霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法。主要用来从图像中分离出具有某种相同特征的几何形状(如,直线,圆等)。最基本的霍夫变换是从黑白图像中检测直线(线段)。
一、直线检测
1.直线的表示方式
对于平面中的一条直线,在笛卡尔坐标系中,常见的有点斜式,两点式两种表示方法。然而在hough变换中,考虑的是另外一种表示方式:使用(r,theta)来表示一条直线。其中r为该直线到原点的距离,theta为该直线的垂线与x轴的夹角。如下图所示。
也就是霍夫变换中表示一条直线的参数变成了(r,theta)。
2.如何判断多个点是否在同一直线上
当我们的对象变成点时,我们知道一个点可以发射出无数条直线,根据霍夫变换的直线表达形式,假设这个点为i,则通过这个点的直线我们用(ri,thetai)表示。再假设一个点为j,则通过点j的一系列直线我们用(rj,thetaj)表示。我们知道两点决定一条直线,所以这两个点的直线必定有ri=rj,thetai= thetaj的时候。
那如果是三个点呢,假设第三个点是k,则通过k点的一系列直线为(rk,thetak),如果三点在一条直线上,那必定有某个ri=rj=rk = r,thetai = thetaj= thetak = theta。
在霍夫变换检测直线时我们需要找到这样一样直线,如何找到这条直线呢?
3.如何检测出直线
假设有N个点,我们要检测其中的直线,也就是我们要找到具体的r和theata。对于上面所说的每个点可以通过无数条直线,这里我们设为n条(通常 n = 180),则我们一起可以找到Nn个(r, theata),对这Nn个(r,theata),我们可以利用统计学,统计到在theta=某个值theta_i时,多个点的r近似相等于r_i。也就是说这多个点都在直线(r_i,theta_i)上。
4.举例说明
如果空间中有3个点,如何判断这三个点在不在一个直线上,如果在,这条直线是的位置为?
这个例子中,对于每个点均求过该点的6条直线的(r,theta)坐标,共求了3*6个(r,theta)坐标。可以发现在theta=60时,三个点的r都近似为80.7,由此可判定这三个点都在直线(80.7,60)上。
通过 r-o-theta 坐标系可更直观表示这种关系,如下图:图中三个点的(r,theta)曲线汇集在一起,该交点就是同时经过这三个点的直线。
在实际的直线检测情况中,如果超过一定数目的点拥有相同的(r,theta)坐标,那么就可以判定此处有一条直线。在r-O-theta 坐标系图中,明显的交汇点就标示一条检测出的直线。
如下图,可以判定出平面上的点共构成了两条直线,即检测出两条直线。
上面参考:http://blog.163.com/yuyang_tech/blog/static/21605008320130233343990/
这里插入一个用opencv进行霍夫变化检测直线的例子
http://blog.sina.com.cn/s/blog_60b330b801018md4.html
先进行边缘提取,再设置一些线段的容忍长度,可以检测到直线。
二、圆检测
1.圆的表示方式
两点确定一条直线,不在一条直线上的三点确定一个圆。与使用(r,theta)来表示一条直线相似,使用(a,b,r)来确定一个圆心为(a,b)半径为 r 的圆。
2.如何判断多个点是否在一个圆上
同样经过一个点可以作出无数个圆,假设某个点平面坐标为(xi,yi),使用的参数为(ai,bi,ri)则经过此点的圆的表达式为(xi-ai)^2 +(yi-bi) ^ 2=ri ^ 2。对于点(xj,yj),必定存在(aj,bj,rj)使得 近似计算中 ai=aj,bi= bj, ri = rj,即两个点在同一个圆上;同理如果三个点在同一个圆上,则也必须存在 ai=aj =ak = a, bi=bj=bk = b, ri=rj=rk = r 的情况。
3.如何检测圆
要将圆检测出来,也就是要将上述的(a,b,r)求解出来。
假设r确定,此时点(x,y)又已知,根据(x-a)^2 +(y-b) ^ 2=r ^ 2 ,则(a,b)的轨迹在几何上则变成了以(x,y)为圆心,r为半径的圆;而r不确定时,(a,b,r)的轨迹变成了以(x,y)为顶点的一个圆锥。则(ai,bi,ri),(aj,bj,rj), (ak,bk,rk)的圆为下图中圆锥面的角点A。
例子用一个opencv的霍夫变换检测圆:
https://blog.csdn.net/kh1445291129/article/details/45674417
找到灰度图后进行双边滤波,利用houghcircle检测圆,再利用circle将圆显示出来。
三、其他形状
无论是直线还是圆,都是根据本身的几何形状的数学性质,直线根据极坐标的(r,theta)来表示,圆根据(a,b,r)来表示。要检测出直线或者圆其实就是要找到这样的(r,theta)或者(a,b,r)。根据相关的直线或圆的表达式反推出(r,theta)及(a,b,r)的轨迹,相应轨迹的交点就是要找到的直线或圆或想要找到的形状。