Fit ellipsoid to (x,y,z) data
11 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Geetartha Dutta
el 25 de Oct. de 2023
Comentada: Geetartha Dutta
el 1 de Nov. de 2023
I have a 3D dataset having (x,y,z) coordinates. The x and y values are equally spaced (regular grid). How can I fit an ellipsoid of the form (x-p)^2/a^2 + (y-q)^2/b^2 + (z-r)^2/c^2 , where (p,q,r) are the coordinates of the center of the ellipsoid, and a,b,c are the radii?
7 comentarios
Matt J
el 26 de Oct. de 2023
Editada: Matt J
el 26 de Oct. de 2023
I know that there seems to be two modes in the data
Looks like a lot more than that. I can't tell which is supposed to be the "greater" mode. In any case, if you want a good fit in a particular region, you will have to prune the data to exclude the other regions.
Respuesta aceptada
Matt J
el 26 de Oct. de 2023
Editada: Matt J
el 26 de Oct. de 2023
I'm finding that a decent fitting strategy is to first fit with a Gaussian, but then use the parameters of the Gaussian to construct an ellipsoid hemisphere. For the Gaussian fitting, I used gaussfitn, which is downloadable from,
load xyz
[maxval,i]=max(z(:));
mu0=[x(i);y(i)];
D0=min(z(:));
opts={'FunctionTolerance',1e-14, 'OptimalityTolerance',1e-14, 'StepTolerance',1e-14};
G0={D0,maxval-D0,mu0,100*eye(2)};
LB={0,0,[],[]};
UB={D0,maxval,[],[]};
G = gaussfitn([x(:),y(:)],z(:),G0,LB,UB,opts{:});
%Disaply surfaces
[Zg,Ze]=getSurf(x,y,G);
surf(x,y,z,'FaceAlpha',0.5,'FaceColor','b');
surface(x,y,Ze,'FaceColor','r'); xlabel X, ylabel Y
legend('Raw Data','Fit')
function [Zg,Ze]=getSurf(x,y,G)
[D,A,mu,sig]=deal(G{:});
sz=size(x);
xy=[x(:),y(:)]'-mu;
Zg=D+A*exp(-0.5*sum( (sig\xy).*xy,1)); Zg=reshape(Zg,sz); %Gaussian Fit
Ze=D+A*sqrt(1-sum( (sig\xy).*xy)); Ze=reshape(Ze,sz); %Ellipsoid Fit
end
6 comentarios
Más respuestas (2)
Matt J
el 26 de Oct. de 2023
Editada: Matt J
el 26 de Oct. de 2023
Using quadricFit from,
%%%%%%%%%%%Fake input data
[X,Y,Z] = sphere;
[X,Y,Z]=deal(1+40*X, 2+20*Y,3+30*Z); %stretch into an ellipsoid
surf(X,Y,Z); axis equal
%%%%%%%%%%% Do the fit
XYZ=[X(:),Y(:),Z(:)]';
[XYZ,T]=quadricFit.homogNorm(XYZ);
X=XYZ(1,:).';
Y=XYZ(2,:).';
Z=XYZ(3,:).';
e=+ones(size(X,1),1);
M= [X.^2, [], [], X, ...
Y.^2, [], Y, ...
Z.^2 Z, ...
e];
coeffs=quadricFit.mostnull(M);
ABCDEFGHIJ=zeros(1,10);
ABCDEFGHIJ([1,4,5,7:10])=coeffs;
ABCDEFGHIJ=num2cell(ABCDEFGHIJ);
[A,B,C,D,E,F,G,H,I,J]=deal(ABCDEFGHIJ{:});
Q=[A, B, C; %D
0 E, F; %G
0 0 H];%I
%J
Q=Q/2+Q.'/2;
W=T.'*[Q,[D;G;I]/2;[D,G,I]/2,J]*T;
Q=W(1:3,1:3);
x0=-Q\W(1:3,end);
T=eye(4); T(1:3,4)=x0;
W=T.'*W*T; W=-W/W(end);
rad=sqrt(1./diag(W(1:3,1:3)));
[a,b,c]=deal(rad(1),rad(2),rad(3)) %ellipsoid radii
[p,q,r]=deal(x0(1),x0(2),x0(3)) %ellipsoid center coordinates
2 comentarios
Ver también
Categorías
Más información sobre Curve Fitting Toolbox en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!