drawing a best fit graph

is there a way to draw a best fit graph from a cut off circle, i have the [x y] coordinates for the first black points. now i want to use these coordinates to draw the exact shape on a graph. i tried polyfit but it doesnt give me the required shape

1 Comment

Can you provide data or code to produce the plot shown?

Sign in to comment.

Answers (1)

I = imread('image.png') ;
I = rgb2gray(I) ;
[y,x] = find(~I) ;
% Get center
idx = boundary(x,y) ;
x = x(idx) ;
y = y(idx) ;
imshow(I)
hold on
plot(x,y,'r')

9 Comments

this seems to work but why is it that when i remove the line imshow, the graph switches on the y axis. Also, why did you have [y,x] = find(~I) ; instead of [x,y]?
this is how i tried to do it but i get a figure like this. my code is below. the imgThresh is the image converted to binary
x=zeros(1,10000);
y=zeros(1,10000);
count=1;
for i=fliplr(1:10:rows)
for j=1:columns
if imgThresh(i,j)==0
y(count)=rows-i+1;
x(count)=j;
count=count+1;
break
end
end
end
for i=fliplr(1:10:rows)
for j=fliplr(1:columns)
if imgThresh(i,j)==0
y(count)=rows-i+1;
x(count)=j;
count=count+1;
break
end
end
end
nonzeros(x);
nonzeros(y);
and i also want to be able to draw a tangent to the curve
why did you have [y,x] = find(~I) ; instead of [x,y]?
If you have a table of data, such as a logarithm table
then would find data by referring to "row 7, column 3" -- vertical distance named first, and then horizontal distance named.
This is the order that MATLAB uses for arrays. The first index is vertical distance, and the second index is horizontal distance.
However, the convention for Cartesian coordinates is that the independent variable, x, is along the vertical axes and is named first, followed by the dependent variable on the vertical axes second.
Row is vertical distance. Vertical distance is y. Therefore, row coordinates correspond to y, and column coordinates correspond to x.
why is it that when i remove the line imshow, the graph switches on the y axis.
imshow() does an automatic
set(gca,'Ydir','reverse')
unless hold is on for the axes. When you are dealing with images, it is very common to think of them in terms of distance down from the top, instead of in terms of distance up from the bottom (Cartesian coordinates.)
Yes, three incompatible conventions.
would you know how to draw a tangent starting from base to the curve
Pick a point on circle, where you want a tangent. You have center and point in hand; get the slope, get the slope of tangent. Use point slope formula.
how do i get the center
the idx gives many points
this is the code i used to get the center, it works for other test images but for this. the output does not give me a tangent across the blue line. does your code pasted earlier have a way of getting the center of the ellipse?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [xc,yc,R,a] = circfit(x,y)
%
% [xc yx R] = circfit(x,y)
%
% fits a circle in x,y plane in a more accurate
% (less prone to ill condition )
% procedure than circfit2 but using more memory
% x,y are column vector where (x(i),y(i)) is a measured point
%
% result is center point (yc,xc) and radius R
% an optional output is the vector of coeficient a
% describing the circle's equation
%
% x^2+y^2+a(1)*x+a(2)*y+a(3)=0
%
% By: Izhak bucher 25/oct /1991,
x=x(:); y=y(:);
a=[x y ones(size(x))]\[-(x.^2+y.^2)];
xc = -.5*a(1);
yc = -.5*a(2);
R = sqrt((a(1)^2+a(2)^2)/4-a(3));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[xfit,yfit,Rfit] = circfit(x,y);
plot(xfit,yfit,'*r','MarkerSize',10);
plinex=[xfit min(x)];
pliney=[yfit max(y)];
coefficients=polyfit(plinex,pliney,1);
slope=coefficients(1)
[x1p, index1] = min(plinex)
[x2p, index2] = max(plinex)
% Get y at those endpoints
y1p = pliney(index1);
y2p = pliney(index2);
% Compute the slope
perpSlope = -1 / slope
% Equation of line going through the left most x (at x1p) is
% (y - y1p) = perpSlope * (x - x1p)
y1 = perpSlope * (x1p - plinex(index1)) + y1p
y2 = perpSlope * (x2p - plinex(index1)) + y1p
line([x1p, x2p], [y1, y2], 'Color', 'r', 'LineWidth', 0.5)
I would suggest you this:
I = imread('image.png') ;
I = rgb2gray(I) ;
[y,x] = find(~I) ;
% Get center
idx = boundary(x,y) ;
x = x(idx) ;
y = y(idx) ;
%% Get circle radius and centre ;
% select three points randomly on circle
idx = [10 100 150] ;
pt1 = [x(idx(1)) y(idx(1))] ;
pt2 = [x(idx(2)) y(idx(2))] ;
pt3 = [x(idx(3)) y(idx(3))] ;
[C, R] = calcCircle(pt1, pt2, pt3) ;
%% Draw circle
th = linspace(0,2*pi) ;
xc = C(1)+R*cos(th) ;
yc = C(2)+R*sin(th) ;
imshow(I)
hold on
plot(xc,yc,'r')

Sign in to comment.

Asked:

on 2 Mar 2021

Commented:

on 4 Mar 2021

Community Treasure Hunt

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

Start Hunting!