有一系列的数据点 {xi,yi}。我们知道这些数据点近似的落在一个圆上。依据这些数据预计这个圆的參数就是一个非常有意义的问题。今天就来讲讲怎样来做圆的拟合。圆拟合的方法有非常多种,最小二乘法属于比較简单的一种。

今天就先将这样的。

我们知道圆方程能够写为:

(x?xc)2+(y?yc)2=R2

通常的最小二乘拟合要求距离的平方和最小。也就是

f=∑((xi?xc)2+(yi?yc)2??????????????????√?R)2

最小。

这个算起来会非常麻烦。

也得不到解析解。

所以我们退而求其次。

f=∑((xi?xc)2+(yi?yc)2?R2)2

这个式子要简单的多。我们定义一个辅助函数:

g(x,y)=(x?xc)2+(y?yc)2?R2

那么上面的式子能够表示为:

f=∑g(xi,yi)2

依照最小二乘法的通常的步骤,可知f 取极值时相应以下的条件。

?f?xc=0?f?yc=0?f?R=0

先来化简 ?f?R=0

?f?R=?2R×∑((xi?xc)2+(yi?yc)2?R2)=?2R×∑g(xi,yi)=0

我们知道半径 R 是不能为 0 的。所以必定有:

∑g(xi,yi)=0

这是个非常实用的结论。剩下的两个式子:

?f?xc=?4∑((xi?xc)2+(yi?yc)2?R2)(xi?xc)=?4∑g(xi,yi)(xi?xc)=?4∑xig(xi,yi)=0?f?yc=?4∑((xi?xc)2+(yi?yc)2?R2)(yi?yc)=?4∑g(xi,yi)(yi?yc)=?4∑yig(xi,yi)=0

也就是以下两个等式:

∑xig(xi,yi)=0∑yig(xi,yi)=0

这里设:

ui=xi?xˉuc=xc?xˉvi=yi?yˉvc=yc?yˉ

当中:

xˉ=∑xi/Nyˉ=∑yi/N

那么简单的推导一下,就会发现:

∑uig(ui,vi)=0∑vig(ui,vi)=0

事实上都不须要推导,这个变量替换仅仅只是是改动了坐标原点的位置。而我们的等式根本就与坐标原点的详细位置无关。

所以必定成立。

这两个式子展开写是这样的:

∑((ui?uc)2+(vi?vc)2?R2)ui=0∑((ui?uc)2+(vi?vc)2?R2)vi=0

进一步展开:

∑(u3i?2u2iuc+uiu2c+uiv2i?2uivivc+uiv2c?uiR2)=0∑(u2ivi?2uiviuc+viu2c+v3i?2v2ivc+viv2c?viR2)=0

我们知道 ∑ui=0, ∑vi=0。所以上面两个式子是能够化简的。

∑(u3i?2u2iuc+uiv2i?2uivivc)=0∑(u2ivi?2uiviuc+v3i?2v2ivc)=0

为了简化式子,我们定义几个參数:

Suuu=∑u3iSvvv=∑v3iSuu=∑u2iSvv=∑v2iSuv=∑uiviSuuv=∑u2iviSuvv=∑uiv2i

那么上面的式子能够写为:

Suuuc+Suvvc=Suuu+Suvv2Suvuc+Svvvc=Suuv+Svvv2

至此,就能够解出uc 和vc 了。

uc=SuuvSuv?SuuuSvv?SuvvSvv+SuvSvvv2(S2uv?SuuSvv)vc=?SuuSuuv+SuuuSuv+SuvSuvv?SuuSvvv2(S2uv?SuuSvv)

那么:

xc=uc+xˉyc=vc+yˉ

还剩下个 R 没求出来。 也非常easy。

∑g(xi,yi)=0∑((xi?xc)2+(yi?yc)2?R2)=0

所以:

R2=∑((xi?xc)2+(yi?yc)2)

好了。

以下给出个代码,这个代码的详细公式和我这里给出的有一点小差异。可是原理是同样的。

/**

* 最小二乘法拟合圆

* 拟合出的圆以圆心坐标和半径的形式表示

* 此代码改编自 newsmth.net 的 jingxing 在 Graphics 版贴出的代码。

* 版权归 jingxing, 我仅仅是搬运工外加一些简单的改动工作。

*/

typedef complex POINT;

bool circleLeastFit(const std::vector &points, double &center_x, double &center_y, double &radius)

{

center_x = 0.0f;

center_y = 0.0f;

radius = 0.0f;

if (points.size() < 3)

{

return false;

}

double sum_x = 0.0f, sum_y = 0.0f;

double sum_x2 = 0.0f, sum_y2 = 0.0f;

double sum_x3 = 0.0f, sum_y3 = 0.0f;

double sum_xy = 0.0f, sum_x1y2 = 0.0f, sum_x2y1 = 0.0f;

int N = points.size();

for (int i = 0; i < N; i++)

{

double x = points[i].real();

double y = points[i].imag();

double x2 = x * x;

double y2 = y * y;

sum_x += x;

sum_y += y;

sum_x2 += x2;

sum_y2 += y2;

sum_x3 += x2 * x;

sum_y3 += y2 * y;

sum_xy += x * y;

sum_x1y2 += x * y2;

sum_x2y1 += x2 * y;

}

double C, D, E, G, H;

double a, b, c;

C = N * sum_x2 - sum_x * sum_x;

D = N * sum_xy - sum_x * sum_y;

E = N * sum_x3 + N * sum_x1y2 - (sum_x2 + sum_y2) * sum_x;

G = N * sum_y2 - sum_y * sum_y;

H = N * sum_x2y1 + N * sum_y3 - (sum_x2 + sum_y2) * sum_y;

a = (H * D - E * G) / (C * G - D * D);

b = (H * C - E * D) / (D * D - G * C);

c = -(a * sum_x + b * sum_y + sum_x2 + sum_y2) / N;

center_x = a / (-2);

center_y = b / (-2);

radius = sqrt(a * a + b * b - 4 * c) / 2;

return true;

}

