Detect multiple circles of various radii in complex, noisy, grayscale image

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)

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

Correct except for the red arrow farthest to the upper left and the one at the very bottom. That's more the background connective substance if you will.
Thanks! Did you use the original image for your process or the more contrasted one? I get very different looking results depending on which one i use (the contrasted one looks a lot more useful). Would you mind giving me a little more guidance on what morphological operations would be the best to use, and what you think would be the best approach to actually finding the separate centers and radii after the image is cleared?
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.

Sign in to comment.

Asked:

on 9 Aug 2011

Community Treasure Hunt

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

Start Hunting!