Perform the best-fit ellipse (in the Least Squares sense).
[SM,Sm,X0,Y0,P] = NL_V_FitEllipse(X,Y)
X-coordinate vector (measurement).
Y-coordinate vector (measurement).
Semi-major axis.
Semi-minor axis.
x-coordinate of the ellipse center.
y-coordinate of the ellipse center.
Angle of rotation in radians with respect to the x-axis.
NL_V_FitEllipse performs the best-fit ellipse (in the Least Squares sense) for the measurement points X and Y. The ellipse is decribed with its center located X0 and Y0, its magnitude in the two axis (longer SM and shorter Sm), and the angle of rotation in radians with respect to the x-axis P.
Given the quadratic form of an ellipse: a*x^2 + 2*b*x*y + c*y^2 + 2*d*x + 2*f*y + g = 0 (1) We need to find the best (in the Least Square sense) parameters a,b,c,d,f,g. By dividing both sides of equation (1) by a and then move x^2 to the other side, we obtain: 2*b'*x*y + c'*y^2 + 2*d'*x + 2*f'*y + g' = -x^2 (2) where the primed parameters are the original ones divided by a. Now the usual estimation technique is used: M * p = b, where M = [2*x*y y^2 2*x 2*y ones(size(x))], p = [b c d e f g], and b = -x^2. We seek the vector p, given by: p = pseudoinverse(M) * b. We finally construct M. | ![]() | ![]() |
[path]=NL_F_NLPath();//path to NARVAL module path=path+'/demos/';//folder path [x,y]=NL_V_LoadBody2D(path);//dataset loading scf(); plot2d(x,y,rect=[0 0 640 480],style=0); l=length(x); gx=mean(x); gy=mean(y); plot(gx,gy,'ko', 'MarkerSize',6,'LineWidth',2); plot(gx,gy,'kx', 'MarkerSize',6,'LineWidth',2); xstring(gx,gy,'G['+string(gx)+','+ string(gy)+']'); D=sqrt((gx*ones(1,l)-x').*(gx*ones(1,l)-x')+(gy*ones(1,l)-y').*(gy*ones(1,l)-y')); [DS DSv]=gsort(D); gradDS=DS(2:$)-DS(1:$-1); [a b]=min(gradDS); //b index //DSv(b) real index of nodes Dbody=DS(b); ibody=find(D<=Dbody);//filtering xbody=x(ibody); ybody=y(ibody); scf(); plot2d(xbody,ybody,rect=[0 0 640 480],style=0); gbodyx=mean(xbody); gbodyy=mean(ybody); plot(gbodyx,gbodyy,'ko', 'MarkerSize',6,'LineWidth',2); plot(gbodyx,gbodyy,'kx', 'MarkerSize',6,'LineWidth',2); xstring(gbodyx,gbodyy,'G['+string(gbodyx)+','+ string(gbodyy)+']'); [e_body_a,e_body_b,e_body_x0,e_body_y0,e_body_phi]=NL_V_FitEllipse(xbody,ybody);//application of NL_V_FitEllipse | ![]() | ![]() |