win10+Python3.7.3+OpenCV3.4.1入门学习(十六 霍夫变换)————16.1 霍夫变换原理

Python版本是Python3.7.3,OpenCV版本OpenCV3.4.1,开发环境为PyCharm

第16章 霍夫变换

霍夫变换是一种在图像中寻找直线、圆形以及其他简单形状的方法。霍夫变换采用类似于投票的方式来获取当前图像内的形状集合,该变换由Paul Hough(霍夫)于1962年首次提出。最初的霍夫变换只能用于检测直线,经过发展后,霍夫变换不仅能够识别直线,还能识别其他简单的图形结构,常见的有圆、椭圆等。
本章主要介绍霍夫直线变换和霍夫圆变换。霍夫直线变换用来在图像内寻找直线,霍夫圆变换用来在图像内寻找圆。在OpenCV中,前者可以用函数cv2.HoughLines()和函数cv2.HoughLinesP()实现,后者可以用函数cv2.HoughCircles()实现。
OpenCV提供了函数cv2.HoughLines()和函数cv2.HoughLinesP()用来实现霍夫直线变换。

16.1 霍夫变换原理

为了方便说明问题,先以我们熟悉的笛卡儿坐标系(与笛卡儿空间对应)为例来说明霍夫变换的基本原理。与笛卡儿坐标系对应,我们构造一个霍夫坐标系(对应于霍夫空间)。在霍夫坐标系中,横坐标采用笛卡儿坐标系中直线的斜率k,纵坐标使用笛卡儿坐标系中直线的截距b。
首先,我们观察笛卡儿空间中的一条直线在霍夫空间内的映射情况。例如,在下图中,左图是笛卡儿x-y坐标系(笛卡儿空间),右图是霍夫k-b坐标系(霍夫空间)。在笛卡儿空间中,存在着一条直线y=k0x+b0,该直线的截距k0是已知的常量,截距b0也是已知的常量。将该直线映射到霍夫空间内,找到已知的点(k0, b0),即完成映射。

在这里插入图片描述

从上述分析中可知,笛卡儿空间内的一条直线,其斜率为k,截距为b,映射到霍夫空间内成为一个点(k, b)。或者,可以这样理解,霍夫空间内的一个点(k0, b0),映射到笛卡儿空间,就是一条直线y=k0x+b0。
这里,我们用“映射”这个词表达不同的空间(坐标系)之间的对应关系,也可以表述为“确定”。例如,上述关系可以表述为:
● 笛卡儿空间内的一条直线确定了霍夫空间内的一个点。
● 霍夫空间内的一个点确定了笛卡儿空间内的一条直线。
接下来,观察笛卡儿空间中的一个点在霍夫空间内的映射情况。如图16-2所示,在笛卡儿空间内存在一个点(x0, y0),通过该点的直线可以表示为y0=kx0+b。其中,(x0, y0)是已知的常量,(k, b)是变量。
对于表达式y0=kx0+b,通过算术运算的左右移项,可以表示为b=-x0k+y0。将点(x0, y0)映射到霍夫空间时,可以认为对应的直线斜率为-x0,截距为y0,即b=-x0k+y0,如下图中右图的直线所示。

在这里插入图片描述

从上述分析可知:
● 笛卡儿空间内的点(x0, y0)映射到霍夫空间,就是直线b=-x0k+y0。
● 霍夫空间内的直线b=-x0k+y0映射到笛卡儿空间,就是点(x0, y0)。
下面我们看看笛卡儿空间中的两个点映射到霍夫空间的情况。例如,在下图中,左图的笛卡儿空间中存在着两个点(x0, y0)、(x1, y1),分析这两个点映射到霍夫空间的情况。

在这里插入图片描述

为了方便理解,我们从不同的角度分析笛卡儿空间中这两个点到霍夫空间的映射情况。
● 角度1:笛卡儿空间的一个点会映射为霍夫空间的一条线。
在笛卡儿空间内,存在着任意两个点(x0, y0)、(x1, y1)。在霍夫空间中,这两个点对应着两条不同的直线。当然,通过分析可知,一条直线是b=-x0k+y0,另外一条直线是b=-x1k+y1。
● 角度2:笛卡儿空间的一条线会映射为霍夫空间的一个点
在笛卡儿空间内,存在着任意两个点(x0, y0)、(x1, y1)。这两个点一定能够用一条直线连接,将连接它们的直线标记为y=k1x+b1,则该直线的截距和斜率是(k1,b1)。也就是说,该直线在霍夫空间内映射为点(k1,b1)。
从上述分析可知:
● 笛卡儿空间内的两个点会映射为霍夫空间内两条相交于(k1,b1)的直线。
● 这两个点对应的直线会映射为霍夫空间内的点(k1,b1)。
换句话说,角度1决定了线条的数量,角度2决定了两条线相交的点。
这说明,如果在笛卡儿空间内有两个点A、B,它们能够连成一条直线y=k1x+b1,那么在霍夫空间中的点(k1,b1)上会有两条直线,分别对应着笛卡儿空间内的两个点A、B。
下面我们看看笛卡儿空间中的三个点映射到霍夫空间的情况。在图16-4中,左图是笛卡儿空间,其中存在(0, 1)、(1, 2)、(2, 3)三个点。

