平面二维任意椭圆数据拟合算法推导及程序实现详解

2023-11-13

         在刚刚过去的2017全国大学生数学建模比赛中,笔者有幸指导了一组本科学生参赛。对于赛题A《 CT系统参数标定及成像》中的CT系统参数标定,经过将问题进一步的提炼,问题最终变成了在平面二维空间中对任意椭圆进行拟合的问题,笔者花了大概四个小时的时间建立了该问题的数学公式表达、并推导出了求解该问题的算法、同时编写了实现该算法的Matlab程序。整个过程一气呵成,没有一丝的错误,当时就把我震惊了,本来以为会出很多的问题,但是当我编写完代码按下F5的那一刻,出来的结果和我之前预想的一模一样,为了更进一步的验证算法的正确性后续又做了很多的测试,结果表明算法完全正确。那一刻我真的感受到了自己平时公式推导的严谨态度和规范代码编写带来的巨大效率的提升。

公式推导

      好了,闲话不多说了,进入正题,我们通常见到的椭圆表达式是这样的:

      

    这种表达式称为椭圆的标准表达式,即其长短轴分别和坐标轴平行,且中心在坐标原点,但是更一般的椭圆其长短轴不是和坐标轴平行的,且中心也不在原点。我们将上式中的椭圆以坐标原点为旋转中心逆时针旋转θ,得到如下表达式:


展开得:


令:



则有:


此表达式表明此时的椭圆的长短轴已不再和坐标轴平行,但其中心仍在原点,接下来我们将其中心移至点(x_0,y_0)得到:


展开得:


令:


则得到椭圆的一般式:


    从这里我们就可以看到,我们只需要确定参数g, c, d, e, f就可以得到椭圆的中心(x_0,y_0)、旋转角度θ、及长短轴a和b。
    我们可以看到当知道了椭圆上的五个点的坐标后,我们就可以列出一个五元一次方程组,然后求得g, c, d, e, f。然而在实际应用中我们往往得到的数据点是大于5的因此列出的方程是一个超定方程,没有唯一解。但是我们可以求出它的最小二乘解。具体的过程如下:
    设已知椭圆上N个点的坐标的检测值(x_i,y_i) (含有检测误差),i=1,2,•••,N,将每组检测值(x_i,y_i)代入上式,则有方程误差ε_i,即:


    方程误差ε_i是由于对椭圆上点的坐标的检测误差引起的,通常N远大于5。最小二乘法原理就是用极小化方程误差的平方和来确定未知椭圆模型参数(g, c, d, e, f),即他们的极小化性能指标


由极值原则,置


即:


令:



带入上式化简得:

通过求解上述方程从而求得最小二乘意义上的参数(g, c, d, e, f),进而通过关系式:


求得椭圆的中心(x_0,y_0)、旋转角度θ、及长短轴a和b。

Matlab仿真

%椭圆拟合测试程序

clc;
close all;
clear all

alpha = (1:360)/180*pi;  %标准椭圆参数方程角度取值
a = 15;                  %短轴长
b = 40;                  %长轴长
x0 = 5;                  %中心点x坐标
y0 = -10;                %中心点y坐标
Thita = 30/180*pi;       %旋转角度
SNR = 20;                %信噪比

%*********************************生成椭圆数据******************************
%得到标准形式的椭圆数据
x = a*cos(alpha);
y = b*sin(alpha);
%旋转角度Thita
x_r = x*cos(Thita)-y*sin(Thita);
y_r = x*sin(Thita)+y*cos(Thita);
%加入白噪声
x_r = x_r + 10^(-SNR/20)*a*randn(size(x_r));
y_r = y_r + 10^(-SNR/20)*a*randn(size(x_r));
%中心平移到(x0,y0)
x_r_s = x_r + x0;
y_r_s = y_r + y0;

[a_f,b_f,x0_f,y0_f,Thita_f]=Ellipse_fitting(x_r_s,y_r_s);    %椭圆拟合
%%
%**********利用拟合的结果生成拟合后的椭圆数据***********
x = a_f*cos(alpha);
y = b_f*sin(alpha);
x_r = x*cos(Thita_f/180*pi)-y*sin(Thita_f/180*pi);
y_r = x*sin(Thita_f/180*pi)+y*cos(Thita_f/180*pi);
x_r_s_f = x_r + x0_f;
y_r_s_f = y_r + y0_f;
%% 绘图
figure;
plot(x_r_s,y_r_s,'b',x0,y0,'b*');
xlabel('x');
ylabel('y');
axis auto equal
grid on;
hold on;
plot(x_r_s_f,y_r_s_f,'r',x0_f,y0_f,'r*');
legend('原始数据','仿真的椭圆中心','拟合后的','拟合后的椭圆中心');

