# Finding centers and radii of multiple circles in a dense image

I'm trying to locate and write in a file the coordinates (X,Y) of the centres of multiple circles, and their radii, in a 2D dense image. The circles have two different radii (but, in general, they could have more).

I've search the site and found some implementations of how to do similar things and try myself, like [1], [2], [3], [4] and [5], but without sucess. I wanted to comment in those answers for some help, but, don't have enough points for that, so, that's why i'm making this question.

The images I want to analyze are like this. A 1000 x 1000 px image with red and blue circles in a white background. This one in particular have close to a 1000 of each type of circle.

What I tried to do was to change the colors of one of the type of circles into black, as long with the background, then, the other type of circle to white. In the end, with a black and white image, I tried to locate the centers. But it was far from what it should be. I need all the circles to be detected, or as many as possible.

My knowledge of image processing in Mathematica (in general) is very limited, so, if you could explain what is going on for a layman it would be perfect. Also, if there are other ways to do it (with Matlab, Python, etc...) and if it is as good or easier, it would be welcome as well.

If your images have circles with distinct colors, as is the case for your example image, you can extract them by color and then find their centers as the locations at maximum distances from the background.

Import the image:

img = Import["https://i.imgur.com/1aW18qo.png"];


Find the dominant colors in the image:

colors = DominantColors[img];


For your image, this gives a dark red, white and a dark blue.

Create binary images of the red and blue circles:

imgRed = Binarize@ColorDetect[img, colors[[1]]];
imgBlue = Binarize@ColorDetect[img, colors[[-1]]];


Find the centers of the red circles:

maxRed = MaxDetect[DistanceTransform[imgRed]];
centersRed = Values@ComponentMeasurements[maxRed, "Centroid"];


This gives over 1000 positions for centers of red circles. You can see how these points compare with the circles in the image using

HighlightImage[img, {Green, PointSize[Medium], centersRed}]


which places a green point at the centers of red circles.

The same procedure starting from imgBlue finds the centers of the blue circles.

This can miss some circles that touch the edge of the image.

Since the blue circles don't touch each other, you can get their diameters along with the center using, e.g.,

ComponentMeasurements[DistanceTransform[imgBlue], {"Centroid", "MeanCaliperDiameter"}]


or one of the other diameter measures in ComponentMeasurements documentation.

The red circles touch so separating them to find the diameter is trickier. Once you have the centers, you can segment the image starting from those centers. For example, using WatershedComponents on the distance transform:

segmentsRed = WatershedComponents[ColorNegate@DistanceTransform[imgRed], centersRed];


You can then extract the part of the distance transform image corresponding to each segment, using ComponentMeasurements, and then find the diameter of the largest component in each one, again using ComponentMeasurements. This will likely fail for circles that are cut off at the edges of the image.

• It seems that this answer works too, with some adjustment of parameters, but it's not so reliable as your answer for this particular problem (maybe because i don't know much of how to manipulate it yet). Anyways, thank you very much.
– koy
Commented Jun 7 at 4:34