声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 3095|回复: 2

[综合讨论] 如何求解对离散点的最优椭圆拟合?

[复制链接]
发表于 2005-10-7 10:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
最好有现成的代码,谢谢

[ 本帖最后由 eight 于 2008-3-4 15:08 编辑 ]
回复
分享到:

使用道具 举报

发表于 2005-10-7 15:15 | 显示全部楼层

回复:(morning)[求助]如何求解对离散点的最优椭圆拟...

试一下这个下面这段代码:<BR><BR><PRE>function a = fitellipse(X,Y)

% FITELLIPSE  Least-squares fit of ellipse to 2D points.
%        A = FITELLIPSE(X,Y) returns the parameters of the best-fit
%        ellipse to 2D points (X,Y).
%        The returned vector A contains the center, radii, and orientation
%        of the ellipse, stored as (Cx, Cy, Rx, Ry, theta_radians)
%
% Authors: Andrew Fitzgibbon, Maurizio Pilu, Bob Fisher
% Reference: "Direct Least Squares Fitting of Ellipses", IEEE T-PAMI, 1999
%
% This is a more bulletproof version than that in the paper, incorporating
% scaling to reduce roundoff error, correction of behaviour when the input
% data are on a perfect hyperbola, and returns the geometric parameters
% of the ellipse, rather than the coefficients of the quadratic form.
%
%  Example:  Run fitellipse without any arguments to get a demo
if nargin == 0,   % Create an ellipse
  t = linspace(0,2);
  Rx = 300,  Ry = 200,  Cx = 250,  Cy = 150,  Rotation = .4 % Radians
  x = Rx * cos(t);  y = Ry * sin(t);
  nx = x*cos(Rotation)-y*sin(Rotation) + Cx;
  ny = x*sin(Rotation)+y*cos(Rotation) + Cy;
  plot(nx,ny,'o');  % Draw it
  fitellipse(nx,ny)  % Fit it
  % Note it returns (Rotation - pi/2) and swapped radii, this is fine.
  return
end

% normalize data
mx = mean(X); my = mean(Y);
sx = (max(X)-min(X))/2; sy = (max(Y)-min(Y))/2;
x = (X-mx)/sx; y = (Y-my)/sy;

x = x(:); y = y(:); % Force to column vectors
D = [ x.*x  x.*y  y.*y  x  y  ones(size(x)) ]; % Build design matrix
S = D'*D; % Build scatter matrix
C(6,6) = 0; C(1,3) = -2; C(2,2) = 1; C(3,1) = -2; % Build 6x6 constraint matrix

[gevec, geval] = eig(S,C); % Solve eigensystem

% Find the negative eigenvalue
I = find(real(diag(geval)) < 1e-8 & ~isinf(diag(geval)));

% Extract eigenvector corresponding to negative eigenvalue
A = real(gevec(:,I));

% unnormalize
par = [ A(1)*sy*sy, A(2)*sx*sy, A(3)*sx*sx,   ...
      -2*A(1)*sy*sy*mx - A(2)*sx*sy*my + A(4)*sx*sy*sy,   ...
      -A(2)*sx*sy*mx - 2*A(3)*sx*sx*my + A(5)*sx*sx*sy,   ...
      A(1)*sy*sy*mx*mx + A(2)*sx*sy*mx*my + A(3)*sx*sx*my*my,   ...
      - A(4)*sx*sy*sy*mx - A(5)*sx*sx*sy*my,   + A(6)*sx*sx*sy*sy ]';

% Convert to geometric radii, and centers

thetarad = 0.5*atan2(par(2),par(1) - par(3));
cost = cos(thetarad); sint = sin(thetarad);
sin_squared = sint.*sint; cos_squared = cost.*cost; cos_sin = sint .* cost;

Ao = par(6);
Au =   par(4) .* cost + par(5) .* sint; Av = - par(4) .* sint + par(5) .* cost;
Auu = par(1) .* cos_squared + par(3) .* sin_squared + par(2) .* cos_sin;
Avv = par(1) .* sin_squared + par(3) .* cos_squared - par(2) .* cos_sin;

% ROTATED = [Ao Au Av Auu Avv]

tuCentre = - Au./(2.*Auu); tvCentre = - Av./(2.*Avv);
wCentre = Ao - Auu.*tuCentre.*tuCentre - Avv.*tvCentre.*tvCentre;

uCentre = tuCentre .* cost - tvCentre .* sint;
vCentre = tuCentre .* sint + tvCentre .* cost;

Ru = -wCentre./Auu; Rv = -wCentre./Avv;
Ru = sqrt(abs(Ru)).*sign(Ru); Rv = sqrt(abs(Rv)).*sign(Rv);

a = [uCentre, vCentre, Ru, Rv, thetarad];</PRE>

[ 本帖最后由 ChaChing 于 2009-5-23 11:22 编辑 ]
发表于 2008-3-4 14:08 | 显示全部楼层
正好在找这个
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-10-2 14:27 , Processed in 0.058029 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表