fprintf('椭圆拟合结果如下(信噪比 SNR=%ddB):\n',SNR);
fprintf('参数 a=%f,b=%f\n',a_f,b_f);
fprintf('中心坐标(x0=%f,y0=%f)\n',x0_f,y0_f);
fprintf('旋转角度 Thita=%f°\n',Thita_f);

椭圆拟合子函数

function [a,b,x0,y0,xita]=Ellipse_fitting(x,y)
%椭圆拟合子函数
%参数说明
%  a:   x轴上的轴半径
%  b:   x轴上的轴半径
%  x0:   椭圆的中心x轴坐标
%  y0:   椭圆的中心y轴坐标
%  xita:椭圆的旋转角度

N = length(x);   %求总点数

avr_x = sum(x)/N;
avr_y = sum(y)/N;
avr_xx = sum(x.*x)/N;
avr_xy = sum(x.*y)/N;
avr_yy = sum(y.*y)/N;

avr_xxx = sum(x.*x.*x)/N;
avr_xxy = sum(x.*x.*y)/N;
avr_xyy = sum(x.*y.*y)/N;
avr_yyy = sum(y.*y.*y)/N;

avr_xxxy = sum(x.*x.*x.*y)/N;
avr_xxyy = sum(x.*x.*y.*y)/N;
avr_xyyy = sum(x.*y.*y.*y)/N;
avr_yyyy = sum(y.*y.*y.*y)/N;

%求系数矩阵
AA = [avr_xxyy,avr_xyyy,avr_xxy,avr_xyy,avr_xy;...
     avr_xyyy,avr_yyyy,avr_xyy,avr_yyy,avr_yy;...
     avr_xxy, avr_xyy, avr_xx, avr_xy, avr_x;...
     avr_xyy, avr_yyy, avr_xy, avr_yy, avr_y;...
     avr_xy,  avr_yy,  avr_x,  avr_y,  1];
 
bb = [-avr_xxxy;...
      -avr_xxyy;...
      -avr_xxx;...
      -avr_xxy;...
      -avr_xx];
   
out = inv(AA)*bb;
%得到一般式的系数   
g = out(1);
c = out(2);
d = out(3);
e = out(4);
f = out(5);
%得到椭圆中心坐标
AAA = [-2, -g;...
       -g, -2*c];
bbb = [d;e];
out1 = inv(AAA)*bbb;
x0 = out1(1);
y0 = out1(2);
%得到过渡系数
A = 1/(x0^2 + c*y0^2 + g*x0*y0 - f);
B = c*A;
C = g*A;
%求得旋转角度
tan_2xita = C/(A-B);
xita = atan(tan_2xita)/2;
sin_xita = sin(xita);
cos_xita = cos(xita);
%求得轴半径
AAAA = [cos_xita^2,sin_xita^2;...
        sin_xita^2,cos_xita^2];
bbbb =[A;B];
out2 = inv(AAAA)*bbbb;
a = sqrt(1/out2(1));
b = sqrt(1/out2(2));

xita = xita/pi*180;       %转化成°

运行一下该程序得到如下结果:


matlab命令窗口输出:


可见拟合的结果与仿真设定的值很接近。














本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

平面二维任意椭圆数据拟合算法推导及程序实现详解 的相关文章