在这里插入图片描述

下面从不同的角度分析笛卡儿空间中这三个点映射到霍夫空间的情况。
● 角度1:笛卡儿空间内的一个点会映射为霍夫空间的一条线。
例如,笛卡儿空间中的(0, 1)、(1, 2)、(2, 3)三个点映射到霍夫空间时,每个点对应着一条直线,对应关系如下表所示。
在这里插入图片描述

根据对应关系可知:
● 笛卡儿空间内的点(0, 1),对应着霍夫空间内的直线b=1。
● 笛卡儿空间内的点(1, 2),对应着霍夫空间内的直线b=-k+2。
● 笛卡儿空间内的点(2, 3),对应着霍夫空间内的直线b=-2k+3。
从上述分析可知,笛卡儿空间内的三个点映射为霍夫空间内的三条直线。
● 角度2:笛卡儿空间内的一条线会映射为霍夫空间的一个点。
例如,笛卡儿空间中的(0, 1)、(1, 2)、(2, 3)三个点对应着直线y=x+1,斜率k为1,截距b为1。该直线y=x+1映射到霍夫空间内的点(1, 1)。
从上述角度1和角度2的分析可知:
● 笛卡儿空间中的(0, 1)、(1, 2)、(2, 3)三个点会映射为霍夫空间内相交于点(1, 1)的三条直线。
● 笛卡儿空间中的(0, 1)、(1, 2)、(2, 3)三个点所连成(确定)的直线映射为霍夫空间内的点(1, 1)。
这说明,如果在笛卡儿空间内有三个点,并且它们能够连成一条y=k1x+b1的直线,那么在霍夫空间中,对应的点(k1, b1)上会有三条直线,分别对应着笛卡儿空间内的三个点。
到此,我们已经发现,如果在笛卡儿空间内,有N个点能够连成一条直线y=k1x+b1,那么在霍夫空间内就会有N条直线穿过对应的点(k1, b1)。或者反过来说,如果在霍夫空间中,有越多的直线穿过点(k1, b1),就说明在笛卡儿空间内有越多的点位于斜率为k1,截距为b1的直线y=k1x+b1上。
现在,我们看一个在笛卡儿空间内更多个点映射到霍夫空间的例子,也验证一下上述观点。在下图中,左图所示的是笛卡儿空间,其中有6个点,下面从不同的角度看下这6个点在右图霍夫空间的映射情况。

在这里插入图片描述

● 角度1:笛卡儿空间的一点会映射为霍夫空间的一条线。
笛卡儿空间中的6个点:(0, 1)、(1, 2)、(2, 3)、(3, 4)、(3, 2)、(1, 4),映射到霍夫空间时,每个点对应着一条直线,对应关系如下表所示。
在这里插入图片描述

根据对应关系可知:
● 笛卡儿空间内的点(0, 1),对应着霍夫空间内的直线b=1。
● 笛卡儿空间内的点(1, 2),对应着霍夫空间内的直线b=-k+2。
● 笛卡儿空间内的点(2, 3),对应着霍夫空间内的直线b=-2k+3。
● 笛卡儿空间内的点(3, 4),对应着霍夫空间内的直线b=-3
k+4。
● 笛卡儿空间内的点(3, 2),对应着霍夫空间内的直线b=-3k+2。
● 笛卡儿空间内的点(1, 4),对应着霍夫空间内的直线b=-1
k+4。
从上述分析可知,笛卡儿空间内的6个点映射为霍夫空间内的6条直线。
● 角度2:笛卡儿空间的一条线会映射为霍夫空间的一个点。
这里为了观察方便,将笛卡儿空间内连接了较多点的线绘制出来:连接点(0, 1)、(1, 2)、(2, 3)、(3, 4)的线LineA,连接点(2, 3)、(3, 2)、(1, 4)的线LineB,连接点(0,1)、(3,2)的线LineC,如下图的左图所示。

在这里插入图片描述

