上一篇文章介绍了关于OPENCV椭圆拟合的方法 (Python opencv 椭圆拟合)。
在实际工程中,有些场景是需要精确的正圆测量和拟合,使用通用椭圆拟合方式容易引入较大的误差。这一篇文章将介绍关于正圆拟合的方法以及与椭圆拟合算法的对比。

实验数据

我们用sklearn里面的数据集来生成待拟合圆的数据。

    from sklearn.datasets import make_circlesimport numpy as npdef get_unit_circle(shuffle=False, noise=0.02, factor=0.05):data = make_circles(shuffle=shuffle, noise=noise, factor=factor)idx = np.argwhere(data[1] == 0)x = data[0][idx, 0]y = data[0][idx, 1]return x, y

make_circles会生成内圆和外圆两组数据,对应的标签y分别1,0.
圆心为(0,0)半径为1.
可视化生成的数据

import matplotlib.pyplot as pltx, y = get_unit_circle()
plt.scatter(x, y)
plt.axis('equal')
plt.show()

圆拟合

在这一步,我们会用SciPy中的optimize.leastsq去实现圆拟合,也就是调用的最小二乘法。

  • Cost Function

    from scipy import optimize
    from math import pidef r(x, y, xc, yc):'''计算每一个点到圆心的距离'''return np.sqrt((x-xc)**2 + (y-yc)**2)def f(c, x, y):'''Cost Function '''Ri = r(x, y, *c)return np.square(Ri - Ri.mean())
    
  • 最小二乘法拟合圆
    def least_squares_circle(coords):"""Circle fit using least-squares solver.Inputs:- coords, list or numpy array with len>2 of the form:[[x_coord, y_coord],...,[x_coord, y_coord]]or numpy array of shape (n, 2)Outputs:- xc : x-coordinate of solution center (float)- yc : y-coordinate of solution center (float)- R : Radius of solution (float)- residu : MSE of solution against training data (float)"""x, y = None, Noneif isinstance(coords, np.ndarray):x = coords[:, 0]y = coords[:, 1]elif isinstance(coords, list):x = np.array([point[0] for point in coords])y = np.array([point[1] for point in coords])else:raise Exception("Parameter 'coords' is an unsupported type: " + str(type(coords)))# coordinates of the barycenterx_m = np.mean(x)y_m = np.mean(y)center_estimate = x_m, y_mcenter, _ = optimize.leastsq(f, center_estimate, args=(x, y))xc, yc = centerRi       = r(x, y, *center)R        = Ri.mean()residu   = np.sum((Ri - R)**2)return xc, yc, R, residu
    
  • 绘图
    def plot_data_circle(x, y, xc, yc, R):"""Plot data and a fitted circle.Inputs:x : data, x values (array)y : data, y values (array)xc : fit circle center (x-value) (float)yc : fit circle center (y-value) (float)R : fir circle radius (float)Output:None (generates matplotlib plot)."""f = plt.figure(facecolor='white')plt.axis('equal')theta_fit = np.linspace(-pi, pi, 180)x_fit = xc + R*np.cos(theta_fit)y_fit = yc + R*np.sin(theta_fit)plt.plot(x_fit, y_fit, 'b-' , label="fitted circle", lw=2)plt.plot([xc], [yc], 'bD', mec='y', mew=1)plt.xlabel('x')plt.ylabel('y')# plot dataplt.scatter(x, y, c='red', label='data')plt.legend(loc='best', labelspacing=0.1 )plt.grid()plt.title('Fit Circle')
    
  • 圆拟合实验
    coords = np.array([[x[i][0], y[i][0]] for i in range(len(x))])
    xc, yc, r, residual = least_squares_circle(coords)
    print("least_squares: \n""xc: {xc}\n""yc: {yc}\n""r: {r}\n""residual: {residual}\n".format(xc=xc, yc=yc, r=r, residual=residual))
    plot_data_circle(coords[:, 0], coords[:, 1], xc, yc, r)
    plt.show()
    
    least_squares:
    xc: -0.001448768226716725
    yc: 0.001868231073519271
    r: 1.0026485302748585
    s: 0.01798191226855169
    

对比实验

  • 整圆数据拟合测试
    input

    [[-0.20222279  0.97036383][-0.70938247  0.6772127 ][ 0.99928194 -0.13865634][ 0.43164868  0.92726211][-0.98573612 -0.26547395][-0.0846844   1.03034261][ 0.81541324 -0.62520304][ 0.63680427  0.81349025][ 0.5243403   0.82797391][-1.03298498 -0.13068717][ 0.05791061 -1.00685492][ 0.53883561 -0.85298628][-0.5236286  -0.84472701][-0.79429015  0.60075032][-0.51160761  0.83311102][-0.80068973 -0.57344023][-0.71966203 -0.67572335][ 0.78423462  0.57306241][-0.90375463 -0.3620828 ][ 1.01525985  0.25229142]]
    

    output
    有整圆的数据情况下,椭圆拟合算法和圆拟合算法得到的结果基本相同,精度都还不错。

    least_squares:
    xc: 0.004072613875040401
    yc: -0.0018972548200443362
    r: 1.0049178131436773
    residual: 0.010274593350489435fitEllipse:
    xc: 0.010946060180664062
    yc: -0.00024581146240234376
    a: 1.998855224609375
    b: 2.0251834716796875
    

  • 半圆数据拟合测试
    input

    [[ 1.00515793 -0.00581373][ 0.97331632  0.14824388][ 0.98822774  0.23520662][ 0.95820935  0.36923693][ 0.90629294  0.47303492][ 0.81419798  0.56982752][ 0.73716614  0.71245408][ 0.61164932  0.76321955][ 0.5263777   0.86008591][ 0.37880738  0.90808892][ 0.32055051  0.93700053][ 0.20453417  0.99333937][ 0.05113706  1.00244991][-0.04754568  1.01810976][-0.17381077  0.98401702][-0.33780284  0.93704433][-0.4102824   0.92013996][-0.55344694  0.88235196][-0.6336433   0.78243172][-0.70035358  0.68997356]]
    

    output
    对于只有部分圆的数据点,圆拟合的算法比较稳定,估计圆的半径和中心都还算精确。
    椭圆拟合则会有比较大的误差,中心位置估计还算准确,但是半径的误差显著增加。

    least_squares:
    xc: -0.005765623679872315
    yc: -0.006110242659838036
    r: 1.011230956382947
    residual: 0.005535104556472458fitEllipse:
    xc: 0.0839453125
    yc: 0.19866604614257813
    a: 1.5608851318359376
    b: 1.8778536376953125
    

