直线拟合属于比较经典的优化问题了。这里探讨下使用最小二乘拟合和RANSAC两种方法进行拟合。
最小二乘拟合
直线的一般式方程:
$$ ax + by + c = 0 $$
最小二乘拟合时暂不考虑b=0的情况,考虑其斜率方程
$$y = kx + b$$
设观测样本数为N,观测误差
$$ e= \sum_{n=1}^N{(kx_i-y_i)^2} $$
为使e达到最小,分别对k,b求偏导使其等于0
$$ \frac{\partial e}{\partial k}={k\sum_{i=1}^{N}{x_i^2}}+{b\sum_{i=1}^{N}{x_i}} -{\sum_{i=1}^{N}{x_iy_i}}=0 $$
$$\frac{\partial e}{\partial b}=k\sum_{i=1}^{N}{x_i}+Nb-\sum_{i=1}^{N}{y_i}=0$$
求得
$$k=\frac{\sum_{i=1}^{N}{x_i}\sum_{i=1}^{N}{y_i}-N\sum_{i=1}^{N}{x_iy_i}}{(\sum_{i=1}^{N}{x_i})^2-N\sum_{i=1}^{N}{x_i^2})}$$
$$b=\frac{\sum_{i=1}^{N}{x_i}\sum_{i=1}^{N}{x_iy_i}-\sum_{i=1}^{N}{y_i}\sum_{i=1}^{N}{x_i^2}}{(\sum_{i=1}^{N}{x_i})^2-N\sum_{i=1}^{N}{x_i^2})}$$
RANSAC
RANSAC算法的输入是一组观测数据(往往含有较大的噪声或无效点),一个用于解释观测数据的参数化模型以及一些可信的参数。RANSAC通过反复选择数据中的一组随机子集来达成目标。被选取的子集被假设为局内点,并用下述方法进行验证:
- 有一个模型适应于假设的局内点,即所有的未知参数都能从假设的局内点计算得出。
- 用1中得到的模型去测试所有的其它数据,如果某个点适用于估计的模型,认为它也是局内点。
- 如果有足够多的点被归类为假设的局内点,那么估计的模型就足够合理。
- 然后,用所有假设的局内点去重新估计模型(譬如使用最小二乘法),因为它仅仅被初始的假设局内点估计过。
- 最后,通过估计局内点与模型的错误率来评估模型。
上述过程被重复执行固定的次数,每次产生的模型要么因为局内点太少而被舍弃,要么因为比现有的模型更好而被选用。
步骤:
- 任意选择两个点组成直线,计算所有点到该直线的距离,如果小于某个阈值,那么归为内点
- 内点个数大于一定数目,采用该模型;否则继续步骤1,直到达到迭代次数。
这里没有进行评估模型的步骤,直接根据内点的个数来选择模型。
相关公式: - 点$({x_0},{y_0})$到直线$Ax+By+C=0$的距离
$$ d= \left|\frac{Ax_0+By_0+C}{\sqrt{A^2+B^2}}\right|$$
- 已知两点$({x_1},{y_1})$,$({x_2},{y_2})$,可以得到直线的一般式方程$Ax+By+C=0$,其中
$$ A=y_2-y_1 $$
$$ B=x_1-x_2 $$
$$ C=x_2y_1-x_1y_2 $$
测试代码
|
|