随机推荐

  • week4作业题_A-DDL的恐惧

    A DDL的恐惧 题目描述 ZJM 有 n 个作业 每个作业都有自己的 DDL 如果 ZJM 没有在 DDL 前做完这个作业 那么老师会扣掉这个作业的全部平时分 所以 ZJM 想知道如何安排做作业的顺序 才能尽可能少扣一点分 请你帮帮他吧
  • 数据结构学习笔记(一)线性表

    文章目录 前言 一 线性表是什么 线性结构 线性表 二 线性表的顺序表示和实现 1 什么是线性表的顺序表示 2 代码实现 总结 参考资料 前言 文章目的在于记录学习数据结构这门课程中遇到的知识点以及难点 为解决或优化实际代码问题打好基础 一
  • 辨析BigDecimal的toString()方法和toPlainString()方法

    辨析BigDecimal的toString 方法和toPlainString 方法 toString toString方法会将BigDecimal的值以科学计数方式的字符串 但是转换成科学计数的方式也是有场景的 并不是所有的值都会转为科学计
  • Nginx 代理解决跨域问题分析

    当你遇到跨域问题 不要立刻就选择复制去尝试 请详细看完这篇文章再处理 我相信它能帮到你 分析前准备 前端网站地址 http localhost 8080 服务端网址 http localhost 59200 首先保证服务端是没有处理跨域的
  • Android注册登录页面

    Android注册登录页面 需求 分析 项目目录 java domain JsonBean java UserInfo java utils GetJsonDataUtil java Login java MainActivity java
  • 前端实现预览功能,播放rtsp视频流(node.js+ffmpeg+flv.js)

    实现思路 获取摄像头rtsp流 通过node js ffmpeg转码 通过哔哩哔哩flv js播放 1 获取摄像机RTSP流 之前文章有说明不多阐述 2 配置流媒体服务器 1 下载安装node js 运行node js 网上教程很多自行下载
  • XGBoost-工程实现与优缺点(中)

    工程实现 块结构设计 我们知道 决策树的学习最耗时的一个步骤就是在每次寻找最佳分裂点是都需要对特征的值进行排序 而 XGBoost 在训练之前对根据特征对数据进行了排序 然后保存到块结构中 并在每个块结构中都采用了稀疏矩阵存储格式 Comp
  • 为什么MVC不是一种设计模式

    比较Backbone和Ext4 x在MVC实现上的差异 大漠穷秋 前言 圣人云 不想做妈咪的小姐不是好码农 每一个码农的心中都有一个终极理想 那就是有一天不用再Coding 在成为妈咪的道路上 设计模式 被认为是一项必备的技能 因此 经常有
  • python sys.path.append()和sys.path.insert()的作用与区别

    python程序中使用 import XXX 时 python解析器会在当前目录 已安装和第三方模块中搜索 xxx 如果都搜索不到就会报错 使用sys path append 方法可以临时添加搜索路径 方便更简洁的import其他包和模块
  • Eclipes下载并且导入GitHub中的maven项目

    第一步 确保eclipse装有git和maven插件 最新的eclipse不需要下载应该都集成了这些基本的功能 如果没有这两个插件自己下载安装 第二步 下载GitHub项目 拷贝想要下载的项目URL eclipse gt gt gt Fil
  • C#调用C++封装的SDK库(dll动态库)——下

    C 调用C 封装的SDK库 dll动态库 下 一 说明 上一篇我们相当于封装的是C语言风格的动态dll库 供C 来调用的 C 调用C 封装的SDK库 dll动态库 上 如果我们要封装的是下面的类呢 我们该怎么办 大家先思考下 class C
  • Excel中的VLOOKUP函数

    这几天开始刷计算机二级Office的题库 怎么说呢 遇到了很多之前根本就不知道的函数 并且感觉很有用 所以想把一些考试频繁要考的 同时也是很实用的函数一点一点的记下来 今天我来谈一下在Excel里面的一个查找函数 VLOOKUP函数 这个函
  • 小小程序员预备上路

    2011正式接触代码 进入CSDN乐知学院PHP方向 这篇博客便是我所有的成长的见证 至今 大大小小的项目做过不少 项目中学会了很多 怎么与小组默契配合 提高效率 大一第一次的项目 纯HTML静态网页 班级40个人5人一小组 总共8组 稀里
  • 手机投屏不是全屏怎么办_手机投屏怎么满屏

    手机投屏是很多小伙伴们都喜欢玩的 不少小伙伴们小伙伴们在使用手机投屏的时候发现不能满屏 想要知道方法的小伙伴们 就让小编给大家详细的讲讲满屏方法吧 手机投屏怎么满屏 1 手机具有投屏的功能 目前大多数手机都已经具备发无线投屏的功能 2 电视
  • Linux 部署 Mycat 实现 MariaDB 分库分表

    安装请参照Mycat 实现 Mysql 集群读写分离 高飞的博客 CSDN博客MySQL 读写分离的概述https blog csdn net gaofei0428 article details 117503469 spm 1001 20
  • 【Stable Diffusion】安装过程中常见报错解决方法

    转自 https openai wiki stable diffusion error html 如何查看报错 在你安装时可能经常遇到各种各样的问题 但是对于一堆陌生的英文和各种各样的错误 大家可能经常无从下手 下面我将会教大家如何查看报错
  • SQL Server研习录(29)——sql server 设置列自增长

    SQL Server研习录 29 sql server 设置列自增长 版权声明 一 设置列自增长 1 创建表时 2 创建表后 版权声明 本文原创作者 清风不渡 博客地址 https blog csdn net WXKKang 一 设置列自增
  • kali Linux2021安装VMwareTools更新源(详解)

    VMwareTools安装 1 点击虚拟机设置 点击安装VMwareTools 2 打开kali进入界面 双击界面中的VMwareTools 3 进入界面中VMwareTools所在文件中复制压缩包到 目录中的tmp里 4 在tmp中打开终
  • 基于 Android 13 的 Activity 启动流程分析

    对于 Android 客户端开发者来说 Activity 是我们再熟悉不过的一个组件了 它是 Android 四大组件之一 是一个用于直接与用户交互的展示型 UI 组件 在开发过程中 启动并创建一个 Activity 流程非常简单 而在系统
  • 平面二维任意椭圆数据拟合算法推导及程序实现详解

    在刚刚过去的2017全国大学生数学建模比赛中 笔者有幸指导了一组本科学生参赛 对于赛题A CT系统参数标定及成像 中的CT系统参数标定 经过将问题进一步的提炼 问题最终变成了在平面二维空间中对任意椭圆进行拟合的问题 笔者花了大概四个小时的时