Python OpenCV Hough Circles returns None

Question:

I’m trying to figure out Hough Circles before I incorporate it into my main code for a tracking program I’m trying to write, but I can’t seem to get anything but None out from the circles. I’m using the Bengali flag as my image, since it’s simple and will be easy to detect. Here’s my code:

import numpy as np
import cv2


img = cv2.imread('Capture.PNG')

grayput = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

circles = cv2.HoughCircles(grayput, cv2.cv.CV_HOUGH_GRADIENT, 1, 20, param1 =50, param2 =10, minRadius=10, maxRadius=40)
print (circles)

    # need circles 
if circles is not None:
    # convert the coord. to integers
    circles = np.round(circles[0, :]).astype("int")

    # loop over the (x, y) coordinates and radius of the circles
    for (x, y, r) in circles:
        # draw the circle in the output image
        cv2.circle(img, (x, y), r, (0, 0, 0), 4)


cv2.imwrite("image.PNG",img)
Asked By: David Tran

||

Answers:

The following code will give you non-None circles:

import numpy as np
import cv2

img = cv2.imread("../images/opencv_logo.png", 0)
img = cv2.medianBlur(img,5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
cv2.imshow("grayscale", cimg)
cv2.waitKey(0)

circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,20,
                                    param1=50,param2=30,minRadius=0,maxRadius=0)
print (circles)

Indeed, the output is:

[[[  45.5         133.5          16.50757408]
  [  97.5          45.5          16.80773544]
  [ 147.5         133.5          16.32482719]]]

Note: the snippet uses the following as its input image:

enter image description here

Answered By: boardrider

Through trial and error, I was able to manipulate the param1 and param2 to where the cv2.HoughCircle output returns a numpy.ndarray. It seems it returned None if HoughCircle param1 and or param2 threshold is not met.

Answered By: Andy Duong

First off, and most critically, Hough works best (or maybe only) on images that have been converted to edges only. You could try a line this this, after converting to B&W but before calling HoughCircle:
edges = cv2.Canny(grayput, threshold1=10, threshold2=30).
Then pass ‘edges’ to HoughCircles rather than ‘grayput’

I would urge you to also output this image to see it. Make sure you see nice clean circles. You may need to tune either your blur parameter, or these two ‘edge’ threshold parameters, threshold1 and threshold2. Note that it is recommended to keep the ratio of the two of those to 1:2 to 1:3, and the first always lower than the second.

Second, you can tune your HoughCircle call as well; the most critical parameter, imho, is parameter2, which is the accumulator threshold. Hough works by ‘accumulating’ votes for possible circles, and if your edge image is very lean (very skinny lines), then you should require fewer votes (lower accumulator threshold, parameter2) to trigger the detection of a circle. Make this too low and you’ll see lots of spurious circles, so it takes a little experimentation, but these algos are great. You’ll get it.

Answered By: larboyer