HSN
HSN

Reputation: 783

Calculating the coordinates for the center of a circle in an image

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??

Upvotes: 5

Views: 4076

Answers (3)

Gunther Struyf
Gunther Struyf

Reputation: 11168

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

Upvotes: 5

Serg
Serg

Reputation: 14118

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

Upvotes: 2

Konrad Viltersten
Konrad Viltersten

Reputation: 39268

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.

Upvotes: 1

Related Questions