霍夫变换是一种特征检测。例如:线条。他的算法流程大致如下,给定一个物件,要辨别的形状的种类,算法会在参数空间中执行投票来决定物体的形状,而这是由累加空间里的局部最大值决定。
霍夫变换最初被设计成用来检测能够精确的解析定义的形状(例如直线,圆等)。在这些情况下,我们可以通过对于形状信息的充分了解来找出他们在图像中的位置和方向。而广义霍夫变换在霍夫变换的基础上根据模板匹配的原理进行了调整,广义霍夫变换不要求能够给出需要检测的形状的解析式,它可以检测任意给定的形状。
1.基本原理
一条直线可以由两个点A,B确定(笛卡尔坐标)1.直线在极坐标系中的表示
另一方面,y=kx+q也可以写成关于(k,q)的函数表达式(霍夫空间):
对应的变换可以通过图形直观表示:
变换后的空间称为霍夫空间。即:笛卡尔坐标系中一条直线,对应霍夫空间的一个点。
反过来同样成立(霍夫空间的一条直线,对应笛卡尔坐标系的一个点)
再看A、B两个点,对应霍夫空间的情形:
一步步来,再看三个点共线的情况:有两条直线:
可以看出如果笛卡尔坐标系的点共线,这些点在霍夫空间对应的直线交于一点:这就是必然,共线只有一种取值的可能。
如果不止一条直线呢,再看看多点的情况(有两条直线):
其实,(3,2)与(4,1)也可以组成直线,只不过它有两个点确定,而图中A、B两点是由三条直线汇成,这也是霍夫变换后处理的基本方式:选择由尽可能多直线汇成的点。
看看,霍夫空间:选择由三条交汇直线确定的点(中间图),对应的笛卡尔坐标系的直线(右图)。
到这里问题似乎解决了,已经完成了霍夫变换的求解,但是如果像下图这种情况呢?
k=∞是不方便表示的,而且q怎么取值呢。因此将笛卡尔坐标系换为:极坐标表示。
应用1:利用霍夫变换检测直线
1.直线在极坐标系中的表示
对于平面中的一条直线,在直角坐标系中,常见的有点斜式,两点式两种表示方法。然而在霍夫变换中,考虑的是另外一种表示方式:使用极坐标(r,theta)来表示一条直线。其中r为该直线到原点的距离,theta为该直线的垂线与x轴的夹角。
2.如果坐标系中由多个点,又怎样识别出那些点在一条直线上?
使用hough变换来检测直线的洗点就是:为每一个点假设n个方向的直线,通常n=180,此时检测的直线角度精度为1度,分别计算这n条直线的(r,theta)坐标,得到n个坐标点。如果要判断的点共N个最终得到的(r,theta)坐标有N×n个,有关这N×n个(r,theta)坐标,其中theta是离散的角度,共有180个取值。
最重要的地方来了,如果多个点在一条直线上,那么必有这么多个点在theta=某个值theta_i时,这多个点的r近似相等r_i。也就是说这多个点都在直线(r_i,theta_i)上。
3.下面拿个例子说明:
如果空间中有3个点,如何判断这三个点在不在一个直线上,如果在,这条直线的位置为?
这个例子中,对于每个点均求过该点的6条直线的(r,theta)坐标,共求了3*6个(r,theta)坐标。可以发现在theta=60时,三个点的r都近似为80.7,由此可以判定这三个点都在直线(80.7,60)上。
通过r,theta坐标系可以更直观表示这种关系,如下图:图中三个点的(r,theta)曲线汇集在一起,该焦点就是同时经过这三个点的直线。
在实际的直线检测情况中,如果超过一定数目的点拥有相同的(r,theta)坐标,那么就可以判定此处有一条直线。在r theta坐标系图中,明显的交汇点就标示一条检测出的直线。
如下图,可以判定出平面上的点共构成了两条直线,即检测出两条直线。
应用2:利用霍夫变换检测圆
具体步骤如下:
1.对输入图像进行边缘检测,获取边界点,即前景点。
2.加入图像中存在圆形,那么其轮廓必定属于前景点。
3.如同霍夫变换检测直线一样,将圆形的一般性方程换一种方式表示,进行坐标变换。由x-y坐标系转换到a-b坐标系。写成如下形式(a-x)²+(b-y)²=r²。那么x-y坐标系中圆形边界上的点对应到a-b坐标系中即为一个圆。
4.那x-y坐标系中一个圆形边界上有很多个点,对应到a-b坐标系中就会有很多个圆。由于原图像中这些点都在同一个图形上,那么转换后a,b必定也满足a-b坐标系下的所有圆形的方程式。直观表现为这许多点对应的圆会相交于一点。,那么这个交点可能是圆心(a,b)。
5.统计局部交点处圆的个数,取每一个局部最大值,就可以获得原图像中对应的圆形的圆心坐标(a,b)。一旦在某一个r下面检测到圆,那么r的值也就随之确定。
注:r值的确定
Opencv中提供的cvHoughCIrcle()函数里面可以设定半径r的取值范围,相当于有一个先验设定,在每一个r来说,在二维空间内寻找a和b就可以了,能够减少计算量。