在http://blog.csdn.net/piaoxuezhong/article/details/58587907中,介绍的基于霍夫变换检测直线的原理,并给出了opencv算法实现,本篇再次使用霍夫变换在matlab中检测图像中的直线。
具体步骤:
1. 彩色图像->灰度图
2. 去噪(高斯核)
3. 边缘提取(梯度算子、拉普拉斯算子、canny、sobel)
4. 二值化(判断此处是否为边缘点,就看灰度值==255)
5. 映射到霍夫空间(准备两个容器,一个用来展示hough-space概况,一个数组hough-space用来储存voting的值,因为投票过程往往有某个极大值超过阈值,多达几千,不能直接用灰度图来记录投票信息)
6. 取局部极大值,设定阈值,过滤干扰直线
7. 绘制直线、标定角点
Matlab实现:
1. 转灰度: Img=rgb2gray(Img)
2. 高斯去噪
3. sobel算子提取边界
4. 二值化(应该设置一个阈值,对不同的图,不同的阈值,以便完整显示边界)
在高斯去噪和边界提取之后都需要二值化
5. 映射到霍夫空间先在原图构造一个x-y平面,一一对应各点的直线方程计算O(0,0)为事实上的原点,O‘(width/2,height/2)为构造平面的原点,然后构造一个hough-space,其中纵轴表示theta的刻度,theta取值0~PI,分成500个刻度,r的最大值为: max_length=sqrt((width/2)^2 + (height/2)^2),又r存在正负值,故而hough-space的横轴需要2*max_length。
%% 图像中直线检测
function I_out=HoughLineDetect(Img,thresholdValue)
%input:
% img:输入图像;
% thresholdValue:hough阈值;
%output:
% I_out:检测直线结果,二值图像;
if ~exist( 'thresholdValue', 'var' )
thresholdValue = 150;
end
if length(size(Img))>2
I_gray=rgb2gray(Img); %如果输入图像是彩色图,需要转灰度图
else
I_gray=Img;
end
[x,y]=size(I_gray); %图像大小
BW=edge(I_gray); %计算图像边缘
rho_max=floor(sqrt(x^2+y^2))+1; %由图像坐标算出ρ最大值,结果取整并加1,作为极坐标系最大值
AccArray=zeros(rho_max,180); %初始化极坐标系的数组
Theta=0:pi/180:pi; %定义θ数组,范围从0-180度
for n=1:x,
for m=1:y
if BW(n,m)==1
for k=1:180
%hough变换方程求ρ值
rho=(m*cos(Theta(k)))+(n*sin(Theta(k)));
%为了防止ρ值出现负数,将ρ值与ρ最大值的和的一半作为ρ的坐标值
rho_int=round(rho/2+rho_max/2);
%在极坐标中标识点,相同点累加
AccArray(rho_int,k)=AccArray(rho_int,k)+1;
end
end
end
end
%利用hough变换提取直线
K=1; %存储数组计数器
% thresholdValue=200; %设定直线的最小值。
for rho=1:rho_max %在hough变换后的数组中搜索
for theta=1:180
if AccArray(rho,theta)>=thresholdValue
case_accarray_rho(K)=rho;
case_accarray_theta(K)=theta;
K=K+1;
end
end
end
%将直线提取出来,输出图像数组I_out
I_out=zeros(x,y);
for n=1:x,
for m=1:y
if BW(n,m)==1
for k=1:180
rho=(m*cos(Theta(k)))+(n*sin(Theta(k)));
rho_int=round(rho/2+rho_max/2);
for a=1:K-1
if rho_int==case_accarray_rho(a)&&k==case_accarray_theta(a)
I_out(n,m)=BW(n,m);
end
end
end
end
end
end
figure,imshow(Img);title('输入图像');
% figure,imshow(BW);title('edge处理后的边界图');
figure,imshow(I_out);title('Hough变换检测出的直线');
end
测试文件及结果:
%% 图像直线检测测试程序
clc,clear all,close all;
imgPath='D:\test_image\exposure_image\';
img=imread(fullfile(imgPath,'4.jpg'));
I_out=HoughLineDetect(img,60);
程序里,输入参数除了图像,还一个是投票阈值,为了可以方便修改,如果不带这个参数,程序里默认是150。
参考:
http://blog.csdn.net/piaoxuezhong/article/details/58587907
https://www.cnblogs.com/cheermyang/p/5348820.html