Why does "imfindcircles" not find circles in my image?

204 views (last 30 days)
The "imfindcircles" function does not reliably find circles, especially if they are imperfect or if the image contrast is low. How can I find circles more reliably and effectively in my images?

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 4 Mar 2021
Edited: MathWorks Support Team on 4 Mar 2021
A couple tips for successfully using imfindcircles can be found in the "Tips" section of the documentation for this function:
There are certain other factors that also obstruct the correct detection of the circles. For example, imfindcircles is known to be sensitive to the contrast of the image. Below are several additional factors to consider when using the imfindcircles funtion: 
  • If the image contrast is low, it may require significant pre-processing steps such as contrast equalization using 'histeq' or 'adapthisteq'.
  • If the first step amplifies noise then one can think about using some de-noising steps beforehand.
  • If the features of interest still don't stand out, some kind of feature extraction or enhancement can be used before using the "imfindcircles".
  • In many cases, correct detection of circles will also require tweaking the ‘EdgeThreshold’, ‘Sensitivity’ and 'ObjectPolarity' parameters.
  • One can further use the ‘metric’ output to filter the spurious circles if the high Sensitivity results in too many spurious circles.
  • The imfindcircles also has two separate algorithms under the hood, which can be switched using the 'Method' parameter. Sometimes one algorithm gives better results than the other.
----------
Another method entirely for finding circles in an image is to use the function 'regionprops', combined with the 'eccentricity' property. This tends to be a more flexible and robust method, especially when the regions are not perfect circles, or the contrast is low. For example, when operating on a binary image, 'BW', you can do something similar to the following:
stats = regionprops('table', BW, 'Centroid', 'Eccentricity', 'EquivDiameter');
This returns each region in the image with it's eccentricity (a measure of how circular something is), the approximate diameter of that circle, and the approximate center of that circle. Furthermore, you could do some filtering of the results to only accept regions with eccentricity less that 0.5 and a diameter between 80 and 100 pixels as follows:
stats( stats.Eccentricity > .5 , : ) = []
stats( stats.EquivDiameter > 80 | stats.EquivDiameter < 100 , : ) = []
 
​If you then wanted to plot these circles, you can do so using the "viscircles" function using the centroids and radii as inputs. You can find more information on the function 'regionprops' at the following page:
https://www.mathworks.com/help/releases/R2017a/images/ref/regionprops.html
 
  3 Comments
Pedro Silva
Pedro Silva on 23 May 2021
Hello.
If I try this line of code as you suggested
stats( stats.Eccentricity > .5 , : ) = []
I get an error message saying
"Error using >
Too many input arguments"
For some weird reason, I can't seem to get it to work or go around it...
Is there a reason for this to be hapenning or how can I go around it? I'm fairly new to matlab, sorry...

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!