Reference

[1] https://scipy-cookbook.readthedocs.io/index.html
[2] https://se.mathworks.com/help/curvefit/least-squares-fitting.html

Python 圆拟合相关推荐

  1. python最小二乘法拟合圆_最小二乘法拟合圆

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

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

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

  3. python函数拟合不规则曲线_python曲线拟合

    Python曲线拟合 前言 这篇文章的由来:前几天在做大学物理居家实验水滴法测量声速的时候需要使用phyphox软件导出的数据拟合y=1/(a+b*x)曲线.虽然老师要求使用Origin软件拟合,但是 ...

  4. python数据拟合

    python数据拟合 文章目录 python数据拟合 1.多项式拟合 1.1 多项式拟合描述 1.2 多项式拟合实现 2.自定义函数拟合 2.1 自定义函数拟合描述 2.1 自定义函数拟合的实现 1. ...

  5. Python数据拟合幂函数y=ax^b

    Python数据拟合--幂函数y=ax^b from scipy.optimize import curve_fit import numpy as np import matplotlib.pypl ...

  6. python多项式拟合:np.polyfit 和 np.polyld

    python数据拟合主要可采用numpy库,库的安装可直接用pip install numpy等. 这段代码可以直接用,但是要用自己的值 #多项式拟合 y = data_jiedian_2 #输入自己 ...

  7. Python 高斯拟合

    Python 高斯拟合 通常我们进行高斯拟合的办法是导入scipy的curve_fit 包,不过这需要自己手写一个高斯分布的函数表达式,不是很方便,astropy提供了一个写好的高斯拟合包 1. 调包 ...

  8. 圆拟合算法(距离之和最小)

    上一篇博客介绍了最小二乘法拟合圆的方法.这种方法对误差符合正态分布的数据点很有效.但是在机器视觉应用中经常会碰到一些干扰点.这些干扰点多数时候是偏向某一个方向的.这时要是用最小二乘法拟合,拟合出的圆会 ...

  9. python 直线拟合_python matplotlib拟合直线的实现

    这篇文章主要介绍了python matplotlib拟合直线的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下 import numpy ...

  10. python来拟合Langmuir非线性方程

    python来拟合Langmuir非线性方程`` 简介 以前都是用origin来进行拟合,但是参数初值需要猜测,有时候不一定能够得到正确结果.后来用过MATLAB的工具箱,可以拟合,但电脑要安装MAT ...

最新文章

  1. 每天拖地好麻烦?用这几招,地板每天光亮如新!
  2. Git 撤销中间某次的提交记录
  3. Android JNI入门第一篇——HelloJni
  4. JVM之盘点家底查看初始默认值和更改值
  5. 低功耗STM32F411开发板(原理图+PCB源文件+官方例程+驱动等)
  6. 我要3万取款机怎么取_7万的新宝骏RS-3怎么样?用车三个月后,车主说出了实话...
  7. php转译html,使用php转义输出HTML到JavaScript
  8. tf.nn.dropout
  9. 减少C++代码编译时间的方法
  10. pre textarea code标签区别
  11. ubuntu下lvs负载均衡dr模型shell脚本
  12. map mybatis 的字段返回0_mybatis返回map类型数据空值字段不显示(三种解决方法)
  13. 柱状图之最大矩形面积
  14. freemarker生成java代码,freeMarker之根据模板生成JAVA代码示例
  15. OC中常见的Signal错误
  16. 拜耳2020年10个新植保制剂商业化,3个生物技术性状项目推进至上市阶段
  17. ActiveX图片控件,图片处理基于Internet的程序
  18. 家庭监控,网络摄像头(OpenWRT平台下Mjpg-Streamer+Ngrok实现方案)
  19. 外卖和快递行业数据_白领市场三分天下,外卖行业将何去何从?
  20. 科大迅飞语音听写(流式版)WebAPI,Web前端、H5调用 语音识别,语音搜索,语音听写

热门文章

  1. 小米校招产品作业解读:设计一款日记APP
  2. 数字化闯入“深水区”,超级营销平台是突破口吗?
  3. Android消息机制和应用
  4. html加载图片路径问题
  5. Vue整合Markdown组件+SpringBoot文件上传+代码差异对比
  6. 如何结交阿里P9,腾讯T4这样的大佬?
  7. 微图影像地图导出拼接大图的参数说明
  8. BT种子/磁力/eD2K,P2P和各种下载协议
  9. 模模搭古城搭建学习笔记3:建筑篇
  10. 新浪短网址API接口(3月15日更新)