I would recommend you use Circular Hough Transform through imfindcircles . However, you need version 8 of the Image Processing Toolbox, which has been available from R2012a onwards. If you do not have this, then, unfortunately, this will not work: (... but let go with the assumption that you have it. However, if you use something older than R2012a, Dev-iL in his / her the comment above is related to some MATLAB File Exchange code on the implementation of this, most likely, was created before the Circular Hough Transform was available: http://www.mathworks.com/matlabcentral/fileexchange/9168-detect-circles-with- various-radii-in-grayscale-image-via-hough-transform /
This is a special case of the Hough Transform transform, in which you try to find circles in your image, not lines. The beauty is that you can find circles even if the circle is partially completed or overlaps.
I will take the image you specified above and do some post processing on it. I am going to convert the image to a binary file and remove the border that is white and contains the title. I am also going to fill in any holes that will cause all objects to be filled with solid white. After I take this step, there is some residual quantization noise, so I'm going to a small hole with a 3 x 3 square element. After that, Iβm going to close the shapes with a 3 x 3 square element, because I see that spaces are noticeable in the shapes. Therefore:
Therefore, direct reading in your image from the place where you placed it:
im = imread('http://s29.postimg.org/spkab8oef/image.jpg'); %// Read in the image im_gray = im2double(rgb2gray(im)); %// Convert to grayscale, then [0,1] out = imclearborder(im_gray > 0.6); %// Threshold using 0.6, then clear the border out = imfill(out, 'holes'); %// Fill in the holes out = imopen(out, strel('square', 3)); out = imclose(out, strel('square', 3));
This is the image I get:

Now apply the circular transform. The general syntax for this is:
[centres, radii, metric] = imfindcircles(img, [start_radius, end_radius]);
img will be the binary image that contains your shapes, start_radius and end_radius will be the smallest and largest radius of the circles you want to find. The Circular Hough Transform transformation is performed in such a way that it finds any circles that are in this range (in pixels). Outputs:
centres : which returns the position (x,y) centers of each detected circle.radii : radius of each circlemetric : A measure of the purity of a circle. Higher values ββmean that the shape is more likely for the circle and vice versa.
I was looking for circles with a radius of 30 to 60 pixels. Therefore:
[centres, radii, metric] = imfindcircles(out, [30, 60]);
Then we can demonstrate the detected circles as well as the radii with a combination of plot and viscircles . Therefore:
imshow(out); hold on; plot(centres(:,1), centres(:,2), 'r*'); %// Plot centres viscircles(centres, radii, 'EdgeColor', 'b'); %// Plot circles - Make edge blue
Here is the result:

As you can see, even with overlapping circles to the top, the Circular Hough Transform was able to detect two different circles in this shape.
Edit - November 16, 2014
You want the objects to be split before you make bwboundaries . This is a little hard to do. The only way to see that you are doing this is to not use bwboundaries at all and do it yourself. I assume that you will want to analyze the properties of each figure yourself, so I suggest you iterate through each circle, and then place each circle in a new empty image, make a regionprops call on this form, and then add it to a separate array. You can also track all circles with a separate array that adds circles one at a time to this array.
Once you are done with all the circles, you will have an array of structures containing all the measured properties for all the measured circles that you found. You should use an array that contains only the circles on top, and then use them and remove from the original image to get only the rows. Then you call another regionprops on this image to get row information and add this to your final structural array.
Here is the first part of the procedure described above:
num_circles = numel(radii); %// Get number of circles struct_reg = []; %// Save the shape analysis per circle / line here %// For creating our circle in the temporary image [X,Y] = meshgrid(1:size(out,2), 1:size(out,1)); %// Storing all of our circles in this image circles_img = false(size(out)); for idx = 1 : num_circles %// For each circle we have... %// Place our circle inside a temporary image r = radii(idx); cx = centres(idx,1); cy = centres(idx,2); tmp = (X - cx).^2 + (Y - cy).^2 <= r^2; % // Save in master circle image circles_img(tmp) = true; %// Do regionprops on this image and save struct_reg = [struct_reg; regionprops(tmp)]; end
The above code may be a little hard to learn, but slowly skip it. First I will find out how many circles we have, which just looks at how many radii we found. I save a separate array called struct_reg , which will add regionprops struct for each circle and row that we have in our image. I use meshgrid to determine the coordinates (x,y) with respect to the image containing our shapes so that I can draw one circle on an empty image in each iteration. To do this, you just need to find the Euclidean distance relative to the center of each circle and set the pixels to true only if this location has a distance less than r . After completing this operation, you will create only one circle and filter out all of them. Then you would use regionprops in that circle, adding it to our circles_img array that would only contain circles, and then continue with the rest of the circles.
At this moment, we will keep all our circles. Here is what circles_img looks circles_img :

You will notice that the drawn circles are clean, but the actual circles in the original image are a bit jagged. If we try to remove circles with this clean image, you will get some residual pixels along the border, and you cannot completely remove the circles themselves. To illustrate what I mean, this is what your image looks like if I try to delete circles using circles_img myself:

... not good, right?
If you want to completely remove the circles, perform a morphological reconstruction through imreconstruct , where you can use this image as a seed image and indicate the original image we are working on. Morphological reconstruction work is essentially a flood. You specify the seed pixels and the image you want to work on, and the imreconstruct task is from these seeds, the fill is filled with white until we reach the boundaries of the objects in which the seed pixels lived. Therefore:
out_circles = imreconstruct(circles_img, out);
Therefore, we get this for our final reconstructed circles image:

Excellent! Now use this and remove the circles from the original image. After that, run regionprops again on this destination image and add struct_reg to your variable. Obviously, keep a copy of the original image before doing this:
out_copy = out; out_copy(out_circles) = false; struct_reg = [struct_reg; regionprops(out_copy)];
Just for the sake of argument, here is what the image with deleting circles looks like:

Now we have analyzed all our forms. Keep in mind that I made a complete call to regionprops because I donβt know exactly what you want in my analysis ... so I just decided to give you everything.
Hope this helps!