ax+by+c=0 型直线拟合算法

所谓直线拟合,通常也叫做线性拟合、一元线性回归。指的是当我们有一批数据(xi,yi),这些数据在平面坐标系下落在一条直线上,或近似的落在一条直线上。我们就要求出这条直线的参数。如果这条直线可以写为:

y=kx+b

那么

k=∑(xi?xˉ)(yi?yˉ)∑(xi?xˉ)2

b=yˉ?kxˉ

这个关系式许多教科书上都有详细的推导,无需多说。

今天要说的是另一种情况,当我们的数据有可能落在一条竖直的直线上,也就是k 有可能为∞ 时,应该如何做拟合。这时我们肯定就不能用y=kx+b 了,但是可以将这个表达式变变形。我们知道

k=tanθ=sinθcosθ

那么原来的直线方程可以写为:

ycosθ=xsinθ+bcosθ

或者写为更一般的形式:

ax+by+c=0

同时满足附加条件:

a2+b2=1

下面就来说说这种形式的直线方程如何拟合。

点到直线的垂直距离

首先先要解决一个小问题,一个点 (xi,yi) 到这条直线的距离是多少。

直接计算有点麻烦,我们先考虑一种简单的形式,点 (0,0) 到这条直线的距离。

直线方程:

xsin(θ)?ycos(θ)+c=0

那么与它垂直的过原点的直线方程为:

xsin(θ+π/2)?ycos(θ+π/2)=0

化简后得到:

xcos(θ)+ysin(θ)=0

这两个直线的交点为两条直线方程组成的方程组的解:

