图像的直线检测——霍夫变换(Hough transform)

首先给大家推荐一下我老师大神的人工智能教学网站。教学不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵黄段子!点这里可以跳转到网站

定义:

霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,可以识别图像中的几何形状。它将图像空间中的特征点映射到参数空间进行投票,通过检测累计结果的局部极值点得到一个符合某特定形状的点的集合。经典霍夫变换用来检测图像中的直线,后来霍夫变换扩展到任意形状物体的识别,多为圆和椭圆。它的抗噪声、抗形变能力较强。另一种直线提取的方法是对图像边缘点进行链码追踪,在得到的链码串中提取直线。

霍夫变换将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测任意形状的问题转化为统计峰值问题。

标准霍夫变换:

考虑点和线的对应关系,过一点(x1,y1)的直线可表示为:y1=kx1+b,将变量和参数互换,已知一个点(x1,y1),经过这一点的直线簇可以表示为b=(-x1)k+y1。位于同一条直线上的点具有相同的斜率和截距,反映到参数空间上就是这些直线会交于同一点(k,b)。

举个例子:图像空间有三个点(1,1),(2,2),(3,3),他们在直线y=1*x+0上,如下图所示

互换参数,在参数空间里这三个点对应三条直线:1=k+b,2=2*k+b,3=3*k+b,交于同一点(1,0),这一点即图像空间中直线的斜率和截距,如果我们能得到这些点,也就得到了图像空间的直线:

由于上面的变换不能表示斜率为无穷大的情况,因此,采用极坐标的方式:Rho = X * Cos(Theta) + Y * Sin(Theta):

在实际操作时,步骤如下:

1、得到图像的边缘信息;
2、对边缘图像中的每一个点,在k-b空间中画出一条直线;
3、对各直线上的点,我们采取“投票”(vote)的方法,即累加:有直线经过这一点,这一点的值加1;
4、遍历k-b空间,找出局部极大值点,这些点的坐标(k,b)就是原图像中可能的直线的斜率和截距。

霍夫变换的计算量和存储都是很大的。

同样的原理,我们可以用来检测圆,等式变为:(x –a ) ^2 + (y-b) ^ 2 = r^2,这样霍夫的参数空间就变成一个三维参数空间。若给定圆的半径则简化为二维霍夫参数空间。

动态广义霍夫变换

直线上的任意两点满足:

theta是直线与x轴的夹角。

对于图像中的特征点(x,y),将其他所有特征点与其进行上述计算

将theta(i)的值累加得到角度和累加值的直方图,检测直方图的局部峰值可得到经过该点的直线信息。这样检测峰值由二维变一维。遍历所有的点得到所有直线。映射计算量是很大。实际中,检测到一条直线后即将这条直线上的特征点去除。

随机霍夫变换

也是为了减少计算量发展来的。在图像空间中随机采N个点,计算(rho,theta),在参数空间累加投票,当最大值大于阈值时,判断为直线,并将该条直线上的点从图像中去除,循环执行,直到N个特征点在参数空间的最大值小于阈值,退出。

matlab仿真

用标准霍夫变换检测车道:

1.道路划线要清晰

2.周边建筑物,树木要尽量少

检测效果才好。

matlab代码如下:

clc,close    image=imread('IMG01070.jpg');     image=rgb2gray(image); image=double(image);subplot(121),imshow(image,[]);    title('Road Image'); %----------------先进性边缘检测----------------thresh=[0.02,0.2];  sigma=2;BW = edge(image,'canny',thresh,sigma);% f = imdilate(f,ones(2));%图像膨胀% subplot(121),imshow(BW,[]);    % title('Canny Edge Detection');     %-----------------得到参数空间------------------[H, theta, rho]= hough(BW,'RhoResolution', 0.5,'ThetaResolution',0.5);          peak=houghpeaks(H,5); %求极值点   lines=houghlines(BW,theta,rho,peak); %返回原图直线信息 subplot(122),imshow(BW,[]),title('Hough Transform Detect Result'),hold on    for k=1:length(lines)        xy=[lines(k).point1;lines(k).point2];        plot(xy(:,1),xy(:,2),'LineWidth',4);    end    

点这里可以跳转到人工智能网站

发表评论