天天看点

Hough变换检测直线

Hough变换检测直线

一幅图像是由一个个的像素组成的,有时候希望找出这些像素点中位于直线上的点所组成的点集。一种可行的方法是Hough变换,考虑一个点(x1,y1)和一条通过这个点的直线斜截式方程y1=a*x1 + b,通过点(x1, y1)的直线有无数条,然而如果将直线y1=a*x1 + b写成以a, b为参数的形式b =-a*x1 + y1,在(a, b)平面上,b = -a*x1 + y1就可以表示成一条斜率为-x1, 截距为y1的直线。也就是说(x, y)平面上的一个点对应着(a,b)平面上的一条直线,反之亦然。示例如下:(x, y)平面直线过点A(1,1),B(2,2)。点A(1,1)对应(a, b)平面的直线1, 点B对应直线2.

Hough变换检测直线

直线1,2相交于点(0,1),即a = 1, b = 0处,这在返回到(x, y)平面表示有两条直线他们的斜率均为a = 1,截距均为b = 0,也即(a, b)平面的重合点(0, 1)对应到(x, y)平面的两条直线重合为一条直线,这条直线就是直线AB。通过统计(a, b)平面上是否有重合点就可以判断对应的(x, y)平面是否有直线。在(a, b)平面某处的重合点的个数就表示对应的(x , y)平面上的直线通过点的个数。这个重合点数目的大小可以得出对应(x, y)平面共线直线的精度。

由于(a, b)平面的a, b 对应为(x, y)平面直线的斜率和截距,那么当(x, y)平面内的直线处于垂直或平行与x轴的状态时,a, b就有一个为无穷大,这就为直线检测带来了麻烦,我们不可能分配一个无穷大的矩阵来存放(a, b)平面的所有直线经过的像素点。解决这一难点的方案是使用直线的标准式:

Hough变换检测直线
Hough变换检测直线

对应方式与直线类似。对于直线垂直的情况和也不会出现无穷大。

导入图片利用上述方法检测直线:

Hough变换检测直线
<pre name="code" class="cpp"><pre name="code" class="plain">% hough transform detectlines in image
imag0 = imread('pic.jpg');
% imag = imag0(:,:,2);
imag = im2bw(imag0);
BW = imag;
figure;
imshow(imag);
BW = edge(imag,'canny');
% figure ; imshow(BW);
% Compute the Houghtransform of theimage using the hough function.
[H,theta,rho] = hough(BW);
% Findthe peaks in theHough transform matrix, H, usingthe houghpeaks function.
P = houghpeaks(H,10,'threshold',ceil(0.3*max(H(:))));
% Find lines in the imageusing the houghlines function.
lines =houghlines(BW,theta,rho,P,'FillGap',11,'MinLength',3)
% Create a plot thatsuperimposes the lineson the original image.
figure, imshow(imag0), hold on;
max_len = 0;
for k = 1:length(lines)
   xy = [lines(k).point1; lines(k).point2];
   plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','red');
 
   % Plotbeginnings and ends of lines
%   plot(xy(1,1),xy(1,2),'x','LineWidth',1,'Color','yellow');
%    plot(xy(2,1),xy(2,2),'x','LineWidth',1,'Color','green');
 
   %Determine the endpoints of the longest line segment
   len = norm(lines(k).point1 -lines(k).point2);
   if ( len > max_len)
      max_len = len;
      xy_long = xy;
   end
end
           

继续阅读