How to measure radius of circle in big image?

1 次查看(过去 30 天)
(image above is copydrawing of original image. Sorry for impossible of uploading original image)
Because its size is over 2000x2000 pixels, Some problem has been found.
I tried 3 ways, and failed with each following reasons.
%%%%%%%%%%%%%%%fail 1 %%%%%%%%%%%%%%%%%%%%%%%%%
stats = regionprops('table',K,'Centroid',...
'MajorAxisLength','MinorAxisLength');
centers = stats.Centroid;
diameters = mean([stats.MajorAxisLength stats.MinorAxisLength],2);
radii = diameters/2;
viscircles(centers,radii);
% Tracked wrong circle.
%%%%%%%%%%%%%%%fail 1 %%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%fail 2 %%%%%%%%%%%%%%%%%%%%%%%%%
[centers, radii] = imfindcircles(out,[1000 1100], 'Sensitivity', 0.92);
h = viscircles(centers, radii);
% Too big size to track it
% One radius per multiple circles tracked.
%%%%%%%%%%%%%%%fail 2 %%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%fail 3 %%%%%%%%%%%%%%%%%%%%%%%%%
r = sqrt(sum(out(:))/pi);
% Code for full circle
%%%%%%%%%%%%%%%fail 3 %%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%exp 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[B,L,N] = bwboundaries(out,4,'holes');
figure; imshow(out); hold on;
for k = 1 : length(B),
boundary = B{k};
if(k > N)
plot(boundary(:,2), boundary(:,1), 'g', 'LineWidth', 2);
else
plot(boundary(:,2), boundary(:,1), 'r', 'LineWidth', 2);
end
end
x = boundary(:,2);
y = boundary(:,1);
n=length(x); xx=x.*x; yy=y.*y; xy=x.*y;
A=[sum(x) sum(y) n;sum(xy) sum(yy) sum(y);sum(xx) sum(xy) sum(x)];
B=[-sum(xx+yy) ; -sum(xx.*y+yy.*y) ; -sum(xx.*x+xy.*y)];
a=A\B;
xc = -.5*a(1);
yc = -.5*a(2);
R = sqrt((a(1)^2+a(2)^2)/4-a(3));
%
%%%%%%%%%%%%%%%exp 1 %%%%%%%%%%%%%%%%%%%%%%%%%
and still finding which elements should be selected as x,y component in circfit function.
  • Is there anything I missed?
  • Or did I choose wrong way?
Any small kind answer would be a huge help!

回答(1 个)

hyong suk choo
hyong suk choo 2017-3-6
编辑:hyong suk choo 2017-3-6
Solved with calc_circle code
https://kr.mathworks.com/matlabcentral/newsreader/view_thread/165185
Select 3 point on edge (2 Lowest point with extreme right and left side and 1 highest point on right side) and use this code
Of course it is not precise method, but error is negligible for me. (error in 10 pixel scale.)
I = imread(image);
%Detect Entire Cell
[~, threshold] = edge(I,'sobel');
fudgeFactor = .8;
BWs = edge(I,'sobel',threshold*fudgeFactor);
%Dilate the image
se90 = strel('line',3,90);
se0 = strel('line',3,0);
BWsdil = imdilate(BWs,[se90 se0]);
[B,L,N] = bwboundaries(BWsdil,4,'holes');
figure;
imshow(BWsdil);
axis equal;
hold on;
for k = 1 : length(B),
boundary = B{k};
if(k > N)
plot(boundary(:,2), boundary(:,1), 'g', 'LineWidth', 2);
else
plot(boundary(:,2), boundary(:,1), 'r', 'LineWidth', 2);
end
end
[y,x] = find(BWsdil);
table(:,1) = x; % making table array
table(:,2) = y;
yyy = max(y);
exp1 = table(table(:,2)==yyy); % lowest position on image
pp1 = min(exp1); % end of left side
pp3 = max(exp1); % end of right side
tablefor3rd = table(:,1) > 2000; % X coordinate over 2000
extracted = table(tablefor3rd,:); % rows with X coordinates over 2000
maxiy = min(extracted(:,2)); % highest position
list = extracted(:,2) == maxiy; % point list with highest point
list2 = extracted(list,:);
maxix = max(list2(:,1));
p1 = [pp1,yyy];
p2 = [maxix,maxiy];
p3 = [pp3,yyy];
[c r] = calc_circle(p1, p2, p3);
axis equal
hold on
if r == -1
disp('COLLINEAR')
else
rectangle('Position', [c(1)-r,c(2)-r,2*r,2*r],...
'Curvature', [1,1], 'EdgeColor', 'g')
end
plot(p1(1), p1(2), '*')
plot(p2(1), p2(2), '*')
plot(p3(1), p3(2), '*')

Community Treasure Hunt

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

Start Hunting!

Translated by