2

I am trying to detect a large number of small circles that are in relatively close proximity to one another (only about 20 pixels apart) using OpenCV. I have managed to create this mask using cv::inRange() and cv::Canny().

Original Image

enter image description here

Mask

circle mask

However, when I use cv::HoughCircles() only some of the circles are being detected accurately. Currently, I am using cv::HoughCircles() with the following parameters:

cv::HoughCircles(mat, circles, CV_HOUGH_GRADIENT, 2, mat.rows / 256, 100, 8, 2, 8);

Is this method not effective enough to detect circles that are this small and close together, or do I simply need to modify the parameters of cv::HoughCircles()?

Also, it would be useful to get rid of the "noise" surrounding the array of circles in the middle of the mask because some "false circles" are being detected around the edges of the mask. Is there a simple way to do this?

Community
  • 1
  • 1
Kevin Gurney
  • 1,411
  • 11
  • 20

2 Answers2

3

Get rid of the noise :

If you can make sure to always have the same environment parameters (e.g. distance from the circle, luminosity...), then you could mask your image just after the Canny edge detection, with cvAnd; here is what the mask would look like :

enter image description here

Hough circles detection :

Now, about HoughCircle. First, this function performs its own Canny edge detection. You are doing one too just before the call to HoughCircle. It may have an impact on the shapes of your circles, because of the way Canny works (i.e. intensity gradient on binary image...).

Speaking about the shape of your circles, just below is a close-up of what your "circles" look like; I would have been very impressed if HoughCircle actually did detect all or even just some of those. It can't give anything good in Hough space. Just to make sure, set the last two parameters to 0 (min/max radius), and try to lower the minimum distance between centers. But honestly, I think you need to find another approach to your problem.

[EDIT]

A possible approach would be to perform connected component labeling (e.g. blob detection). As far as I know it is not possible to do this simply with OpenCV alone, you will need something like cvblob, which is a very good OpenCV-based blob library. In particular, you might be interested in cvCentroid(CvBlob *blob).

Cheers

enter image description here

CTZStef
  • 1,675
  • 2
  • 18
  • 47
  • Ah, okay. Thank you for the help and clarification CTZStef. I had a hunch that the circles might not be large enough to be properly detected, especially with the variations in the circular shapes, as you pointed out in your close up image. The ability to mask around only the region of interest is quite useful, however. Since you pointed out that HoughCircles may not be robust enough to detect such small circles, is there another potential approach you might suggest? – Kevin Gurney Jul 27 '13 at 15:30
  • I tried setting the minimum and maximum radius to 0, and I lowered the minimum distance between the center of the circles to 2, but now there are many "false circles" being detected. – Kevin Gurney Jul 27 '13 at 15:51
  • See my suggestion (edit) above. Let me know how it goes ! What exactly are you trying to do btw ? – CTZStef Jul 27 '13 at 19:30
  • Well, essentially I am just trying to determine whether each consecutive point in the matrix of points is within some predefined distance tolerance apart from one another. I appreciate the suggestion of using blob detection, as well CTZStef! – Kevin Gurney Jul 28 '13 at 17:10
  • Did we answer your question Kevin ? – CTZStef Jul 29 '13 at 00:42
  • I have not gotten an opportunity to try blob detection yet, but yes, you did help me with my question. Sorry, I will mark your answer as accepted. Thank you again for all of your help, CTZStef! – Kevin Gurney Jul 29 '13 at 02:23
1

Hum, do you really need to detect them as circles? (as opposed to model them as circles).

If this is some kind of calibration pattern, and you are only interested in estimating the image positions of the centers, It may be a lot more efficient to detect them as point-like features first, then process each detected one individually - e.g. fitting a circle to a blob of white pixels in the neighborhood of each detected feature.

Francesco Callari
  • 11,300
  • 2
  • 25
  • 40
  • Well, I suppose they do not necessarily need to be detected as circles, so much as "points." Essentially, I am just trying to detect whether each of the "points" is within a certain predefined distance apart from one another, so that I can determine whether the points lie in a constant-ish matrix. – Kevin Gurney Jul 28 '13 at 17:12