记录搜罗到的Matlab 对散点进行椭圆拟合

需要基于一些散点拟合椭圆估计并计算出椭圆的参数和周长,搜罗到直接上代码
(1)有用的椭圆拟合及参数计算函数

cpp 复制代码
function W = fitellipse(x,y)
% 构造矩阵
D = [x.*x, x.*y, y.*y, x, y,ones(size(x))];
S = D'*D;
G = zeros(6);
G(1,3) = 2; G(3,1) = 2; G(2,2) = -1;

% 求解
[vec, val] = eig(S\G);
[~, idx] = find(val>0&~isinf(val));
W = vec(:,idx);
W = sqrt(1/(W'*S*W))*W;
end
cpp 复制代码
function [Center,Axis,Theta] = calellipseparams(W)
a = W(1); 
b = W(2); 
c = W(3); 
d = W(4); 
e = W(5); 
f = W(6);
% 中心
cx = (b*e-2*c*d)/(4*a*c-b^2);
cy = (b*d-2*a*e)/(4*a*c-b^2);
Center = [cx,cy];
% 长短轴  
MA1 = sqrt(2*(a*cx^2+c*cy^2+b*cx*cy-f)/(a+c+sqrt((a-c)^2+b^2)));
MA2= sqrt(2*(a*cx^2+c*cy^2+b*cx*cy-f)/(a+c-sqrt((a-c)^2+b^2)));
Axis = [max(MA1,MA2),min(MA1,MA2)];

% 长轴倾角
if b==0
    if f*a>f*c
        Theta = 0;
    else  
        Theta = pi/2;
    end
else
    if f*a>f*c
        alpha = atan((a-c)/b);
        if alpha<0
            Theta = 0.5*(-pi/2-alpha);
        else
            Theta = 0.5*(pi/2-alpha);
        end
    else
        alpha = atan((a-c)/b);
        if alpha<0
            Theta = pi/2+0.5*(-pi/2-alpha);
        else
            Theta = pi/2+0.5*(pi/2-alpha);
        end
    end
end
end
cpp 复制代码
function C=drawellipse(W)
% 获取椭圆参数:中心、长、短半轴和长轴倾角
[Center,Axis,Theta] = calellipseparams(W);

% 绘制椭圆
funs = @(x,y) W(1)*x.^2 + W(2)*x.*y + W(3)*y.^2 + W(4)*x + W(5)*y + W(6);
fimplicit(funs,'LineWidth',2)

% 绘制长短轴
Majcoor = [-Axis(1),0; Axis(1),0];
Mincoor = [0,-Axis(2); 0,Axis(2)];
RM = [cos(Theta),-sin(Theta);sin(Theta),cos(Theta)];
Majcoor = Majcoor*RM'+Center;
Mincoor = Mincoor*RM'+Center;

Slen = sqrt((Mincoor(1,1)-Mincoor(2,1))^2 + (Mincoor(1,2)-Mincoor(2,2))^2);
Llen = sqrt((Majcoor(1,1)-Majcoor(2,1))^2 + (Majcoor(1,2)-Majcoor(2,2))^2);
 C =(3.1415926*Slen+2*(Llen-Slen));

line(Majcoor(:,1),Majcoor(:,2),'Color','r','LineWidth',3)
line(Mincoor(:,1),Mincoor(:,2),'Color','g','LineWidth',3)
plot(Center(1),Center(2),'y.','MarkerSize',15)

end

(2)利用以上函数对已有散点进行椭圆拟合,并计算椭圆的周长如下:

cpp 复制代码
XX=[....];%需拟合的散点
YY=[.....];

% 椭圆拟合
W = fitellipse(YY',ZZ');%输入参数为列向量且长度一致,不是列向量时需要转置

% 绘制结果
figure
plot(YY,ZZ,'.'), 
axis equal
hold on
C=drawellipse(W);%返回椭圆周长
axis equal

下面是本次拟合的结果,看起来还不错,

相关推荐
凉白开3385 分钟前
Scala基础知识
开发语言·后端·scala
不要不开心了7 分钟前
Scala内容
开发语言·pytorch·flask·scala·dash
2401_824256868 分钟前
Scala的函数式编程
开发语言·后端·scala
幻想趾于现实25 分钟前
C# Winform 入门(2)之发送邮件
开发语言·c#
半盏茶香31 分钟前
启幕数据结构算法雅航新章,穿梭C++梦幻领域的探索之旅——堆的应用之堆排、Top-K问题
java·开发语言·数据结构·c++·python·算法·链表
小吴先生6661 小时前
Groovy 规则执行器,加载到缓存
java·开发语言·缓存·groovy
秋风&萧瑟1 小时前
【QT】QT的多界面跳转以及界面之间传递参数
开发语言·qt
骑牛小道士1 小时前
JAVA- 锁机制介绍 进程锁
java·开发语言
郭涤生1 小时前
Chapter 1: Historical Context_《C++20Get the details》_notes
开发语言·c++20
独好紫罗兰1 小时前
洛谷题单2-P5712 【深基3.例4】Apples-python-流程图重构
开发语言·python·算法