算法思想:

算法通过最小化约束条件4ac-b^2 = 1,最小化距离误差。利用最小二乘法进行求解,首先引入拉格朗日乘子算法获得等式组,然后求解等式组得到最优的拟合椭圆。

算法的优点:

  a、椭圆的特异性,在任何噪声或者遮挡的情况下都会给出一个有用的结果;

  b、不变性,对数据的Euclidean变换具有不变性,即数据进行一系列的Euclidean变换也不会导致拟合结果的不同;

  c、对噪声具有很高的鲁棒性;

  d、计算高效性。

算法原理:

代码实现(Matlab):

 %
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,
%
% @Article{Fitzgibbon99,
% author = "Fitzgibbon, A.~W.and Pilu, M. and Fisher, R.~B.",
% title = "Direct least-squares fitting of ellipses",
% journal = pami,
% year = 1999,
% volume = 21,
% number = 5,
% month = may,
% pages = "476--480"
% }
%
% 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 ==
% Create an ellipse
t = linspace(,); Rx = ;
Ry = ;
Cx = ;
Cy = ;
Rotation = .; % Radians NoiseLevel = .; % Will add Gaussian noise of this std.dev. to points x = Rx * cos(t);
y = Ry * sin(t);
nx = x*cos(Rotation)-y*sin(Rotation) + Cx + randn(size(t))*NoiseLevel;
ny = x*sin(Rotation)+y*cos(Rotation) + Cy + randn(size(t))*NoiseLevel; % Clear figure
clf
% Draw it
plot(nx,ny,'o');
% Show the window
figure(gcf)
% Fit it
params = fitellipse(nx,ny);
% Note it may return (Rotation - pi/) and swapped radii, this is fine.
Given = round([Cx Cy Rx Ry Rotation*])
Returned = round(params.*[ ]) % Draw the returned ellipse
t = linspace(,pi*);
x = params() * cos(t);
y = params() * sin(t);
nx = x*cos(params())-y*sin(params()) + params();
ny = x*sin(params())+y*cos(params()) + params();
hold on
plot(nx,ny,'r-') return
end % normalize data
mx = mean(X);
my = mean(Y);
sx = (max(X)-min(X))/;
sy = (max(Y)-min(Y))/; x = (X-mx)/sx;
y = (Y-my)/sy; % Force to column vectors
x = x(:);
y = y(:); % Build design matrix
D = [ x.*x x.*y y.*y x y ones(size(x)) ]; % Build scatter matrix
S = D'*D; % Build 6x6 constraint matrix
C(,) = ; C(,) = -; C(,) = ; C(,) = -; % Solve eigensystem
if
% Old way, numerically unstable if not implemented in matlab
[gevec, geval] = eig(S,C); % Find the negative eigenvalue
I = find(real(diag(geval)) < 1e-8 & ~isinf(diag(geval))); % Extract eigenvector corresponding to negative eigenvalue
A = real(gevec(:,I));
else
% New way, numerically stabler in C [gevec, geval] = eig(S,C); % Break into blocks
tmpA = S(:,:);
tmpB = S(:,:);
tmpC = S(:,:);
tmpD = C(:,:);
tmpE = inv(tmpC)*tmpB';
[evec_x, eval_x] = eig(inv(tmpD) * (tmpA - tmpB*tmpE)); % Find the positive (as det(tmpD) < ) eigenvalue
I = find(real(diag(eval_x)) < 1e-8 & ~isinf(diag(eval_x))); % Extract eigenvector corresponding to negative eigenvalue
A = real(evec_x(:,I)); % Recover the bottom half...
evec_y = -tmpE * A;
A = [A; evec_y];
end % unnormalize
par = [
A()*sy*sy, ...
A()*sx*sy, ...
A()*sx*sx, ...
-*A()*sy*sy*mx - A()*sx*sy*my + A()*sx*sy*sy, ...
-A()*sx*sy*mx - *A()*sx*sx*my + A()*sx*sx*sy, ...
A()*sy*sy*mx*mx + A()*sx*sy*mx*my + A()*sx*sx*my*my ...
- A()*sx*sy*sy*mx - A()*sx*sx*sy*my ...
+ A()*sx*sx*sy*sy ...
]'; % Convert to geometric radii, and centers thetarad = 0.5*atan2(par(),par() - par());
cost = cos(thetarad);
sint = sin(thetarad);
sin_squared = sint.*sint;
cos_squared = cost.*cost;
cos_sin = sint .* cost; Ao = par();
Au = par() .* cost + par() .* sint;
Av = - par() .* sint + par() .* cost;
Auu = par() .* cos_squared + par() .* sin_squared + par() .* cos_sin;
Avv = par() .* sin_squared + par() .* cos_squared - par() .* cos_sin; % ROTATED = [Ao Au Av Auu Avv] tuCentre = - Au./(.*Auu);
tvCentre = - Av./(.*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];

实验效果:

a、同等噪声条件下,不同长度的样本点,导致的拟合结果,如下所示:

b、相同长度的样本点下,不同噪声的样本点,导致的拟合结果,如下所示:

c、少样本点下,拟合结果如下:

源码下载:

      地址: FitEllipse

参考文献:

[1]. Andrew W. Fitzgibbon, Maurizio Pilu and Robert B. Fisher. Direct Least Squares Fitting of Ellipses. 1996.

