霍夫变换(Hough Transform )HoughLines 和HoughLinesP 有什么不同?
一、背景
1. HoughLines定义
OpenCV 提供了函数 ()用来实现霍夫直线变换,该函数要求所操作的源图像是一个二值图像,所以在进行霍夫变换之前要先将源图像进行二值化,或者进行 Canny 边缘检测。
函数 ()的语法格式为:
lines=(image,rho,theta,threshold)
式中:
● image 是输入图像,即源图像,必须是 8 位的单通道二值图像。如果是其他类型的图像,在进行霍夫变换之前,需要将其修改为指定格式。
● rho 为以像素为单位的距离 r 的精度。一般情况下,使用的精度是 1。
● theta 为角度 θ 的精度。一般情况下,使用的精度是 π/180,表示要搜索所有可能的角度。
● threshold 是阈值。该值越小,判定出的直线就越多。通过上一节的分析可知,识别直线时,要判定有多少个点位于该直线上。在判定直线是否存在时,对直线所穿过的点的数量进行评估,如果直线所穿过的点的数量小于阈值,则认为这些点恰好(偶然)在算法上构成直线,但是在源图像中该直线并不存在;如果大于阈值,则认为直线存在。所以,如果阈值较小,就会得到较多的直线;阈值较大,就会得到较少的直线。
● 返回值 lines 中的每个元素都是一对浮点数,表示检测到的直线的参数,即(r,θ),是 类型。
2. HoughLinesP定义
概率霍夫变换对基本霍夫变换算法进行了一些修正,是霍夫变换算法的优化。它没有考虑所有的点。相反,它只需要一个足以进行线检测的随机点子集即可。
为了更好地判断直线(线段),概率霍夫变换算法还对选取直线的方法作了两点改进:
● 所接受直线的最小长度。如果有超过阈值个数的像素点构成了一条直线,但是这条直线很短,那么就不会接受该直线作为判断结果,而认为这条直线仅仅是图像中的若干个像素点恰好随机构成了一种算法上的直线关系而已,实际上原图中并不存在这条直线。
● 接受直线时允许的最大像素点间距。如果有超过阈值个数的像素点构成了一条直线,但是这组像素点之间的距离都很远,就不会接受该直线作为判断结果,而认为这条直线仅仅是图像中的若干个像素点恰好随机构成了一种算法上的直线关系而已,实际上原始图像中并不存在这条直线。
在 OpenCV 中,函数 ()实现了概率霍夫变换。其语法格式为:
式中参数与返回值的含义如下:
● image 是输入图像,即源图像,必须为 8 位的单通道二值图像。对于其他类型的图像,在进行霍夫变换之前,需要将其修改为这个指定的格式。
● rho 为以像素为单位的距离 r 的精度。一般情况下,使用的精度是 1。
● theta 是角度 θ 的精度。一般情况下,使用的精度是 /180,表示要搜索可能的角度。
● threshold 是阈值。该值越小,判定出的直线越多;值越大,判定出的直线就越少。
● minLineLength 用来控制「接受直线的最小长度」的值,默认值为 0。
● maxLineGap 用来控制接受共线线段之间的最小间隔,即在一条线中两点的最大间隔。
如果两点间的间隔超过了参数 maxLineGap 的值,就认为这两点不在一条线上。默认值为 0。
● 返回值 lines 是由 类型的元素构成的,其中每个元素都是一对浮点数,表示检测到的直线的参数,即(r,θ)。
以上两个定义摘自《OpenCV轻松入门》,但书中这里出现了一处错误,应该是笔误
书中写到HoughLinesP返回值为(r,θ),
实际上是错误的。返回值应该为:x1,y1,x2,y2,
即返回两个点的坐标。
二、效果展示
1. 经典数独:
在数独检测中,HoughLines 的表现似乎比HoughLinesP 好一些。但别着急,请看下一个
2. 经典building
OpenCV 官网提供了一幅名为 的图像用来测试,大家可以下载该图像,对其进行霍夫变换,观察检测的效果。该图在使用霍夫变换进行检测时,存在非常严重的误检测。为了解决上述问题,人们提出了霍夫变换的改进版——概率霍夫变换。
似乎HoughLinesP看起来要清楚些。
实际上,主要是HoughLines是一条直线而非线段,而那些小树叶又容易被误检测成图片,所以才会画的面目。
3. 最后一个小提示
在我使用的 OpenCV 3.4.0版本中 ,HoughLinesP中还有一个可选参数Lines,这个参数在书中没有提到
HoughLinesP 参数列表中的Lines是有什么用呢?
在官方文档中并没有解释这个参数的意义,
我自己简单测试了几个样例,也暂时没用发现有什么不同。
如果您在知晓这个参数的作用,或在其他地方看到了相关资料,还请您指教,在评论区指出或者私信我均可,谢谢您。