霍夫变换——直线检测

时间:2022-05-07 09:45:27

霍夫变换(Hough)通过转换坐标系,将特定形状的检测映射到参数空间中,从而根据参数空间中的值来确定特定形状的相关信息。
  Hough变换的比较简单的应用例子有检测直线。

检测直线

  设空间中有若干点,我们要判断这些点是否能构成一条直线,即为直线检测。平面中直线的通用公式为xcos(θ)+ysin(θ)=ρxcos(θ)+ysin(θ)=ρ。常用的y=wx+by=wx+b公式,因为不能兼容y=by=b的情况,所以不能使用。对于某个点,其坐标是(xi,yi)(xi,yi),过该点的直线有无数条,这些直线统一表示为xicos(θ)+yisin(θ)=ρxicos(θ)+yisin(θ)=ρ,其中xi,yixi,yi是常量。反过来看,代表这些直线的公式,可以看做θθ为自变量,ρρ为因变量,xi,yixi,yi为常量参数的直线公式。这样,在x-y空间过(xi,yi)(xi,yi)的无数条直线,可以在θ−ρθ−ρ空间中用一条线代表。见下图:
霍夫变换——直线检测
 
 霍夫变换——直线检测
  上图是x-y空间,下图是θ−ρθ−ρ空间。其中红、绿、蓝三条线可以汇聚成一个点,说明这三条线对应的点,其在θ−ρθ−ρ空间中的直线参数是一样的。反过来就是说,穿过这三个点的无数直线中,有“三”条直线,其θ,ρθ,ρ值相同,这“三“条直线是一根直线,即这三个点可以共线。

通过量化霍夫参数空间为有限个值间隔等分或者累加格子。当霍夫变换算法开始,每个像素

坐标点P(x, y)被转换到(r, theta)的曲线点上面,累加到对应的格子数据点,当一个波峰出现

时候,说明有直线存在。

编程思路解析:

  1. 读取一幅带处理二值图像,最好背景为黑色。

  2. 取得源像素数据

  3. 根据直线的霍夫变换公式完成霍夫变换,预览霍夫空间结果

  4. 寻找最大霍夫值,设置阈值,反变换到图像RGB值空间(程序难点之一)

  5. 越界处理,显示霍夫变换处理以后的图像

对于0~70°范围内直线检测结果:
霍夫变换——直线检测霍夫变换——直线检测
霍夫变换——直线检测霍夫变换——直线检测

-70~0°范围内直线检测:
霍夫变换——直线检测霍夫变换——直线检测

matlab代码:

%% 霍夫曼变换 检测直线
clear all;
close all;

% I=imread('gantrycrane.png'); 
I=imread('3.jpg'); 
Ihsv=rgb2hsv(I); 
Iv=Ihsv(:,:,3);%提取v空间 
Ivl=Iv(:,:);%截取下半部 
Iedge=edge(Ivl,'sobel');%边沿检测 
% Iedge = imdilate(Iedge,ones(3));%图像膨胀
%新建窗口,绘图用 
figure;
imshow(uint8(255*Iedge));title('orignal picture')

%左方直线检测与绘制 
%得到霍夫空间 
[H1,T1,R1] = hough(Iedge,'Theta',0:0.1:75); 

figure;
       imshow(imadjust(mat2gray(H1)),'XData',T1,'YData',R1,...
              'InitialMagnification','fit');
       title('Limited theta range Hough transform of gantrycrane.png');
       xlabel('\theta'), ylabel('\rho');
       axis on, axis normal;

%求极值点
Peaks=houghpeaks(H1,8); 

hold;
for i=1:8
   plot(T1(Peaks(i,2)),R1(Peaks(i,1)),'ro','LineWidth',4); 
end

%得到线段信息 
lines=houghlines(Iedge,T1,R1,Peaks);

figure;
imshow(uint8(255*Iedge));title('after picture'); hold on
%绘制线段 
for k=1:length(lines) 
 xy=[lines(k).point1; lines(k).point2]; 
 plot(xy(:,1),xy(:,2),'LineWidth',4); 
end 
%右方直线检测与绘制 
[H2,T2,R2] = hough(Iedge,'Theta',-75:0.1:-20);
Peaks2=houghpeaks(H2,6); 
lines2=houghlines(Iedge,T2,R2,Peaks2);

figure;
       imshow(imadjust(mat2gray(H2)),'XData',T2,'YData',R2,...
              'InitialMagnification','fit');
       title('Limited theta range Hough transform of gantrycrane.png');
       xlabel('\theta'), ylabel('\rho');
       axis on, axis normal;

hold;
for i=1:6
   plot(T2(Peaks2(i,2)),R2(Peaks2(i,1)),'ro','LineWidth',4); 
end

figure;
imshow(uint8(255*Iedge));title('after picture 2'); hold on             
for k=1:length(lines2) 
 xy2=[lines2(k).point1;lines2(k).point2];
 plot(xy2(:,1),xy2(:,2),'LineWidth',4);
end