[2]. http://research.microsoft.com/en-us/um/people/awf/ellipse/

基于直接最小二乘的椭圆拟合(Direct Least Squares Fitting of Ellipses)的更多相关文章

  1. 基于MATLAB的多项式数据拟合方法研究-毕业论文

    摘要:本论文先介绍了多项式数据拟合的相关背景,以及对整个课题做了一个完整的认识.接下来对拟合模型,多项式数学原理进行了详细的讲解,通过对文献的阅读以及自己的知识积累对原理有了一个系统的认识.介绍多项式 ...

  2. opencv学习之路(27)、轮廓查找与绘制(六)——外接圆、椭圆拟合、逼近多边形曲线、计算轮廓面积及长度、提取不规则轮廓

    一.最小外接圆 #include "opencv2/opencv.hpp" #include<iostream> using namespace std; using ...

  3. 【Matlab&Mathematica】对三维空间上的点进行椭圆拟合

    问题是这样:比如有一个地心惯性系的轨道,然后从轨道上取了几个点,问能不能根据这几个点把轨道还原了? 当然,如果知道轨道这几个点的速度的情况下,根据轨道六根数也是能计算轨道的,不过真近点角是随时间变动的 ...

  4. 基于EM的多直线拟合

    作者:桂. 时间:2017-03-22  06:13:50 链接:http://www.cnblogs.com/xingshansi/p/6597796.html 声明:欢迎被转载,不过记得注明出处哦 ...

  5. 基于EM的多直线拟合实现及思考

    作者:桂. 时间:2017-03-22  06:13:50 链接:http://www.cnblogs.com/xingshansi/p/6597796.html 声明:欢迎被转载,不过记得注明出处哦 ...

  6. Dlib Opencv cv2.fitEllipse用于人眼轮廓椭圆拟合

    dlib库的安装以及人脸特征点的识别分布分别在前两篇博文里面 Dlib Python 检测人脸特征点 Face Landmark Detection Mac OSX下安装dlib (Python) 这 ...

  7. 6、基于highcharts实现的线性拟合,计算部分在java中实现,画的是正态概率图

    1.坐标点类 package cn.test.domain; public class Point { double x; double y; public Point(){ } public Poi ...

  8. C# + Matlab 实现计件工时基于三层BP神经网络的拟合--真实项目

    工序工时由该工序的工艺参数决定,有了工时后乘以固定因子就是计件工资.一般参考本地小时工资以及同类小时工资并考虑作业的风险等因素给出固定因子 采用的VS2010 , Matlab2015a 64,  开 ...

  9. 【翻译】拟合与高斯分布 [Curve fitting and the Gaussian distribution]

    参考与前言 英文原版 Original English Version:https://fabiandablander.com/r/Curve-Fitting-Gaussian.html 如何通俗易懂 ...

随机推荐

  1. mvc 分部视图(Partial)显示登陆前后变化以及Shared文件夹在解决方案资源管理器中没有显示的问题

    刚开始我的解决方案资源管理器中没有显示Shared文件夹,但Shared文件夹在项目中是实际存在的,我搜了下好像没有类似的解答(可能是我搜索的关键词不够准确).后来自己看了下vs2012. 其实解决方 ...

  2. unity 2d 游戏优化之路 遇坑记录

    情景说明:  unity 出的Android包,在目前一些主流机型跑都没有问题,但是在 小米3 这种比较老的机器上跑,报如下错误 GLSL compilation failed, no infolog ...

  3. java基础45 IO流技术(输入字符流/缓冲输入字符流)

    一.输入字符流 1.1.输入字符流体系 ------| Reader:输入字符流的基类(抽象类)  ----------| FileReader:向指定文件读取数据的输入字符流(把硬盘上的数据读取到程 ...

  4. 回归模型效果评估系列3-R平方

    决定系数(coefficient of determination,R2)是反映模型拟合优度的重要的统计量,为回归平方和与总平方和之比.R2取值在0到1之间,且无单位,其数值大小反映了回归贡献的相对程 ...

  5. 由结构体成员地址计算结构体地址——list_entry()原理详解

    #define list_entry(ptr, type, member) container_of(ptr, type, member) 在进行编程的时候,我们经常在知道结构体地址的情况下,寻找其中 ...

  6. (三)HtmlUnit 实践

    第一节: htmlunit 爬取百度云资源

  7. 使用EasyWechat快速开发微信公众号支付

    前期准备: 申请微信支付后, 会收到2个参数, 商户id,和商户key.注意,这2个参数,不要和微信的参数混淆.微信参数: appid, appkey, token支付参数: merchant_id( ...

  8. 如何在k8s集群里快速运行一个镜像?

    在docker里,快速run一个镜像,很简单的. k8s的世界,与之类似. 但要注意一下,如果镜像本身没有提供command命令,这个容器由于前台输出完成,很快就退出了. 所以,遇到这种镜像,就最好自 ...

  9. Pg168—2题 修改

    package org.hanqi.pn0120; public class JuXing { JuXing(double chang,double kuan) { this.chang=chang; ...

  10. 【51nod】1312 最大异或和

    题解 很显然我们求出一组线性基来,如果有M个基,那么可以构造N - M + 1个最大异或值 而对于线性基中的元素,除了最大的元素,我们用最大异或值异或掉每个元素累加进答案 而不是把线性基中的元素处理成 ...