椭圆拟合理论推导和Matlab实现

1 理论推导

前面一篇文章,解决了最小二乘圆拟合的问题。这篇文章将以类似的方法解决椭圆拟合的问题。

首先搞清楚问题,最小二乘拟合椭圆,即输入为散点集{(xi,yi)∣xi∈R,yi∈R}\{(x_i,y_i)|x_i\in \R,y_i\in \R\}{(xi​,yi​)∣xi​∈R,yi​∈R},定义新的向量{X∣X=[x1x2...xn]T∈Rn}\{X|X=[x_1\ x_2...x_n]^T\in \R^n\}{X∣X=[x1​ x2​...xn​]T∈Rn}和{Y∣Y=[y1y2...yn]T∈Rn}\{Y|Y=[y_1\ y_2...y_n]^T\in \R^n\}{Y∣Y=[y1​ y2​...yn​]T∈Rn},求解能够尽可能接近这些点的椭圆。一般斜椭圆具有5个参数,即椭圆中心坐标(x0,y0)(x_0,y_0)(x0​,y0​),椭圆长径和短径R1,R2R_1,R_2R1​,R2​以及坐标轴旋转的角度ϕ\phiϕ,只需要求解了这几个参数椭圆就被唯一确定了。那么对于椭圆的求解则至少需要5个独立的方程。即输入的点的个数至少是5个。

然后开始我们正式的推导,我们在中学时代就已经知道,一般的圆锥曲线的隐式方程为:
Ax2+Bxy+Cy2+Dx+Ey+1=0Ax^2+Bxy+Cy^2+Dx+Ey+1=0 Ax2+Bxy+Cy2+Dx+Ey+1=0
其与我们想要参数之间的转换关系是(这个地方的推导比较复杂,不是重点):
{x0=BE−2CD4AC−B2y0=BD−2AE4AC−B2R1=2(Ax02+Cy02+Bx0y0−1)A+C+(A−C)2+B2R2=2(Ax02+Cy02+Bx0y0−1)A+C−(A−C)2+B2ϕ=12arctan(BA−C)\begin{cases} \begin{aligned} x_0&=\frac{BE-2CD}{4AC-B^2}\\ y_0&=\frac{BD-2AE}{4AC-B^2}\\ R_1&=\sqrt{\frac{2(Ax_0^2+Cy_0^2+Bx_0y_0-1)}{A+C+\sqrt{(A-C)^2+B^2}}}\\ R_2&=\sqrt{\frac{2(Ax_0^2+Cy_0^2+Bx_0y_0-1)}{A+C-\sqrt{(A-C)^2+B^2}}}\\ \phi &= \frac{1}{2}arctan(\frac{B}{A-C}) \end{aligned} \end{cases} ⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧​x0​y0​R1​R2​ϕ​=4AC−B2BE−2CD​=4AC−B2BD−2AE​=A+C+(A−C)2+B2​2(Ax02​+Cy02​+Bx0​y0​−1)​​=A+C−(A−C)2+B2​2(Ax02​+Cy02​+Bx0​y0​−1)​​=21​arctan(A−CB​)​​
值得一提的是,上式中的长径和短径并一定满足R1>R2R_1>R_2R1​>R2​,称呼为旋转前X轴截距的一半和y轴截距的一半其实更为准确。这样做的目的是为了不失一般性;同样为了不失去一般性,设ϕ∈[0,2π]\phi \in [0,2\pi]ϕ∈[0,2π]。因此在Matlab中使用反三角函数时,采用atan2() 二不是 atan()

为了计算的方便,凭借我们朴素的数学直觉,我们对于隐式方程进行x2x^2x2项系数归一处理:
x2+axy+by2+cx+dy+e=0x^2+axy+by^2+cx+dy+e=0 x2+axy+by2+cx+dy+e=0

对于每个点,都是关于未知数向量[abcde]T[a\ b\ c\ d\ e]^T[a b c d e]T的线性方程,写成矩阵形式为:
[xyy2xy1]×[abcde]=−x2\begin{bmatrix} xy&y^2&x&y&1 \end{bmatrix}\times \begin{bmatrix} a\\b\\c\\d\\e \end{bmatrix}=-x^2 [xy​y2​x​y​1​]×⎣⎢⎢⎢⎢⎡​abcde​⎦⎥⎥⎥⎥⎤​=−x2
这样对于每个点,我们都能得到一个线性方程。对于nnn个点,我们将得到的方程写成矩阵的形式:
[x1y1y12x1y11x2y2y22x2y21⋮⋮⋮⋮⋮xnynyn2xnyn1]×[abcde]=−[x12x22⋮xn2]\begin{bmatrix} x_1y_1&y_1^2&x_1&y_1&1\\ x_2y_2&y_2^2&x_2&y_2&1\\ \vdots&\vdots&\vdots&\vdots&\vdots\\ x_ny_n&y_n^2&x_n&y_n&1 \end{bmatrix}\times \begin{bmatrix} a\\b\\c\\d\\e \end{bmatrix}= -\begin{bmatrix} x_1^2\\x_2^2\\\vdots\\x_n^2 \end{bmatrix} ⎣⎢⎢⎢⎡​x1​y1​x2​y2​⋮xn​yn​​y12​y22​⋮yn2​​x1​x2​⋮xn​​y1​y2​⋮yn​​11⋮1​⎦⎥⎥⎥⎤​×⎣⎢⎢⎢⎢⎡​abcde​⎦⎥⎥⎥⎥⎤​=−⎣⎢⎢⎢⎡​x12​x22​⋮xn2​​⎦⎥⎥⎥⎤​
这个问题中,未知数的个数为5,独立方程的个数为nnn。矩阵论中给出了形如AX=bAX=bAX=b的方程组在独立方程个数多于未知数个数时的最佳二乘解为X=A+bX=A^+bX=A+b,其中A+A^+A+表示的是矩阵AAA的M-P广义逆。

对于我们这个问题我们需要求下面这个矩阵的广义逆:
A=[x1y1y12x1y11x2y2y22x2y21⋮⋮⋮⋮⋮xnynyn2xnyn1]A=\begin{bmatrix} x_1y_1&y_1^2&x_1&y_1&1\\ x_2y_2&y_2^2&x_2&y_2&1\\ \vdots&\vdots&\vdots&\vdots&\vdots\\ x_ny_n&y_n^2&x_n&y_n&1 \end{bmatrix} A=⎣⎢⎢⎢⎡​x1​y1​x2​y2​⋮xn​yn​​y12​y22​⋮yn2​​x1​x2​⋮xn​​y1​y2​⋮yn​​11⋮1​⎦⎥⎥⎥⎤​
对于拟合问题,矩阵AAA是一个列满秩矩阵。矩阵论中给出了列满秩矩阵的广义逆计算公式为:
A+=(AHA)−AHA^+=(A^HA)^-A^H A+=(AHA)−AH
对于实矩阵,AHA^HAH表示其对称矩阵,则未知数构成的向量的解为:
[abcde]=(AHA)−AH[−x12−x22⋮−xn2]=B−C\begin{bmatrix} a\\b\\c\\d\\e \end{bmatrix}=(A^HA)^-A^H \begin{bmatrix} -x_1^2\\-x_2^2\\\vdots\\-x_n^2\\ \end{bmatrix}=B^-C ⎣⎢⎢⎢⎢⎡​abcde​⎦⎥⎥⎥⎥⎤​=(AHA)−AH⎣⎢⎢⎢⎡​−x12​−x22​⋮−xn2​​⎦⎥⎥⎥⎤​=B−C
计算BBB矩阵:
B=AHA=[x1y1x2y2⋯xnyny12y22⋯yn2x1x2⋯xny1y2⋯yn11⋯1][x1y1y12x1y11x2y2y22x2y21⋮⋮⋮⋮⋮xnynyn2xnyn1]=[∑i=1nxi2yi2∑i=1nxiyi3∑i=1nxi2yi∑i=1nxiyi2∑i=1nxiyi∑i=1nxiyi3∑i=1nyi4∑i=1nxiyi2∑i=1nyi3∑i=1nyi2∑i=1nxi2yi∑i=1nxiyi2∑i=1nxi2∑i=1nxiyi∑i=1nxi∑i=nnxiyi2∑i=1nyi3∑i=1nxiyi∑i=1nyi2∑i=1nyi∑i=1nxiyi∑i=1nyi2∑i=1nxi∑i=1nyi∑i=1n1]B=A^HA = \begin{bmatrix} x_1y_1&x_2y_2&\cdots&x_ny_n\\ y_1^2&y_2^2&\cdots&y_n^2\\ x_1&x_2&\cdots&x_n\\ y_1&y_2&\cdots&y_n\\ 1&1&\cdots&1 \end{bmatrix} \begin{bmatrix} x_1y_1&y_1^2&x_1&y_1&1\\ x_2y_2&y_2^2&x_2&y_2&1\\ \vdots&\vdots&\vdots&\vdots&\vdots\\ x_ny_n&y_n^2&x_n&y_n&1 \end{bmatrix}\\= \begin{bmatrix} \sum_{i=1}^nx_i^2y_i^2&\sum_{i=1}^nx_iy_i^3&\sum_{i=1}^nx_i^2y_i&\sum_{i=1}^nx_iy_i^2&\sum_{i=1}^nx_iy_i\\ \sum_{i=1}^nx_iy_i^3&\sum_{i=1}^ny_i^4&\sum_{i=1}^nx_iy_i^2&\sum_{i=1}^ny_i^3&\sum_{i=1}^ny_i^2\\ \sum_{i=1}^nx_i^2y_i&\sum_{i=1}^nx_iy_i^2&\sum_{i=1}^nx_i^2&\sum_{i=1}^nx_iy_i&\sum_{i=1}^nx_i\\ \sum_{i=n}^nx_iy_i^2&\sum_{i=1}^ny_i^3&\sum_{i=1}^nx_iy_i&\sum_{i=1}^ny_i^2&\sum_{i=1}^ny_i\\ \sum_{i=1}^nx_iy_i&\sum_{i=1}^ny_i^2&\sum_{i=1}^nx_i &\sum_{i=1}^ny_i &\sum_{i=1}^n1 \end{bmatrix} B=AHA=⎣⎢⎢⎢⎢⎡​x1​y1​y12​x1​y1​1​x2​y2​y22​x2​y2​1​⋯⋯⋯⋯⋯​xn​yn​yn2​xn​yn​1​⎦⎥⎥⎥⎥⎤​⎣⎢⎢⎢⎡​x1​y1​x2​y2​⋮xn​yn​​y12​y22​⋮yn2​​x1​x2​⋮xn​​y1​y2​⋮yn​​11⋮1​⎦⎥⎥⎥⎤​=⎣⎢⎢⎢⎢⎡​∑i=1n​xi2​yi2​∑i=1n​xi​yi3​∑i=1n​xi2​yi​∑i=nn​xi​yi2​∑i=1n​xi​yi​​∑i=1n​xi​yi3​∑i=1n​yi4​∑i=1n​xi​yi2​∑i=1n​yi3​∑i=1n​yi2​​∑i=1n​xi2​yi​∑i=1n​xi​yi2​∑i=1n​xi2​∑i=1n​xi​yi​∑i=1n​xi​​∑i=1n​xi​yi2​∑i=1n​yi3​∑i=1n​xi​yi​∑i=1n​yi2​∑i=1n​yi​​∑i=1n​xi​yi​∑i=1n​yi2​∑i=1n​xi​∑i=1n​yi​∑i=1n​1​⎦⎥⎥⎥⎥⎤​
计算CCC矩阵:
C=AH×[−x12−x22⋮−xn2]=[x1y1x2y2⋯xnyny12y22⋯yn2x1x2⋯xny1y2⋯yn11⋯1][−x12−x22⋮−xn2]=−[∑i=1nxi3yi∑i=1nxi2yi2∑i=1nxi3∑i=1nxi2yi∑i=1nxi2]C=A^H\times \begin{bmatrix} -x_1^2\\ -x_2^2\\ \vdots\\ -x_n^2 \end{bmatrix}= \begin{bmatrix} x_1y_1&x_2y_2&\cdots&x_ny_n\\ y_1^2&y_2^2&\cdots&y_n^2\\ x_1&x_2&\cdots&x_n\\ y_1&y_2&\cdots&y_n\\ 1&1&\cdots&1 \end{bmatrix} \begin{bmatrix} -x_1^2\\ -x_2^2\\ \vdots\\ -x_n^2 \end{bmatrix} =-\begin{bmatrix} \sum_{i=1}^nx_i^3y_i\\ \sum_{i=1}^nx_i^2y_i^2\\ \sum_{i=1}^nx_i^3\\ \sum_{i=1}^nx_i^2y_i\\ \sum_{i=1}^nx_i^2 \end{bmatrix} C=AH×⎣⎢⎢⎢⎡​−x12​−x22​⋮−xn2​​⎦⎥⎥⎥⎤​=⎣⎢⎢⎢⎢⎡​x1​y1​y12​x1​y1​1​x2​y2​y22​x2​y2​1​⋯⋯⋯⋯⋯​xn​yn​yn2​xn​yn​1​⎦⎥⎥⎥⎥⎤​⎣⎢⎢⎢⎡​−x12​−x22​⋮−xn2​​⎦⎥⎥⎥⎤​=−⎣⎢⎢⎢⎢⎡​∑i=1n​xi3​yi​∑i=1n​xi2​yi2​∑i=1n​xi3​∑i=1n​xi2​yi​∑i=1n​xi2​​⎦⎥⎥⎥⎥⎤​

细心的读者可能会发现,如果样本的值本身比较大,那么对齐进行平方、立方等处理后进行求和,很可能会导致程序中的变量对应的寄存器存储不了这么庞大的数,因此在程序中需要把xi,yix_i,y_ixi​,yi​变换到xi∈[−1,1],yi∈[−1,1]x_i \in[-1,1],y_i\in[-1,1]xi​∈[−1,1],yi​∈[−1,1]。具体做法是每个元素除以其构成的向量中的最大绝对值。最后计算完后再进行逆变换。

至此我们在具备矩阵论知识的基础上,推导了最佳拟合椭圆的解析解。

2 Matlab 实现

[Talk is cheap;Show me the code.]

在前文理论的支撑下,啪的一下就写完了,很快啊!

最小二乘椭圆拟合函数:

%%020406081012141618202224262830323436384042444648505254565860626466687072747678%%
%@func:Fit the scatters by least-square ellipse;
%@inpt:Coordinate set (x,y);
%@oupt:The structure contains the center of the ellipse, the long and short dia-
%      meters and the rotation angle;
%@note:
%@date:2021/01/23 by xiyin,li in hust;
function [ellipse] = ellipseFit(x,y)
xlength = length(x);
xmax = max(abs(x));
ymax = max(abs(y));
x = x./xmax;
y = y./ymax;%%归一化处理
if(xlength ~= length(y) | xlength  < 5)warning('the length of x and y must be same and >= 5');
elsexigema.one = xlength;  xigema.x = sum(x);     xigema.y = sum(y);xigema.xx =sum(x.*x);  xigema.xy = sum(x.*y); xigema.yy = sum(y.*y);xigema.xxx = sum(x.^3); xigema.xxy = sum(x.*x.*y);xigema.xyy = sum(x.*y.*y); xigema.yyy = sum(y.^3);xigema.xxxy = sum(x.^3.*y);xigema.xxyy = sum(x.*x.*y.*y);xigema.xyyy = sum(x.*y.^3);xigema.yyyy = sum(y.^4);B = [xigema.xxyy xigema.xyyy xigema.xxy xigema.xyy xigema.xy;xigema.xyyy xigema.yyyy xigema.xyy xigema.yyy xigema.yy;xigema.xxy xigema.xyy xigema.xx xigema.xy xigema.x;xigema.xyy xigema.yyy xigema.xy xigema.yy xigema.y;xigema.xy xigema.yy xigema.x xigema.y xigema.one];if(rank(B)<5)warning("Please check input set again")elseC = [xigema.xxxy;xigema.xxyy;xigema.xxx;xigema.xxy;xigema.xx];D = -inv(B)*C;%标准方程参数(注意反归一化)norm.a = 1/(xmax*xmax*D(5));norm.b = D(1)/(xmax*ymax*D(5));norm.c = D(2)/(ymax*ymax*D(5));norm.d = D(3)/(xmax*D(5));norm.e = D(4)/(ymax*D(5));%参数方程参数ellipse.x0  =(norm.b*norm.e-2*norm.c*norm.d)/(4*norm.a*norm.c-norm.b^2);ellipse.y0 = (norm.b*norm.d-2*norm.a*norm.e)/(4*norm.a*norm.c-norm.b^2);ellipse.a = sqrt((2*(norm.a*ellipse.x0^2+norm.c*ellipse.y0^2+norm.b*ellipse.x0*ellipse.y0-1)).../(norm.a+norm.c+sqrt((norm.a-norm.c)^2+norm.b^2)));ellipse.b = sqrt((2*(norm.a*ellipse.x0^2+norm.c*ellipse.y0^2+norm.b*ellipse.x0*ellipse.y0-1)).../(norm.a+norm.c-sqrt((norm.a-norm.c)^2+norm.b^2)));ellipse.phi = 0.5*atan2(norm.b,(norm.a-norm.c));%绘制图像theta =  linspace(0.1*pi,1.9*pi,100)plot(x*xmax,y*ymax,'o')hold onx = ellipse.a * cos(theta);y = ellipse.b * sin(theta);Ex = (x*cos(ellipse.phi)-y*sin(ellipse.phi) + ellipse.x0);Ey = (x*sin(ellipse.phi)+y*cos(ellipse.phi) + ellipse.y0);plot(Ex,Ey,'r','linewidth',1.6)axis equalend
end
end

使用如下的例子进行测试(对于斜椭圆和其他形式的椭圆已经做过了测试):

clc,clear;
close all
Sensor012 = csvread('CircleSensor012.csv');
Sensor.num1.x = Sensor012(4,:);
Sensor.num1.y = Sensor012(5,:);
Sensor.num1.z = Sensor012(6,:);
figure(1)
ellipse = ellipseFit(Sensor.num1.x,Sensor.num1.z)
figure(2)
t = linspace(0,2*pi,180);
x = 5000*sin(t-0.1*pi);
y = 3000*cos(t+pi/4);
ellipse = ellipseFit(x,y)

结果为:

3 总结

  • 本文通过M-P广义逆求取了最小二乘椭圆。

  • 本文通过Matlab进行了实现,实现过程与推导过程完全一致。

  • 今天Markdown比昨天顺手多了,公式等号对齐怎么这么难用。

  • 后面将进行双曲线拟合以及其他一些二次型曲线拟合(如果用不到估计就不会写了)。

椭圆拟合理论推导和Matlab实现相关推荐

  1. 【自适应盲均衡4】基于RLS的多径衰落信道均衡算法(RLS-CMA)的理论推导与MATLAB仿真

    关注公号[逆向通信猿]更精彩!!! 一.回顾CMA和MMA 对于前面两种算法 [自适应均衡]多径衰落信道的复数常模算法(CMA)的理论推导与MATLAB仿真 [自适应均衡]多模算法(MMA)--复数改 ...

  2. 【自适应盲均衡3】多模算法(MMA)——复数改进常模算法(MCMA)的理论推导与MATLAB仿真

    关注公号[逆向通信猿]更精彩!!! 接上篇[自适应均衡2]多径衰落信道的复数常模算法(CMA)的理论推导与MATLAB仿真 理论推导 MMA或者MCMA其实是在CMA基础上改进而得到的,有学者称其为实 ...

  3. 椭圆 —— 从理论推导到最小二乘法拟合

    前言 椭圆在高中数学里就开始提到,都是从标准方程开始如: x2a2+y2b2=1(a>b>0)\frac{x^2}{a^2}+\frac{y^2}{b^2}=1(a>b>0) ...

  4. 【自适应盲均衡2】多径衰落信道的复数常模算法(CMA)的理论推导与MATLAB仿真

    关注公号[逆向通信猿]更精彩!!! 关于均衡的基础知识,首先可参考本人博客 LMMSE.Godard.CMA常模.Sato等算法在信道均衡中的应用理论与MATLAB仿真 理论推导 代价函数 J = E ...

  5. FEM基函数:从理论推导到matlab实现形式

    这次的内容是补充昨天的内容的理论推导部分 二维FEM建模及求解(入门级:数理方程到代码编写)_m0_58134168的博客-CSDN博客 直接粘理论推导的笔记: 以上即为理论到matlab代码实现的矩 ...

  6. c++椭圆最小二乘法原理_利用最小二乘法拟合椭圆方程的理论推导,附有matlab代码...

    为了很好的进行椭圆方程拟合,本文先对椭圆基本知识进行复习,后进行非标准椭圆方程拟合公式推导,最后有matlab代码的实现. 1. 用最小二乘法做椭圆拟合 1.1. 椭圆标准方程 对椭圆印象最深的就是高 ...

  7. 【图像分割】基于区域的重叠椭圆拟合实现细胞分割附matlab代码

    1 内容介绍 一种基于区域的方法,用于用自动确定的可能重叠椭圆的数量来逼近任意 2D 形状.RFOVE 是完全无监督的,在没有任何假设或关于对象形状的先验知识的情况下运行,并且扩展和改进了递减椭圆拟合 ...

  8. MATLAB实战系列(三十三)-技术和医疗的完美结合(续),基于最小二乘法的椭圆拟合

    前言 在上篇文章,基于MATLAB的骨骼测量系统--医学影像研究中,第3节金属球的求识别,运用到椭圆函数拟合来得到金属球大小.本文介绍如何采用MATLAB进行椭圆拟合,包括特殊的圆,一般椭圆及倾斜椭圆 ...

  9. matlab画椭圆 长轴 短轴,跟踪目标的快速椭圆拟合方法

    摘  要: 提出一种基于最小外包矩形的快速椭圆拟合方法,该方法利用最小二乘法获得目标的最小外包矩形框,再求取外包矩形框的内切椭圆,该椭圆能有效反映目标的大部分运动信息.本文对该方法进行了目标拟合的有效 ...

最新文章

  1. silverlight 无法发布 如何灵活配置IP
  2. Linux软件安装管理---源码安装
  3. MQ和RabbitMQ作用特点
  4. 【算法设计】虎溪校园导游系统
  5. 移动端数据统计,精细化运营的永动机
  6. 微软统一预训练语言模型UniLM 2.0解读
  7. Android之Installation error: INSTALL_FAILED_UPDATE_INCOMPATIBLE问题解决
  8. What?一个 Dubbo 服务启动要两个小时!
  9. mysql安装及一些注意点
  10. mac电脑bash_profile创建,打开,编辑,保存
  11. 彻底解决git中.gitignore文件失效原因及解决办法
  12. vbs无法拒绝的表白代码
  13. 自适应滤波器之块自适应滤波器
  14. android ts流解码,DVB开发之TS流的接收,解码与播放
  15. 21天养成早起晨记习惯-早起的秘诀
  16. 忒修斯之船,你还是原来的你吗?
  17. 【集合论】序关系 ( 哈斯图示例 | 整除关系哈斯图 | 包含关系哈斯图 | 加细关系哈斯图 )
  18. #小何不断努力#8.18
  19. 《三体》里的超级计算机_我们今天能造出来吗?
  20. 李开复写给中国大学生的第三封信

热门文章

  1. python的sort方法是哪种_python中的sort方法使用详解
  2. 什么是jiathis,为什么用jiathis
  3. FPGA中加扰与解扰的实现
  4. 响应式pbootcms模板网站建设类网站
  5. Day19 学习java(网络编程、正则表达式)
  6. 机器视觉检测技术在螺丝螺母缺陷检测中的应用
  7. Win7或是过渡品Win8前瞻消息全预览
  8. 为什么LCC充电会卡在一个固定的电压值呢?
  9. 【MongoDB入门】
  10. iOS button设置背景图片后,设置cornerRadius没效果的问题