{xsin(θ)?ycos(θ)+c=0xcos(θ)+ysin(θ)=0

简单计算后可以得到:

{x=?sin(θ)cy=cos(θ)c

容易看出交点到原点的距离为 c,而这就是原点到直线的距离。

下面就可以求点 (xi,yi) 到这条直线的距离了。只需要做个坐标变换。新坐标系下的坐标变量为 x′ 和 y′。 新旧坐标系的关系如下。

{x′=x?xiy′=y?yi

那么原始坐标系下的点(xi,yi) 在这个新的坐标系下称为了坐标原点(0,0)。

原始坐标系下的直线方程 ax+by+c=0 成为了:

a(x′+xi)+b(y′+yi)+c=0

整理一下成为:

ax′+by′+(axi+byi+c)=0

在这个坐标系下直线到原点的距离为: (axi+byi+c),这也就是我们要求的直线到点的垂直距离。

直线拟合

我们要求的直线方程的系数 a、b 和 c 就是在

a2+b2=1

的条件下,使得下面求和式:

f=∑(axi+byi+c)2

取得极小值的 a、b 和 c。

这个问题有标准的处理方法:拉格朗日乘子法。

f=∑(axi+byi+c)2?λ(a2+b2?1)

????????????????f?a=0?f?b=0?f?c=0?f?λ=0

这里先不急着把这几个式子都展开了。只来看看 ?f?c 这一项。

?f?c=2×∑(axi+byi+c)=0

变形之后可以得到:

axˉ+byˉ+c=0xˉ=∑xi/Nyˉ=∑yi/N

用这个式子, c 就确定了。可以将确定后的 c 带入 f 的表达式。

f=∑(a(xi?xˉ)+b(yi?yˉ))2?λ(x2+y2?1)

?f?a=2∑(a(xi?xˉ)+b(yi?yˉ))(xi?xˉ)?2aλ=2(aDxx+bDxy)?2aλ=0

?f?b=2∑(a(xi?xˉ)+b(yi?yˉ))(yi?xˉ)?2bλ=2(aDxy+bDyy)?2bλ=0

其中:

?????Dxx=∑(xi?xˉ)2Dxy=∑(xi?xˉ)(yi?yˉ)Dyy=∑(yi?yˉ)2

所以,我们的 a、b 和 λ 应该满足如下线性方程组。

{aDxx+bDxy=aλaDxy+bDyy=bλ

或者写成矩阵形式:

(DxxDxyDxyDyy)(ab)=λ(ab)

这样写就很清楚了。λ 是 (DxxDxyDxyDyy) 的特征值, a,b 是 (DxxDxyDxyDyy)

的特征向量。

但是这个矩阵有两个特征值,我们应该选用哪个特征值呢。

∑(a(xi?xˉ)+b(yi?yˉ))2=(ab)(DxxDxyDxyDyy)(ab)=λ(a2+b2)=λ

所以,我们应该选取两个特征值中较小的那个。

(Dxx?λDxyDxyDyy?λ)(ab)=0

有非零解的条件是:

∣∣∣Dxx?λDxyDxyDyy?λ∣∣∣=0

λ=(Dxx+Dyy)±(Dxx?Dyy)2+4D2xy?????????????????√2

较小的那个特征根是: λ=(Dxx+Dyy)?(Dxx?Dyy)2+4D2xy√2

(ab)=1D2xy+(λ?Dxx)2???????????????√(Dxyλ?Dxx)

至此,这个直线拟合问题的解决了。但是,关于这个直线拟合与传统的一元线性回归算法的区别我还想说几句。

传统的一元线性回归是认为数据点 (xi,yi) 中只有 yi 是有误差的,因此确定点到直线距离时用的是 y 方向的距离。 我本文中的算法认为数据点 (xi,yi) 都是有误差的,并且不确定度是相同的,因此,数据点到直线的距离用的是垂直距离。这两个异同可以参考下面的图片。当这条直线的斜率很小时,这两种方法求得直线方程很接近,当直线斜率很大时,两个结果可能有很大的区别。具体应该用哪种还是要根据数据点的性质来确定。

后记

写到这里关于直线拟合算法的实现方法就算是说清楚了。但其实还有一个重要的问题没有交代。我们做一元线性回归时会去求相关系数。相关系数反映的是数据点与拟合直线的吻合程度,对于我们的算法,也应该提出一个类似的指标。另外,求出的系数 a、b、c 也应给出不确定度或者置信区间。

关于这些问题,我准备再开一篇博客来详细的说说。(其实是因为有些问题还没想好如何解决(^.^))

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 12:07:09

ax+by+c=0 型直线拟合算法的相关文章

直线拟合算法

在计算机视觉的应用中,经常会用到提取一条直线的精确位置这样的工作.这时就要用到直线的拟合算法了. 这里,我也贴一个利用最小二乘法计算最佳拟合直线的代码. 这个代码是我以前学习<机器视觉算法与应用(双语版)>[德] 斯蒂格(Steger C) 著:杨少荣 等 译 的书时写的.所有的公式推导都在书中 3.8.1 ,还算比较有用. 与一元线性回归算法的区别:一元线性回归算法假定 X 是无误差的,只有 Y 有误差. 而这个算法假设每个点的 X Y 坐标的误差都是符合 0 均值的正态分布的. 因此,在计

直线拟合算法(续)

直线拟合算法(续) 曾经写过一篇博客.介绍直线拟合算法. http://blog.csdn.net/liyuanbhu/article/details/50866802 给出的代码事实上有一点小问题,就是 den = 0 时会出现除以 0 的错误. 今天正好也有网友问起这个问题. 我就再写一篇短文来说说怎样解决问题. 首先我们知道: den=D2xy+(λ?Dxx)2??????????????√ 那么 den=0 意味着: Dxy=0λ=Dxx 我们还有关于 λ 的计算式: λ=Dxx+Dyy

OpenCV 学习(直线拟合)

OpenCV 学习(直线拟合) Hough 变换可以提取图像中的直线.但是提取的直线的精度不高.而很多场合下,我们需要精确的估计直线的参数,这时就需要进行直线拟合. 直线拟合的方法很多,比如一元线性回归就是一种最简单的直线拟合方法.但是这种方法不适合用于提取图像中的直线.因为这种算法假设每个数据点的X 坐标是准确的,Y 坐标是带有高斯噪声的.可实际上,图像中的每个数据点的XY 坐标都是带有噪声的. 下面就来讲讲适用于提取图像中直线的直线拟合算法. 一个点 (xi,yi) 到直线的距离用 ri 来

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

作者:桂. 时间:2017-03-22  06:13:50 链接:http://www.cnblogs.com/xingshansi/p/6597796.html 声明:欢迎被转载,不过记得注明出处哦~ 前言 分布拟合与曲线拟合系列本想简单梳理,却啰嗦的没完没了.本文主要介绍:多直线的拟合,多曲线可以依次类推.全文主要包括: 1)背景介绍 2)理论推导 3)代码实现 4)关于拟合的思考 内容多有借鉴他人,最后一并附上链接. 一.背景介绍 对于单个直线,可以借助MLE或者最小二乘进行求参,对于多条

OpenCV fitline直线拟合函数学习

下图是OpenCV官方文档中,对直线拟合函数的详细介绍: fitLine()函数用于,对二维或三维空间中的点集进行直线拟合.共有六个参数: param 1:输入的点集,可以是Mat或者vector<>,可以是二维点集或三维点集. 例如: vector<Point> points; param 2:拟合结果,即一条直线.在二维空间中,直线可以定义为 Vec4f line; 在二维平面中,(line[0],line[1])表示直线的方向向量,(line[2],line[3])表示直线上

opengl实现直线扫描算法和区域填充算法

总体介绍 1.   使用线性扫描算法画一条线,线性离散点 2.   利用区域填充算法画多边形区域,区域离散的点 开发环境VS2012+OpenGL 开发平台 Intel core i5,Intel HD Graphics Family 设计思路 一.直线扫描算法 1.数值微分法(DDA) 已知过端点P0 (x0, y0), P1(x1, y1)的直线段L:y = kx + b,easy得知直线斜率为:k = (y1-y0)/(x1-x0).(如果x1≠x0). 我们如果|k|≤1,这样x每添加1

最小二乘法直线拟合

最小二乘法的直线拟合 #coding:utf-8 import numpy as np import matplotlib.pyplot as plt dots = np.array([[1,6], [2,5], [3,7], [4,10]]) plt.plot([i[0] for i in dots],      [i[1] for i in dots], 'ro') plt.axis([0, 6, 0, 12]) def nihezhixian(k, x, b):     return k*

清华版CG 实验2 直线生成算法实现

1.实验目的: 理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法. 2.实验内容: (1) 根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果: (2) 指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告: (3) 根据示范代码,将其改造为圆的光栅化算法,写入实验报告: (4) 了解和使用OpenGL的生成直线的命令,来验证程序运行结果. 3.实验原理: 示范代码原理参见教材直线

[计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(一)

一.首先说明: 这是啥? —— 这是利用C#FORM写的一个用来演示计算机图形学中 ①Bresenham直线扫描算法(即:连点成线):②种子填充法(即:填充多边形):③扫描线填充法 有啥用? ——  无论是连点成线还是区域填充在高级编程中基本上都提供很高效的库函数来调用.这里拿出这些算法一方面有利于大家理解那些封装的函数底层是实现:另一方面是方便嵌入式TFT屏幕底层驱动开发时借鉴的. 是啥样? ——  如下面的操作,不言而喻. 二.进入正题: 2-1.直线的扫描转换 图形的扫描转换实质就是在光栅