Many of you know already that I am a big fan of apps–those that are built into MathWorks toolboxes, and ones that I build myself. I do a tremendous amount of image and video processing, and know my way around the functionality of the Image Processing Toolbox pretty well. Still, finding the “best” set of parameters for some of our functions can be challenging–even for a seasoned user.
Consider, for example, the task of finding circles in an image. This topic comes up quite often–in imagery from diverse fields. Circle detection is so common, in fact, that I selected Tao Peng’s circle detector (CircularHough_Grd) as a Pick of the Week back in 2008. At the time, it was one of the one of the best implementations of circular Hough transforms that I could find.
In the nine years since I wrote about Tao’s File Exchange submission, the Image Processing Toolbox team hit a home run with their release of our own version of a (Hough) circle detector, with a function called imfindcircles. Because of that function, detecting circles today is even easier–and faster than ever before!
However, looking at the documentation for imfindcircles, you can imagine that it can be difficult to find the working parameters for detecting challenging circles.
There are two required input arguments (the image, and either the radius or the range of radii of the target circles), and four input parameter-value pairs:
- ‘ObjectPolarity’, with which we indicate whether whether the circular objects are brighter or darker than the background;
- ‘Method’, which specifies the the technique used to compute the accumulator array;
- ‘Sensitivity’, to specify the sensitivity for the circular Hough transform accumulator array; and
- ‘EdgeThreshold’, which sets the gradient threshold for determining edge pixels in the image.
We can readily use the imdistline tool to measure the radii. And of course we can (usually) ascertain the ‘ObjectPolarity’ just by visual inspection. But what about the other parameters?
img = imread('coins.png'); [centers, radii, metric] = imfindcircles(img, [20 30], ... 'ObjectPolarity', 'Bright'); imshow(img) viscircles(centers,radii);
That detection worked beautifully with default input parameters. But say we wanted to detect (and count) cells in this blood-smear image from the Centers for Disease Control (CDC)?
img = imread('Babesia_thin_giemsa_tetrad4.jpg'); [centers, radii, metric] = imfindcircles(img, [20 30], ... 'ObjectPolarity', 'Dark'); imshow(img) viscircles(centers,radii);
Default parameters fail entirely!
That’s where the circleFinder app comes in:
Check out this video showing it in action!
As always, I welcome your thoughts and comments.
Published with MATLAB® R2017a