Detect multiple circles of various radii in complex, noisy, grayscale image
Show older comments
I have a tiff image that contains many roughly circular and sometimes overlapping or connected shapes. The goal is to find the centers and radii of each of these circles in pixels. Unfortunately, the image is very noisy, and the intensity of each circle is not constant. I am relatively new to image processing using Matlab, but I have researched and tried just about every strategy i can find, all with little success. My attempts have included combinations of: increasing the contrast of the image, changing it to a binary image and using regionprops, writing code to differentiate the intensity of each circle, segmenting the image in several ways, and using a Circular Hough Transform code written by Tao Peng. The Hough Transform file was used on a "pick of the week" example that seemed to be very similar to my problem, but even this code (that was much more advanced than my abilities) could not solve the problem accurately. So my question is: Does anyone know of a method of approaching/solving this that is complex enough to handle this image?? I would greatly appreciate the help.
The image is supposed to be 2562 rows x 2624 columns.
The original image:
A more contrasted version:
Answers (1)
Sean de Wolski
on 9 Aug 2011

I'm just posting this as an answer so I can include the image.
Please clarify: Are all of the red arrows pointing at the circles you care about and the green ones pointing as background?
More:
%%read in your image saved from the interwebs
I = imread('ans809.jpg');
S = stdfilt(I,ones(3));
imtool(S<5); %ridge lines kinda
M = S>=5; %map where the std is large
I2 = I.*uint8(M); %apply map
imtool(I2) %blanked out everything but ridge lines. \
imtool(M); %map
with a few morphological operation this should clean right up. You can also look at using different shapes for the std kernel. Since things are circular maybe that would be your best bet. You can also eventually look at using the distance transform on the map. This could open up the watershed option.
Another approach might be to use the gradient:
[fx fy] = gradient(double(I));
imtool(hypot(fx,fy))
threshold it and go.
3 Comments
Adria
on 9 Aug 2011
Adria
on 9 Aug 2011
Sean de Wolski
on 9 Aug 2011
Original, image. The other should better I'm sure since it's more contrasted (duh!).
The lines are broken up and splotchy so I might try a morphological closing (imclose) which is a dilation followed by an erosion. Once you have the lines well defined; invert and use bwconncomp to group blobs. You can then use regionprops with 'centroid' and 'equivdiameter' options to get the centroid and diameter. Divide diameter by two for the radius.
You could also threshold the size of objects to get rid of ones that are too small or large.
Categories
Find more on Process Point Clouds in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!