# Circle detection opencv

I Would like an explanation of the parameters for opencv's HoughCircles function.

I'm new to image processing in general and I have recently started using opencv. I'm struggling to find circles. I obtained the image below by converting a source image to greyscale then performing a binary threshold.

To my eye, the leftmost images are almost perfect circles. I have seen demonstrations where, what I assume are very noisy and distorted circles have been identified by opencv's hough transform.

Assuming the image displayed above is saved as "binaryresult.png". If I run the following code I get circles that are poorly placed. I'd like to understand the HoughCircles function's parameters so that I can better detect circles.

import cv2
import numpy as np

image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
circles = cv2.HoughCircles(image, cv2.cv.CV_HOUGH_GRADIENT,  2, 32, param1=200, param2=100)

# ensure at least some circles were found
if circles is not None:
# convert the (x, y) coordinates and radius of the circles 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, then draw a rectangle
# corresponding to the centre of the circle
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)

# show the output image
cv2.imshow("output", np.hstack([image]))
cv2.waitKey(0)


The hough transform works by creating a buffer (2 dimensional in our case) which represents all the possible lines in the image.

Any possible line can be represented with those 2 numbers $(\rho, \theta)$

From wikipedia

Note this uses polar coordinates to avoid division by zero issues rather than your typical $y = mx + c$ for a line

The hough transform scans an image and casts votes into the 2 dimensional buffer corresponding to $(\rho, \theta)$ values.

The buffer slots that accumulate the most votes are likely to be attributed to the presence of a line for that $(\rho, \theta)$ value.

That's the basic idea of the Hough transform but it can get more complicated from here.

For selecting $(\rho, \theta)$ values from the buffer, methods can get more sophisticated, such as using kernel density estimation. Although I don't think opencv does that.

In the case of the Hough circle transform, we now have a 3 dimensional buffer. $(x, y, r)$

Where

$x, y$: coordinates of center of circle

$r$: radius

Now in practice there's more to making the Hough transform work than this.

Take a look at the source code for the icvHoughCirclesGradient function.

Its here

Also cvHoughCircles and cv::HoughCircles

you can see that the function is also doing canny edge detection and sobel filtering.

These operations have their own input parameters which you can also see as inputs to the hough function.

Examining the function signature

void cv::HoughCircles( InputArray _image, OutputArray _circles,
int method, double dp, double min_dist,
double param1, double param2,


Method: There seems to be only on method now, probably left this for future development

dp: this is the resolution of the votes buffer

min_dist : is the minimum distance between circles (ie: circles that are too close must be part of the same circle)

int canny_threshold = cvRound(param1);