I need to find the diameter of a circle. However, the whole circle is not visible in the image, only the arc is shown. How can i find the diameter of the circle using this arc alone ?

 Réponse acceptée

Image Analyst
Image Analyst le 5 Juin 2018

1 vote

See attached demo.

6 commentaires

Thank you so much Image Analyst. It works perfectly !!!! Thanks alot
sloppydisk
sloppydisk le 5 Juin 2018
Did the radius end up being different from my answer?
Yes. Your answer gave the result 314 while this code gave 515
Image Analyst, thanks for the code. However is there a way to increase the accuracy of the output even more ?
sloppydisk
sloppydisk le 5 Juin 2018
In fact my code gave 521.6413 pixels.
Image Analyst
Image Analyst le 6 Juin 2018
Yes, use a higher resolution camera, and include more of the circle. Improve your lighting. And, depending on the situation and geometry, using a telecentric lens ( a special type of lens that uses parallel rays of light) might help.

Connectez-vous pour commenter.

Plus de réponses (4)

sloppydisk
sloppydisk le 3 Juin 2018

0 votes

Take three points on the arc, draw lines between them and take the bissectors of those lines, where they meet is the center O. The radius is the distance from any of the points to the center O.
Or if you want to do it algebraically take a look at this link .

10 commentaires

Syed Sameer Ul Hasan
Syed Sameer Ul Hasan le 3 Juin 2018
Modifié(e) : Syed Sameer Ul Hasan le 3 Juin 2018
Thank you for your answer sloppy disk. But how can I take the three points on the arc programmatically ? I Actually want the system to work in real time using a camera so user interference has to be zero.
I would probably do something like this:
rgbImage = imread('002.jpg');
grayImage = rgb2gray(rgbImage);
% take edge
bw = edge(grayImage, 'canny', .2);
% clean up edge
[X, Y] = meshgrid(1:size(bw, 2), flip(1:size(bw, 1)));
bw(Y<50|Y>.8*max(Y)) = 0;
figure(1)
imshow(bw) % show edge
bw = flip(bw);
[y, x] = find(bw); % take indices of edge
figure(2)
plot(x, y) % plot edge
[z, r] = fitcircle([x y]); % do fit giving center z and radius r
t = linspace(0, 2*pi, 50);
xfit = z(1) + r*cos(t); yfit = z(2) + r*sin(t);
hold on
plot(xfit, yfit) % plot fit of edge
hold off
X = ['Radius is ',num2str(r), ' pixels'];
disp(X)
Using fitcircle from file exchange.
Thanks for your quick response. Did you use this fitcircle.m file? https://www.mathworks.com/matlabcentral/fileexchange/15060-fitcircle-m
I used the one above but the radius is not coming out to be correct.
Thanks
sloppydisk
sloppydisk le 4 Juin 2018
Yeah I used that one, I linked to it in my comment. How do you know it's not correct? In my fit plot it fits the data closely.
Because i have this circle at hand. I do know it's real diameter. And yes i did mulitiply the radius by calibration factor (mm/pixel)
sloppydisk
sloppydisk le 4 Juin 2018
Did you also multiply by two to go from radius to diameter? Otherwise I don't know what's wrong.
Yes it did. Still thanks alot for the help.
Btw, can you help me with this question of mine ?
https://www.mathworks.com/matlabcentral/answers/403903-how-to-remove-frame-boundary-from-object-boundary
Thanks
John D'Errico
John D'Errico le 5 Juin 2018
Modifié(e) : John D'Errico le 5 Juin 2018
Note that is a moderately poor way to compute approximate circle radius, especially if the arc is not a perfect circle. You are taking two points as normals off of a bumpy & vaguely circular arc, extending lines. So to find the intersection of two lines that are defined by noisy estimates, will generate a noisy result, but worse, the intersection computation will exaggerate that noise. The bast case would be if you had multiple normal vectors to that curve, with the most useful information probably arising when the lines were orthogonal.
Higher quality tools that compute a circular arc will try to use the entire curve, not just effectively two points form that curve.
Thanks for your response John D'Errico. What do you suggest I should do to get the most accurate result ?
sloppydisk
sloppydisk le 5 Juin 2018
@John D'Errico Yes the picture was only meant as an example to show the general principle of getting the center geometrically. In my example code I did use a least squares fit using the entire curve from fitcircle.m from the file exchange.

Connectez-vous pour commenter.

Image Analyst
Image Analyst le 4 Juin 2018

0 votes

Threshold, extract largest blob with bwareafilt(), find perimeter with bwboundaries(), then use the FAQ http://matlab.wikia.com/wiki/FAQ#How_can_I_fit_a_circle_to_a_set_of_XY_data.3F

1 commentaire

Thank you for your reply Image Analyst. I have seen this faq before but didn't understand the working and imputs of this function. If you could please do that it would be very helpful for me

Connectez-vous pour commenter.

John D'Errico
John D'Errico le 5 Juin 2018
Modifié(e) : John D'Errico le 5 Juin 2018

0 votes

Use the entire curve if possible. Well, all of it that you have. Not just a couple of isolated points.
Extract points from the entire accessible arc, as (x,y) pairs. At this point, it becomes a pure circle fitting problem.
Some years ago, I wrote a circle fitting tool. It tries to produce a fit that does as well as possible, even allowing the use of various solvers like backslash, pinv, or robustfit as alternatives. However, there are many algorithms one might postulate. I'll admit, I'm not in love with the one listed in the FAQ, but it is not that bad either. In some quick tests, it was comparable to the one I wrote. So if your data truly comes from a circle, you probably won't do too much better. And your data should not be too noisy since that arc is quite clear.
Can I do better than that though? Were I to try to do a bit better, I might look to using a maximum likelihood estimation, assuming noise in both x and y on each point. But your data is not that noisy, not that crappy that it is worth the effort.
So where will any "problems" arise? They will come from deviations from pure circularity. Thus, is that arc a perfectly circular arc, with a perfectly fixed radius? I doubt it. In fact, I'll bet that the largest amount of error in your circle parameter estimates come from those deviations from circularity, thus, lack of fit to a true circle, rather than from noise in the fit.
If that is true, then what does it mean to try to do better, fitting a circle perfectly to data that is not perfectly circular? There is a limit beyond which the fit becomes an exercise in absurdity. How can you improve things to best effect? Do a better job of extracting those points on the perimeter of the circle. Improving your data is always a good idea, because that means the algorithms meant to post-process the data will have a far easier time of it.
I would look carefully at the data you have. Compare it to the fit you estimate. Does it have systematic patterns in the residuals between your data and the circle fit. If you see patterns, that means your largest problem lies in lack of fit. And if my conjecture is true, then you won't improve things by making a better circle fit.
Christine Tobler
Christine Tobler le 5 Juin 2018

0 votes

There's a recent blog post by Loren on fitting a sine wave to a picture by eye:
This won't give you best accuracy, but could be a nice way of doing the fit by hand, and verifying if the final circle you choose fits the picture well.

Catégories

Community Treasure Hunt

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

Start Hunting!

Translated by