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 , : ) =