参考博客:
1.Opencv学习笔记-----霍夫变换直线检测及原理理解
3.霍夫变换直线检测(Line Detection)原理及示例
霍夫变换(Hough Transform)是图像处理领域内从图像中检测几何形状的基本方法之一。经典霍夫变换用来检测图像中的直线,后来经过扩展可以进行任意形状物体的识别。
原理概括:在一个参数空间中,通过计算累计结果的局部最大值,得到一个符合该特定形状的的集合作为霍夫变换结果。
问题1: 在了解霍夫变换的具体原理之前,先想一下直线有哪些表现形式
- 用直角坐标系表示:y = k*x + b
- 用极坐标表示:r = x*cosθ + y*sinθ
用直角坐标系表示是比较熟悉的一种方式,极坐标表示可能没有那么清晰,在这里做一下说明:
第一种方法:
直线表达式为:
化简后得到:
第二种方法:
ρ和第一种方法中的r是一样的,都是原点到直线的距离。
其实这两种方法本质上是一样的,与直角坐标系不同,它们的切入点在于要有个原点到直线的距离的参数,同时,再加上θ角度就可以确定这条直线。也就是说,给定两个参数: r(原点到直线的距离)和 θ(原点到直线的垂线与x轴的夹角),就代表着一条直线。换句话说就是,直角坐标系中的一条直线对应参数方程中的一个点。
问题2: 了解清楚直线的两种表现方式之后,对理解霍夫变换有什么帮助吗?
首先,给定一个点,我们要想找到与此点在同一条直线上的其他点,是否是要将别的点的坐标代入,看是否符合过此点的坐标公式。这个时候就会出现一个问题,当我们在使用直角坐标公式的时候,也就是:y = k*x + b 时,假设当我们所要检测的点过定点刚好与x轴垂直时,此时的k是趋于无穷大的,无法表示出来,也就是说这种情况没有办法计算这个要检测的点是否与定点在同一条直线上。
所以,霍夫变换要用极坐标公式来进行计算,以消除特殊情况的误差。
再明确一下我们的搜索范围,想要找到哪些点在过定点的直线上,先明确这些点的范围,有可能是在过定点的任意直线上,这也是为什么不使用直角坐标系的原因。此时,绘出过某定点的任意直线的极坐标图像(假设给定点X_0= 8 和Y_0= 6):
如图所示,将得到一条正弦曲线。在问题1已经说过了,直角坐标系中的一条直线对应参数方程中的一个点,只要是在这个直角坐标系上的点,它们的 r 和 θ 的值都是固定的,映射到极坐标系上自然对应一个固定的点。
而对于直角坐标系中的某一点来说,其 r 和 θ 的值不是固定的,因为过此点的直线可能有很多条,每条的 r 和 θ 值也可能不同,因此,直角坐标系中的一个点对应参数方程中的一条曲线。
下图可以直观的看出两者的对应关系:
问题3: 根据直角坐标系(图像空间)与极坐标系(参数空间)中点与直线的对应关系在检测直线中可以发挥什么作用呢?
当我们检测图像空间中的所有点时,在对应的参数空间中会出现很多条对应的曲线。其中会有许多条曲线相交于一点的情况,结合上个问题得出的结论,直角坐标系中的一个点对应参数方程中的一个曲线(过此点的任意直线),当这些参数空间中的曲线有相交的点时,说明过这些点在某 r 和某 θ 值时的直线是重合的,不难推断出这些点在图像空间中是存在于一条直线内的。
到此为止,就将图像空间中的直线变换成参数空间中的点,可通过统计特性来解决检测问题。
然而,又出现一个问题,理论上,一个点对应无数条直线,但在实际中这样很难进行计算。
问题4: 如何利用理论解决实际的问题呢?
可以将 r 和 θ 值离散化为有限个等间距的离散值,离散化后的参数空间就不再是连续的,将会被离散成一个个等大小的网格。
将图像空间中每个像素点坐标值变换到参数空间后,所得值会落在某个网格内,使得该网格的累加计数器加一。当所有的像素点都经过霍夫变换后,可对单元网格进行检查。在此之前还可对直线上点的数量进行限制,即设置一个阈值,当某单元网格的计数值大于设定的直线阈值时,则认为是一条直线。