Haar classifier trouble accurately detecting circles

Hi,

I don’t know anything about this really, especially, I don’t know what Haar Classifier is.

I am just interested. Maybe it will help.

I made a .png file. It has 2 separate blue circles with no fill and 3 nested red circles with no fill on a white background.

This little bit of python correctly finds all the circles and draws around them in yellow:

#! /usr/bin/python3
# try out cv2

import cv2
import numpy as np
import os

def junkjpgs(path):
    print('Clearing out the folders we use, in case there is anything in there ... ')
    pics = os.listdir(path)
    if len(pics) == 0:
        print('Nothing in ' + path + '\n\n')
        return
    for file in pics:
        os.remove(path + file)
    print('ALL files removed from: ' + path + '\n\n')

junkjpgs(path2)

path1 = '/home/pedro/Pictures/'
path2 = '/home/pedro/OMRsteps/'

file = 'pic_find_circles.png'

# save the original image to compare with other steps in the process
pic = path1 + file
image = cv2.imread(pic)
name = 'original_image.png'
cv2.imwrite(path2 + name, image)

# it is better to get the edges from a blurred grey image apparently
grey = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
name = 'step1_grey.png'
cv2.imwrite(path2 + name, grey)

# blurring the image helps apparently
blurred = cv2.GaussianBlur(grey, (5, 5), 0)
name = 'step2_blurred.png'
cv2.imwrite(path2 + name, blurred)

# get the edges in the blurred image
edged = cv2.Canny(blurred, 75, 200)
name = 'step3_edged.png'
cv2.imwrite(path2 + name, edged)

# working on a copy is wise I read
edged2 = edged.copy()

# this only gets external contours
#contours, hierarchy = cv2.findContours(edged.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# this gets nested contours, nested circles
contours, hierarchy = cv2.findContours(edged2, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
print('reading edged2, there are ', len(contours), ' contours')
# find contours in the edge map, then use the contours on the thresh
    
 # draw yellow strokes on the original image corresponding to the circles
# check that the contours line up with the circles on the image

paper2 = image.copy()

for b in range(0, len(contours)):
    cv2.drawContours(paper2, contours, b, (0, 230, 255), 4)

name = 'circle_the_contours.png'
cv2.imwrite(path2 + name, paper2)