Hough 变换
作用
霍夫变换是常用的图像变换,用于在图像中寻找直线、圆、椭圆等这类具有相同特征的几何图形。在许多应用场合中,都需要实现对特定形状物体的快速定位,而霍夫变换由于其对方向和噪声不敏感,因此在这类应用中发挥着重要作用。
原理
霍夫变换最基本的思想通俗讲就是将图像中所有可能出现的几何图形位置进行遍历,以直线检测为例,就是在整幅图像中进行扫描所有可能的直线,看图像中的像素点对各直线的贡献。下面以直线为例,形象地进行介绍:
图 1.霍夫变换示意图
如图1所示,矩形点阵表示图像,黑色的点表示边缘的像素点。霍夫变换即在图中寻找所有可能的直线(如蓝色和红色线条),通过计算像素对直线的贡献,来判断是否存在直线。这里像素对直线的贡献的定义,即该图像中像素与直线所交的点的数量。
如图1中所示,我们可以很直观地判断,两条红色直线所在的位置才是原图像中像素点所表示的两条直线位置,而原图对这两条直线的贡献也最大。霍夫变换的关键就是需要总结应该怎么去找这两条直线,寻找一种方式,即能节省资源,又能获得很高效率,并且不漏检任何一条可能的直线。
霍夫变换找直线简单来说分为以下几步:
1. 计算边缘图像;
2. 进行霍夫变换(对每一个边缘的点计算所有可能的经过该点的直线方程);
3. 寻找其中贡献最大的几条直线的参数。
为了能够直观地理解霍夫变换的原理以及实际应用的整个过程,在下面的描述过程中,我以一副图像为例进行讲述。原图如下,这是一幅网上随便找的图片,反正直线多就好啦:
图 2原图
一、边缘图像
边缘图像的求取方法很多,简单的复杂的都有。常见的就是实用一些‘canny’、‘sobel’、‘prewitt’等算子求边缘;复杂的有进行傅里叶变换,然后通过高通滤波提取高频分量,然后再进行傅里叶反变换重构图像提取边缘信息;还有通过Garbor变换、小波等工具进行多尺度分析来提取边缘。总之方法很多,作为一个预备过程,这里不进行过多介绍。下图所示为对原图像进行计算边缘后求得的边缘图像:
图 3边缘图像
在实际的应用过程中,经过简单的边缘提取可能会导致一条较粗的直线会最终提取为两条直线。比如在上述边缘图像中,直线被两侧的边缘所包围,这时候两侧的边缘都可能会检测成直线。这时候对边缘图像进行简答的形态学处理就能有更好的效果,相应地,在提取直线参数的时候也可以进行一些优化。
二、计算霍夫空间(霍夫变换)
进行霍夫变换最重要的就是将所有可能的直线参数化。我们知道,任意一条经过点 的直线都必须满足方程,该式可以转化为。因此经过点的所有直线就是空间中的一条直线,只有是这条直线上的点都满足上述方程。因此如果总共有个边缘像素点,它们在空间中就有条线,并且会有交点,如下图所示:
对于图中两条直线的交点,我们可以理解为同时经过点和的直线,该直线方程为。因此,如果交于一点的直线越多,那么说明原图像对该直线的贡献最大。但是在空间去寻找可能出现的直线很难用计算机实现,因为交点出现的位置任意,范围是整个二维平面。因此,我们将这个直线方程进行转换,用极坐标进行表示,原直线方程就可以表示为:
其中表示直线到坐标原点的距离;表示直线到坐标原点垂线的角度,示意图如下:
图 5直线到极坐标系转换
固定变量和,则原方程就是一个和的方程,该方程对应为空间中对应的是一条正弦曲线。直观来理解,这些直线就是绕坐标进行旋转,并且由于直线的对称性,直线的方程旋转角度后将出现重复。由于图像本身的尺寸是已知的,因此图像中的直线方程用极坐标表示时变量最大也就是图像对角线的长度,如下图4中所示:
因此对于宽为m,高为n的图像,所有的直线方程在空间上的取值范围为:
这是一个有界的矩形区域,里面由一条条正弦曲线组成,大致的形状如下图所示:
图 7 Hough空间示意
图像中粗线条的曲线代表的就是一条条的直线方程,每计算出一条曲线,该曲线的路径上的对应像素灰度就加1。因此,如果有一个像素点被多条曲线相交,那么该点处的像素灰度值就会很高,原图对该点所表示的直线贡献度也高。
在本例程中对边缘图像进行霍夫变换,求得的霍夫空间的图像如下图:
图 8 霍夫空间图像
从图中我们可以看到,图中有多处亮点,位于许多正弦曲线的交点处。这些亮点就是我们下一步需要提取的目标,即原图中存在的直线参数。
三、直线参数提取
在霍夫图像中提取直线参数实质就是进行图像分割,此时分割方式的选取将直接影响直线提取的数量和精确程度。常见的由进行排序后提取固定直线数量的方法,也有基于区域分割的方式等。这些方法针对不同场合有不同的应用,每种方法都有各自的优缺点。这里我使用了一个固定的阈值进行分割,提取高于阈值的像素点。将提取出来的像素点根据其对应的坐标就可以知道该点对应的直线参数和。根据参数,在原图上绘出这些直线,效果如下:
图 9检测结果图
蓝色线条是检测得到的结果,从图中可知,有部分直线没有检测出来;也有部分直线被检测成两条。在边缘检测那节中就介绍过,可以通过适当的方式来消除这些重复的直线,这里介绍一种:对边缘图像进行形态学处理(闭操作),将两侧的边缘合成一条;在检测直线时进行基于区域的分析,求得各区域块之后计算每一个区域的中心坐标,作为直线的参数。这样相邻的直线就不会变检测为两条了,具体操作比较简单这里就不进行介绍了。