需要注意,在笛卡儿空间内,各个点之间存在多条直线。例如在点(1, 2)、(3, 2)之间,点(3, 2)、(3, 4)之间,点(1, 4)、(3, 4)之间都存在着直线,这里做了简化,没有将上述直线都绘制出来。
下面分析笛卡儿空间内的三条直线LineA、LineB、LineC在霍夫空间内的映射情况。
● 直线LineA经过了4个点,表达式为y=1x+1,斜率k为1,截距b为1,在霍夫空间内对应于点A(1, 1)。
● 直线LineB经过了3个点,表达式为y=-1
x+5,斜率k为-1,截距b为5,在霍夫空间内对应于点B(-1, 5)。
● 直线LineC经过了2个点,表达式为y=-1/3*x+1,斜率k为-1/3,截距b为1,在霍夫空间内对应于点C(-1/3, 1)。
在上图中可以看到,右图所示的霍夫空间内点A有4条直线穿过,点B有3条直线穿过,点C有2条直线穿过。
分析上述关系:
● 霍夫空间内有4条直线穿过点A。点A确定了笛卡儿空间内的一条直线,同时该直线穿过4个点,即霍夫空间内的点A确定了笛卡儿空间内的LineA,该直线上包含(0, 1)、(1, 2)、(2, 3)、(3, 4)共4个点。
● 霍夫空间内有3条直线穿过点B。点B确定了笛卡儿空间内的一条直线,同时该直线穿过3个点,即霍夫空间内的点B确定了笛卡儿空间内的LineB,该直线上包含(2, 3)、(3, 2)、(1, 4)共3个点。
● 霍夫空间内有2条直线穿过点C。点C确定了笛卡儿空间内的一条直线,同时该直线穿过2个点,即霍夫空间内的点C确定了笛卡儿空间内的LineC,该直线上包含(0, 1)、(2, 3)共2个点。
综上所述,在霍夫空间内,经过一个点的直线越多,说明其在笛卡儿空间内映射的直线,是由越多的点所构成(穿过)的。我们知道,两个点就能构成一条直线。但是,如果有一个点是因为计算错误而产生的,那么它和另外一个点,也会构成一条直线,此时就会凭空构造出一条实际上并不存在的直线。这种情况是要极力避免的。因此,在计算中,我们希望用更多的点构造一条直线,以提高直线的可靠性。也就是说,如果一条直线是由越多点所构成的,那么它实际存在的可能性就越大,它的可靠性也就越高。因此,霍夫变换选择直线的基本思路是:选择有尽可能多直线交汇的点。
上面都是以我们熟悉的笛卡儿空间为例说明的。在笛卡儿空间中,可能存在诸如x=x0的垂线LineA的形式,如下图所示。

在这里插入图片描述

此时,斜率k为无穷大,截距b无法取值。因此,图中的垂线LineA无法映射到霍夫空间内。为了解决上述问题,可以考虑将笛卡儿坐标系映射到极坐标系上,如下图所示。

在这里插入图片描述

在笛卡儿坐标系内使用的是斜率k和截距b,即用(k, b)表示一条直线。在极坐标系内,采用极径r(有时也用ρ表示)和极角θ来表示,即(r, θ)来表示。极坐标系中的直线可以表示为:
r=xcosθ+ysinθ
例如,图中的直线LineA,可以使用极坐标的极径r和极角θ来表示。其中,r是直线LineA与图像原点O之间的距离,参数θ是直线LineA的垂线LineB与x轴的角度。在这种表示方法中,图像中的直线有一个(0~π)的角θ,而r的最大值是图像对角线的长度。用这种表示方法,可以很方便地表示上图中的3个点所构成的直线。
与笛卡儿空间和霍夫空间的映射关系类似:
● 极坐标系内的一个点映射为霍夫坐标系(霍夫空间)内的一条线(曲线)。
● 极坐标系内的一条线映射为霍夫坐标系内的一个点。
一般来说,在极坐标系内的一条直线能够通过在霍夫坐标系内相交于一点的线的数量来评估。在霍夫坐标系内,经过一个点的线越多,说明其映射在极坐标系内的直线,是由越多的点所构成(穿过)的。因此,霍夫变换选择直线的基本思路是:选择由尽可能多条线汇成的点。
通常情况下,设置一个阈值,当霍夫坐标系内交于某点的曲线达到了阈值,就认为在对应的极坐标系内存在(检测到)一条直线。
上述内容是霍夫变换的原理,即使完全不理解上述原理,也不影响我们使用OpenCV提供的霍夫变换函数来进行霍夫变换。OpenCV本身是一个黑盒子,它给我们提供了接口(参数、返回值),我们只需要掌握接口的正确使用方法,就可以正确地处理图像问题,无须掌握其内部工作原理。
在某种情况下,OpenCV库和Photoshop等图像处理软件是类似的,只要掌握了它们的使用方法,就能够得到正确的处理结果。在进行图像处理时,并不需要我们关注其实现原理等技术细节。但是,如果我们进一步了解其工作原理,对我们的工作也是有大有裨益的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值