下图是个实际測试的结果。对这样的均匀分布的噪声数据计算的结果还是非常准确的。

可是当数据中有部分偏向某一个方向的干扰数据时。结果就不那么乐观了。下图就非常说明问题。

数据点中有 20% 是干扰数据。

拟合出的圆就明显被拽偏了。

之所以出现这个问题就是由于最小二乘拟合的平方项对离群点非常敏感。解决问题就要用其它的拟合算法,比方用距离之和作为拟合判据。等我有空了再写一篇博客介绍其它几种方法。

python最小二乘法拟合圆_最小二乘法拟合圆相关推荐

  1. 多项式拟合缺点_多项式拟合

    在网上看别人的心得 一 最小二乘法的基本原理 从整体上考虑近似函数同所给数据点(i=0,1,-,m)误差(i=0,1,-,m)的大小,常用的方法有以下三种:一是误差(i=0,1,-,m)绝对值的最 ...

  2. 什么是欠拟合现象_过拟合与欠拟合问题

    过拟合(overfitting)与欠拟合(underfitting)是统计学中的一组现象.过拟合是在统计模型中,由于使用的参数过多而导致模型对观测数据(训练数据)过度拟合,以至于用该模型来预测其他测试 ...

  3. python 拟合圆_最小二乘法拟合圆 转

    有一系列的数据点 {xi,yi}{xi,yi},我们知道这些数据点近似的落在一个圆上,根据这些数据估计这个圆的参数就是一个很有意义的问题.今天就来讲讲如何来做圆的拟合.圆拟合的方法有很多种,最小二乘法 ...

  4. python最小二乘法拟合圆_最小二乘法拟合圆(示例代码)

    有一系列的数据点 {xi,yi}.我们知道这些数据点近似的落在一个圆上.依据这些数据预计这个圆的參数就是一个非常有意义的问题.今天就来讲讲怎样来做圆的拟合.圆拟合的方法有非常多种,最小二乘法属于比較简 ...

  5. python实现最小二乘法的线性回归_最小二乘法求线性回归的python实现

    原文: 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_38003892/arti ...

  6. python怎么重复画圆_重画圆Python

    我这里有一段代码:from tkinter import * class player(): def __init__(self, radius, xcoordinate = 0, ycoordina ...

  7. python圆面积怎么算_如何编写圆和squ面积计算程序

    代码有很多问题.下面是一个我认为你想要完成的工作示例:#!/usr/bin/python pi = 3.14159265 choice = input('Enter Choice [1 or 2]:' ...

  8. 误差函数拟合优缺点_欠拟合、过拟合及如何防止过拟合

    对于深度学习或机器学习模型而言,我们不仅要求它对训练数据集有很好的拟合(训练误差),同时也希望它可以对未知数据集(测试集)有很好的拟合结果(泛化能力),所产生的测试误差被称为泛化误差.度量泛化能力的好 ...

  9. 什么是欠拟合现象_欠拟合和过拟合是什么?解决方法总结

    欠拟合与过拟合 欠拟合是指模型在训练集.验证集和测试集上均表现不佳的情况: 过拟合是指模型在训练集上表现很好,到了验证和测试阶段就大不如意了,即模型的泛化能力很差. 欠拟合和过拟合一直是机器学习训练中 ...

最新文章

  1. 跟小静读CLR via C#(05)- 访问限定、数据成员
  2. ICCV 2017 EAST:《Learning Policies for Adaptive Tracking with Deep Feature Cascades》论文笔记
  3. Enlarge GCD CodeForces - 1034A(欧拉筛+最大公约数)
  4. linux的i o模型,浅谈Linux 网络 I/O 模型简介(图文)
  5. 大学四年,因为这8个网站,我成为同学眼中的学霸。
  6. linux 查看硬盘的uuid_ubuntu16.04 挂载新硬盘
  7. 《Java Web项目开发实战案例》最新源码
  8. Ubuntu20.04 安装CUDA驱动和一些系统配置
  9. 【个人博客网页模板】
  10. C#开根号函数:math.pow()函数
  11. Unity Bounds 边界框(包围盒)
  12. 项目管理知识体系指南(十)项目风险管理
  13. ddl(ddl是什么意思网络语)
  14. 齐次式的相关知识【初级中阶辅导】
  15. 各个排序算法的时间复杂度和稳定性,快排的原理
  16. Android Google原生语音识别
  17. 计算机网络基础之传输介质
  18. 云呐|如何对酒店固定资产进行日常管理
  19. 上网本不会是一场流星雨
  20. 理财笔记 - 老猫有感

热门文章

  1. 计算机应用领域的实践,计算机技术在通信技术领域的应用实践探微
  2. 计算机毕业设计Java高考报考指南网站(源码+系统+mysql数据库+lw文档)
  3. 斐波拉契数列——算法
  4. PETS 5 考试经验
  5. 2018最新版省市区三级联动下拉框+所有源代码以及数据库
  6. 小型数控雕刻机制作Arduino_Arduino 3D打印机,兼具CNC雕刻机功能 (一)机械设计、组装...
  7. SRMUVS-100VAC-2H2D电压继电器
  8. 达州中学高考2021成绩查询,达州中学排名前十名,2021年达州中学排名一览表
  9. 用sets和data解决钢管切割问题(根数最少)
  10. python decorator wrapper_python装饰器(decorator)