Search code examples
pythonopencvimage-processingcomputer-visiondetection

HoughCircles circle detection not working?


I have been trying to write a program that can detect circles on my screen.

This is my screen before code processing

As you can see on the image, there are three circles that the code should detect. I am using HoughCircles function from OpenCV library to achieve this task. My code is below.

ss = gui.screenshot()

img = cv2.cvtColor(np.array(ss), cv2.COLOR_RGB2BGR)
output = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, 100)

if circles is not None:
    print("circles found", len(circles))

    circles = np.round(circles[0, :]).astype("int")

    for (x, y, r) in circles:

        cv2.circle(output, (x, y), r, (0, 255, 0), 4)
        cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)

    cv2.imshow("output", np.hstack([gray, output]))
    cv2.waitKey(0)

cv2.imshow("output", gray)
cv2.waitKey(0)

I am first taking screenshot of my screen. Then, I convert it to use it for opencv.

However, this code does not detect any circles for the screenshot shown in the first picture. I know this because when ran, my program does not print "circles found". Moreover, to show that I have been taking screenshots and transforming them to grayscale properly, I have this image taken from the last two lines of my code.

picture in a gray scale

To show that my code works with other circle images, here is a picture of a regular circle:

before detection

after detection

Any help would be very appreciated!


Solution

  • These are the parameters of houghCircles that works for me. You should also consider running a gaussian blur over the image before trying to find the circles.

    enter image description here

    I'm not a huge fan of houghCircles. I find it to be really finicky and I don't like how much of what it does is hidden inside the function. It makes tuning it mostly trial-and-error. These parameters work for this particular image, but I wouldn't count on this continuing to work under different lighting conditions or for different colors.

    import cv2
    import numpy as np
    
    # load image
    img = cv2.imread("spheres.png");
    
    # grayscale
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);
    gray = cv2.GaussianBlur(gray,(5,5),0);
    
    # circles
    circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp = 1, minDist = 100, param1=65, param2=20, minRadius=20, maxRadius=50)
    
    # draw circles
    if circles is not None:
        # round to ints
        circles = np.uint16(np.around(circles));
        for circle in circles[0, :]:
            # unpack and draw
            x, y, radius = circle;
            center = (x,y);
            cv2.circle(img, center, radius, (255, 0, 255), 3);
    
    # show
    cv2.imshow("Image", img);
    cv2.imshow("Gray", gray);
    cv2.waitKey(0);