计算机视觉学习笔记#3 拟合:最小二乘法、RANSAC、Hough霍夫变换(附代码)
本文最后更新于:2022年7月21日 下午
计算机视觉学习笔记#3 拟合
之前提到的边缘检测虽然能得到线,但是无法得到线的位置,而在下图这种例子中,假如要检测硬币的位置,那需要知道画面中圆边缘和圆心的位置。拟合能够用数学来描述出结果,而不是像素。
拟合的难点
要找到车的拟合边缘有以下难点
- 那图中可能存在许多不属于这个车的边缘(噪声)
- 车可能被遮挡。
- 车包含多个线条,在提取一条线的时候,其他线都是噪声。
最小二乘法:所有点都是有效点的情况
注意最小二乘法的距离是数轴上的距离。如图先定义一个能量函数(类似机器学习的loss),然后把用矩阵表示方程,则,然后我们希望能量函数最小,就求导等于0时为极值。
**缺陷:**无法处理垂直线段的情况,因为此时这个距离未定义
全最小二乘法
距离的定义改成点到线段的举例,所以改了一下能量函数。
RANSAC:一条直线+多点噪声
RANSAC是RANdom SAmple Consensus
的缩写,即基于随机采样的一种方式,是一种能够处理拟合有较多噪声的一条直线的方法。
核心思想是先选择两个点构成一条直线,然后其余点给这条直线进行投票。如图,第一步首先选择两个点,然后第二步构建一条直线,第三步计算其余点到直线的距离,第四步选择距离较小的点为这条线进行投票,第五步重复。
RANSAC也可以拟合其他情况,那么方法扩展为:
- 选择目标模型的最少确定点(比如三角形就是三个点,圆形也是三个点,正方形是两个点)
- 构建模型,并计算其余点对于这个模型的误差(比如距离圆的距离,距离正方形最近边的距离)
- 设置阈值,误差小于阈值的点投上一票
- 重复
现在还有个问题,就是到底要重复多少次才能找到理想的线?假设总共循环次,有比例的噪声点,线的可信度为,那么:
左边选择两个属于直线的点的概率为,其他情况则是1减去这个值,也就是错误情况。假如实验错误了次,也就等于右式。经过计算可以得到下表
在确定最终结果的时候,我们记录了许多条线对应得到的投票数,假如设置一个投票阈值,也可以实现提取多条线。
Python实现 RANSAC算法检测直线、圆、正方形
代码有点长,不直接放在这里了,放Github上,注释很全,代码风格也还行hhh,效果如下:
Hough 霍夫变换:多条直线
初步思想
主要思想是转换空间+投票。这种方法能够处理多条直线、高噪声甚至直线部分点缺失的情况。
如图,霍夫变换能让图像空间的一条直线映射到霍夫空间的一个点(下图1),而图像空间的一个点映射到霍夫空间的一条线(下图2)。图像域的直线方程为,其中有两个确定直线的参数,这两个参数能够构成霍夫参数空间,即以为横坐标,为纵坐标。
假如图像空间有许多个点,那在霍夫空间上就会有许多条直线(如下图3),这些直线会有一个交点,那这个霍夫空间的交点可以映射回一条直线。
另外,由于噪声等因素,在霍夫空间可能不会有明显的一个交点,所以会离散化霍夫空间,分成许多小格子,每条线会给经过的小格子投票,得到票数越多的小格子就越可能是交点的位置。
实际思想:极坐标
那么现在还有问题,假如图像空间有垂直线,那么会趋近于无穷。这个的解决方法就是使用极坐标。如图,一条直线对应的就是过原点的法线角度和长度。(此处图有点小错误,可能是负数,距离应该取绝对值)。
- 图像空间的直线:
->
。 - 图像空间的点:
->
。
那么在极坐标进行投票就是对于所有,计算,然后在对应的投票矩阵中+1
。下面是一些例子:
霍夫变换噪声分析
当噪声增加的时候,可能在霍夫空间较难找出一个点,而图像完全是噪声、没有直线的时候,在霍夫空间也可能有交点,从而识别出线。解决方法是相邻区间加权,就像高斯平滑相对平均平滑一样。
利用梯度
在边缘检测的时候,其实能够检测到一个点对应的直线方向,所以能得到一个具体的,所以就不用对于所有了。
实践时也不是只用一个,而是取一些区间
霍夫圆检测
霍夫变换也能够用来检测圆,此时霍夫空间就是三维的了,对于图上的一个像素,它可能位于圆上,这个时候就是已知圆上一点,求圆心和半径
。
通过边缘检测可以得到圆上一个点的梯度方向,易知圆心在梯度的正向或者反向上。所以霍夫空间上一个就能有两个点(圆心)。这样就可以对于所有进行投票。
霍夫变换直线检测代码
下面这份代码实现了使用极坐标霍夫变换检测直线,包括非最大化抑制、加权投票、检测多条直线等,注释超全。
代码也托管于Github
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!