Hough 变换提取直线
一、实验目标
实现用 Hough 变换检测直线的算法
二、实验内容
1、读入图像
选取有较多直线及部分曲线以作对比的图像作为实验素材,这里我们必须使
用彩色图像(有些看似灰度图像的实际属性也是彩色图像),原因下面有详解。
2、检测图像边缘
如果一个像素落在图像中某一个物体的边界上,那么它的邻域将成为一个灰
度级变化的带。对这种变化最有用的两个特征是灰度的变化率和方向,他们分别
用梯度向量的幅度和方向来表示。
边缘检测算子检查每个像素的邻域并对灰度变化率进行量化,通常也包括方
向的确定。有若干种算子可以使用,大多数是基于方向导数掩模求卷积的方法。
如 Roberts 算子,Sobel 算子 ,Prewitt 算子,Log 算子等。这里采用 Log 算子
提取图像边缘,再用均值滤波去除边缘图像噪声。
3、实现 Houg 变换,检测出图像中的直线
Hough 变换是一种利用图像的全局特征将特定形状的边缘连接起来,形成连
续平滑边缘的一种方法。它通过将源图像上的点影射到用于累加的参数空间,实
现对已知解析式曲线的识别。
这里先对边缘图像进行二值化处理,然后再用 hough 变换提取直线,最后用
红色标记之。因为处理过程中需使用灰度图像,但最后无法给灰度图像赋颜色(会
出错或效果不好),只能给彩色图像赋颜色,故最初输入时请使用彩色图像。
4、Matlab 代码如下:
%保留彩色原图
f=imread('3.png');%读入彩色图像,注意不能使用灰度图像
o=f;
f=rgb2gray(f);%将彩色图像转换为灰度图像,
f=im2double(f);
figure();
subplot(2,2,1);imshow(o);title('原图');
[m,n]=size(f);%得到图像矩阵行数 m,列数 n
for i=3:m-2
for j=3:n-2%处理领域较大,所以从图像(3,3)开始,在(m-2,n-2)结束
l(i,j)=-f(i-2,j)-f(i-1,j-1)-2*f(i-1,j)-f(i-1,j+1)-f(i,j-2)
-2*f(i,j-1)+16*f(i,j)-2*f(i,j+1)-f(i,j+2)-f(i+1,j-1)-2*f(
i+1,j)-f(i+1,j+1)-f(i+2,j);%LoG 算子
end
end
subplot(2,2,2);imshow(l);title('LoG 算子提取图像边缘');
[m,n]=size(l);
for i=2:m-1
for j=2:n-1
y(i,j)=l(i-1,j-1)+l(i-1,j)+l(i-1,j+1)+l(i,j-1)+l(i,j)+l(i,j+1)+l(
i+1,j-1)+l(i+1,j)+l(i+1,j+1);
y(i,j)=y(i,j)/9;
%LoG 算子提取边缘后,对结果进行均值滤波以去除噪
声,为下一步 hough 变换提取直线作准备
end
end
subplot(2,2,3);imshow(y);title('均值滤波器处理后')
q=im2uint8(y);
[m,n]=size(q);
for i=1:m
for j=1:n
if q(i,j)>80;
%设置二值化的阈值为 80
q(i,j)=255; %对图像进行二值化处理,使图像边缘更加突出清晰
q(i,j)=0;
else
end
end
end
subplot(2,2,4);imshow(q);title('二值化处理后');
%Hough 变换检测直线,使用(a,p)参数空间,a∈[0,180],p∈[0,2d]
a=180; %角度的值为 0 到 180 度
d=round(sqrt(m^2+n^2)); %图像对角线长度为 p 的最大值
s=zeros(a,2*d); %存储每个(a,p)个数
z=cell(a,2*d);
for i=1:m
%用元胞存储每个被检测的点的坐标
for j=1:n%遍历图像每个点
if(q(i,j)==255)%只检测图像边缘的白点,其余点不检测
for k=1:a
p = round(i*cos(pi*k/180)+j*sin(pi*k/180));%对每个点从
1 到 180 度遍历一遍,取得经过该点的所有直线的 p 值(取整)
if(p > 0)%若 p 大于 0,则将点存储在(d,2d)空间
s(k,d+p)=s(k,d+p)+1;%(a,p)相应的累加器单元加一
z{k,d+p}=[z{k,d+p},[i,j]'];%存储点坐标
else
end
ap=abs(p)+1;%若 p 小于 0,则将点存储在(0,d)空间
s(k,ap)=s(k,ap)+1;%(a,p)相应的累加器单元加一
z{k,ap}=[z{k,ap},[i,j]'];%存储点坐标
end
end
end
end
for i=1:a
for j=1:d*2 %检查每个累加器单元中存储数量
if(s(i,j) >70) %将提取直线的阈值设为 70
lp=z{i,j};%提取对应点坐标
for k=1:s(i,j)%对满足阈值条件的累加器单元中(a,p)对应的所
有点进行操作
o(lp(1,k),lp(2,k),1)=255; %每个点 R 分量=255,G 分量=0,
B 分量=0
o(lp(1,k),lp(2,k),2)=0;
o(lp(1,k),lp(2,k),3)=0;
%结果为在原图上对满足阈值要求
的直线上的点赋红色
end
end
end
end
figure,imshow(o);title('hough 变换提取直线');
5、实验结果
附:两个参数的调节
1.二值化图像的细节多少可以通过对二值化的阈值调节来控制,阈值越大,细
节越少。
2.最后提取直线的阈值越小,可被赋红色的直线的越多,但更多的无关细节也
可能被赋红色;阈值越大,可被赋红色的直线的越少,同时无关细节也会减少。
通过对这个两个参数的适当调节可使提取直线的效果更好。