Hough直线检测
标准直线Hough变换采用如下参数化直线方程:
x*cosθ+y*sinθ=ρ (1)
式中,θ表示直线的法线方向,0≤θ<180,ρ表示原点至直线的距离(本文中θ的单位均为“度”,ρ的单位均为“像素”)。通常在图像直线检测中不直接使用图像坐标系,而是使用原点在图像中心处、y轴方向与图像的y 方向相反的正交坐标系,如图1所示的Oxy坐标系。
为了进行直线检测,首先需要按一定的量化间隔将可能的θ与ρ 取值范围离散化为若干区间,其中θ的取值范围规定在[0,180)的区间内,而ρ的取值范围则由图像矩形的顶点至原点即图像中心的距离确定;整个可能的θ-ρ 参数空间被离散化为一个二维的网格,对每一个可能的离散化参数对(θi,ρj)即每个网格单元设置一个计数器。然后对图像中的每个特征点(x0,y0),遍历所有的离散θ值,根据式(1)计算出每个θi值下对应的ρ 值及相应的离散区间ρi,并对计数器(θi,ρi)的值加1,这一过程称为特征点对参数空间投票。当所有的特征点均完成了投票后,寻找出参数空间中计数器值大于某一给定阈值T 的局部极大点,这些局部极大点对应的直线参数对(θ,ρ)即代表了检测得到的图像中的直线。
以图1为例,对于每一个在直线l0上的点,均有
x*cosθ0 + y*sinθ0 = ρ0
可以设一个截距式参数方程,x/a + y/b = 1,求得cosθ0,sinθ0;对于点p,Xp,Yp满足Xp/a + Yp/b = 1,然后即可验证Xp*cosθ0+Yp*sinθ0=ρ0.
所以对于计数器 (θ0,ρ0)而言它极有可能为最大值。得到θ0和ρ0后直线也就检测出来了。
下面的代码将检测直线,并标记出来。
<span style="font-size:18px;">void CImageColorProcess::HoughLineDetect(LPBYTE binaryimage, LPBYTE lpDst, int nSrcCount, int nW, int nH, int threshold) {//binaryimage是二值图像,threshold是检测阈值 int nSrcLine = LINEWIDTH(nW*nSrcCount); int roMax = (int)sqrt(nW * nW + nH * nH) + 1; int* mark = new int[roMax*180]; for (int i = 0; i < roMax; i++) for (int j = 0; j < 180; j++) mark[i * 180 + j] = 0; double* theta = new double[180]; for (int i = 0; i < 180; i++) { theta[i] = (double)i * PI / 180.0; } double roValue = 0.0; int transValue = 0; for (int y = 0; y < nH; y++) { for (int x = 0; x < nW; x++) { if (binaryimage[x + y * nW ] == 0) { for (int k = 0; k < 180; k++) { roValue = (double)x * cos(theta[k]) + (double)y * sin(theta[k]); transValue = (int)(roValue / 2 + roMax / 2); mark[transValue*180+k]++; } } } } for (int y = 0; y < nH; y++) { for (int x = 0; x < nW; x++) { lpDst[y*nSrcLine + 3 * x] = 255; lpDst[y*nSrcLine + 3 * x+1] = 255; lpDst[y*nSrcLine + 3 * x+2] = 255; int T = x + y * nW ; if (binaryimage[T] == 0) { for (int k = 0; k < 180; k++) { roValue = (double)x * cos(theta[k]) + (double)y *sin(theta[k]); transValue = (int)(roValue / 2 + roMax / 2); if (mark[transValue*180+ k] > threshold) { lpDst[y*nSrcLine+3*x] = (byte)0;//做标记 } } } } } }</span>
下面是检测结果:
检测直线的霍夫变换提供了在图像中寻找直线的一种算法,是最简单的一种情形,后来发展到检测圆、椭圆、还有一般图形的霍夫变换,其核心思想是把图像中属于某种图形的点集(二维)映射到一个点(可以是高维)上,这个点记录了点集中点的数目,使得程序通过搜索峰值找到该点,这个点就是后面要说到的图形的参数,而该参数的范围就叫做参数空间。霍夫变换不仅能够识别出图像中有无需要检测的图形,而且能够定位到该图像的位置、角度等。
版权声明: