利用Hough变换检测线条

————————————2022-06 更新————————————

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
clc;
clear;

A=imread('test.png');

frame = A;
FrameBw = imbinarize(frame(:,:,1),0.6);
FrameBw8Delete = bwareaopen(FrameBw,2000,8); %自定义面积,删除小于该面积的连通区域
FrameBw8Delete = 1-bwareaopen(1-FrameBw8Delete,2000,8);


%--------------------------------------------------

BWe = edge(FrameBw8Delete,'canny');
[m,n]=size(BWe); % 获取图片原尺寸
BWe=rot90(BWe,1); % 逆时针旋转90度

[H,T,R] = hough(BWe,'Theta',-1:0.01:1);
P_Hough = houghpeaks(H,1,'threshold',ceil(0.3*max(H(:))));

Hough_T=T(P_Hough(:,2));
Hough_R=R(P_Hough(:,1));

P(1)=tand(Hough_T);
% P(2)=Hough_R*cosd(Hough_T); 注意区分弧度和角度
P(2)=Hough_R*cosd(Hough_T)-Hough_R*tand(Hough_T)*sind(Hough_T)-P(1)*n;

%--------------------------------------------------

frame=insertShape(frame,'Line',[1,P(1)*1+P(2),n,P(1)*n+P(2)],'color','blue','LineWidth',1);

imshow(frame);
% imwrite(frame,'testsave.jpg');


————————————2022-02 原文————————————

Hough变换的介绍参考文末链接

  1. 图片预处理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    clc;
    clear;

    A=imread('test.png');

    frame = A;
    FrameBw = im2bw(frame(:,:,1),0.6);
    FrameBw8Delete = bwareaopen(FrameBw,2000,8); %自定义面积,删除小于该面积的连通区域
    FrameBw8Delete = 1-bwareaopen(1-FrameBw8Delete,2000,8);
  1. 直线拟合

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     % 定义初始值
    LeftLine=768; %左侧边线长度
    y_map=zeros(1,LeftLineL);

    % 寻找边缘
    % 直接寻找最高点
    for X_Line=1:LeftLineL %1:numFrames
    y_map(X_Line)=max(find(FrameBw8Delete(:,X_Line)==1));
    end

    % 直接拟合
    % P=polyfit(1:LeftLineL,y_map,1);
    % 绘制HoughMap
    Hough_Map=zeros(2001,301);
    for Hough_j_X=1:LeftLineL
    Hough_In_X=Hough_j_X;
    Hough_In_Y=y_map(Hough_j_X);
    for Hough_i_X=1:300 % 1:100 映射415-512
    Float_X=Hough_i_X+300.0;
    Hough_K=(Hough_In_Y-Float_X)/Hough_In_X; %-0.1刿0.1 映射 1-2001
    print=floor((Hough_K+0.1)*1000);
    if (0<print)&&(print<2001)
    Hough_Map(print,Hough_i_X) =Hough_Map(print,Hough_i_X)+0.1;
    end
    end
    end

    %Hough投票
    h = fspecial('gaussian',5,5);
    out = imfilter(Hough_Map,h);
    %surf(out);
    Max_Hough=max(max(out));
    [x,y]=find(out(:,:)==Max_Hough);
    P(1)=x/1000-0.1;
    P(2)=y+300;

    %得到直线
    y=P(1)*x+P(2);
  1. 测试图像直接拟合结果

    -0.00935534897757482 448.724735848544

  1. Hough投票结果

    -0.0120000000000000 450


参考链接:

图像处理算法 - Hough变换_桂哥317的博客-CSDN博客_hough变换 (快照)

图像处理:Hough变换原理分析_无水先生的博客-CSDN博客_hough图像 (快照)

hough变换理解 原理 步骤_zqx951102的博客-CSDN博客_hough变换步骤

Hough 变换 - MATLAB hough - MathWorks 中国

基于 Hough 变换提取线段 - MATLAB houghlines - MathWorks 中国