5

enter image description here

Say I have this image and I want to get the center of each circle in (X , Y).

Is there an algorithm to do so in MatLab??

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
HSN
  • 783
  • 3
  • 11
  • 20

3 Answers3

5

That's possible with one call to regionprops:

img = imread('KxJEJ.jpg');                      % read the image
imgbw = ~im2bw(img,graythresh(img));            % convert to grayscale

stats  = regionprops(bwlabel(imgbw), 'centroid','area'); % call regionprops to find centroid and area of all connected objects
area = [stats.Area];                            % extract area
centre = cat(1,stats.Centroid);                 % extract centroids

centre = centre(area>10,:);                     % filter out dust specks in the image

Now centre contains an Nx2 array: first column is x-position, second column is y-position of the centres:

centre =

   289.82       451.73
   661.41       461.21
   1000.8       478.01
   1346.7       482.98
Gunther Struyf
  • 11,158
  • 2
  • 34
  • 58
  • they have encountered this error http://www4.0zz0.com/2012/11/13/21/243181924.jpg – HSN Nov 13 '12 at 21:23
  • 1
    you must be using an older version, what happens if you add what the error suggests: `stats=regionprops(bwlabel(imgbw),'centroid','area');` ? – Gunther Struyf Nov 13 '12 at 23:14
2

Here is a result using cross-correlation with artificial circle as a filter. The result is [row, column] from upper left corner:

>> disp(centers)
         483        1347
         460         662
         478        1001
         451         290

There is no detailed comments, please ask it required.

im = rgb2gray(im2double(imread('D:/temp/circles.jpg')));
r = 117; % define radius of circles
thres_factor = 0.9; % see usage
%%
[x, y] = meshgrid(-r : r);
f = sqrt(x .^ 2 + y .^ 2) >= r;
%%
im = im - mean(im(:));
im = im / std(im(:));
f = f - mean(f(:));
f = f / std(f(:)) / numel(f);
imf_orig = imfilter(im, f, 'replicate');
%% search local maximas
imf = imf_orig;
[n_idx, m_idx] = meshgrid(1 : size(imf, 2), 1 : size(imf, 1));
threshold = thres_factor * max(imf(:));
centers = []; % this is the result
while true
    if max(imf(:)) < threshold
        break;
    end
    [m, n] = find(imf == max(imf(:)), 1, 'first');
    centers = cat(1, centers, [m, n]);
    % now set this area to NaN to skip it in the next iteration
    idx_nan = sqrt((n_idx - n) .^ 2 + (m_idx - m) .^ 2) <= r;
    imf(idx_nan) = nan;
end

enter image description here

Serg
  • 13,470
  • 8
  • 36
  • 47
  • The guy who used the code said it worked and he asked "Where should I put the plot command and which variable is used?" – HSN Nov 14 '12 at 00:05
  • 1
    this is done by `figure, imagesc(imf_orig); colorbar;`. Obviously, after calculation of `imf_orig`. – Serg Nov 14 '12 at 16:14
1

I recall doing that at the university, many years ago!

What we did was to apply a threshold and make everything black and white. Then, we blobbed out the white area (non-circle) so it spread onto the circles.

When they started to disappear, we had the coordinates.

You could also pick two points at the circumference, find the exact middle of the line between them and then draw a perpendicular line through that point. If the middle of the new line is the center of the circle.

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • can you please tell me more about "blobing " .. Forgive my ignorance but im not that good at matlab and im asking this question on behalf of my friend ... dose it have anything to do with this ?? http://www.commsp.ee.ic.ac.uk/~jahangiri/Blobdetector.html – HSN Nov 13 '12 at 20:54