在MATLAB中使用Hough变换进行线条检测
Hough变换是一种在图像中分离出特定形状的算法。这些所需的特征应该以一个给定的参数形式来指定。这种算法被广泛用于检测规则的曲线。这些曲线是诸如直线、曲线、椭圆等。然而,Hough变换的一般应用不可能达到简单的分析特征描述。例如,线条检测是一个重要的特征,它有助于分析两个物体。它可以给出两个物体之间更重要的关系。
本教程将研究我们如何在Matlab中使用hough变换。此外,我们将了解线条检测的重要性以及如何使用Matlab代码进行线条检测。
前提条件
要学习本教程,你需要:
- 安装[MATLAB]。
- 对[MATLAB]基础知识的正确理解。
标准哈夫变换
我们可以用这个变换来测量一条线的长度。例如,假设需要检测图像中的一条线,它可以做到这一点。

线条的一般表达式是y=mx+c。这意味着你可以把一条线映射成一个坐标对,m, c 。然而,垂直线有一个问题,因为斜率值是无界的。在这种情况下,Hough变换使用不同的参数表示。参数是θ和ρ。这里, θ 是轴和连接该最接近点的原点线之间的角度。ρ对应于从原点到直线上最近的点的距离。

从概念上讲,Hough变换是将X和Y的图像坐标映射到参数坐标θ,ρ。
使用hough变换来检测一条线
假设一幅图像由一条线组成,如下图所示。

一条线是由多个点组成的。同样地,多条线也可以通过同一个点。我们在Hough变换平面上将多条线可视化,参数 θ 在x轴上,在y轴上。图像上的每一个点都被转换为正弦波。正弦波是一个正弦波形状的信号。

它是有意义的,因为许多线可能会通过图像平面上的一个特定点。它在Hough平面上转化为一个正弦波。如果这些线中有两条或更多的线在图像平面上重合形成一条线,它们将在hough变换平面上相交。

请注意,相交的正弦波的数量决定了一条线的强度。这就是Hough变换的工作原理。
在Matlab中使用hough变换提取线段
假设你有一个带线的图像,你想提取线段;算法是。
- 使用hough函数创建一个hough变换矩阵。
- 找到Hough变换矩阵函数中的峰值。这些峰值对应于参数平面中的交点。每个峰都是一条检测到的线。
- 使用Hough变换函数将峰值映射回图像平面。然后你再提取线段。
现在,我们用一个简单的图像来实现上述算法。我们有两个二进制图像,如下图所示。

这些图像是二进制的,因为Hough变换函数在二进制图像上工作。注意,可以在Matlab中绘制这两幅图像。我们将首先绘制这两幅图像并提取线段。我们首先绘制带有两个点的图像,并从中提取线段,然后再去绘制第二个图像。
为了绘制带有两个点的图像,我们将执行下面的代码。
close all
clear
clc
%% 1. Image with two dots
a = zeros(50);
a(20,20) = 1; a(40,10) = 1;
figure;
subplot(2,2,1)
imshow(a)
title('Image with 2 dots')
Close all 用来关闭所有打开的数字, ,并清除命令窗口。然后我们用 ,制作一个尺寸为50x50的零点矩阵。 和 是放置点的位置。 创建一个图形窗口。然后我们使用 来查看输出。最后,使用 函数,我们为我们的输出创建一个子图。 创建一个 轴,该图被放置在位置 。clc zero(50) a(20, 20) a(40, 10) Figure imshow() subplot() subplot(m,n,p) MxN p
我们使用hough() 函数来计算hough矩阵。这个函数将二进制图像作为输入。这个函数给出了三个输出,即变换矩阵(H)、θ(T)和rho(R)。之后,我们使用实用函数houghMatViz() ,将输出结果可视化,如下图所示。
[H, T, R] = hough(a);
subplot(2, 2, 2)
houghMatViz(H, T, R)
让我们看一下这个实用函数的内容。记住,这个函数应该在一个不同的脚本中,然后我们再调用它。
function houghMatViz(H,T,R)
Hgray = mat2gray(H); % Converting hough matrix(H) into grayscale image.
Hgray = imadjust(Hgray); % Enhancing the brightness
imshow(Hgray,'XData',T,'YData',R);
hold on
axis on % turning on the axis.
axis normal
colormap(hot);title('Hough Transform'); % Giving colormap to the image.
xlabel('\theta') % add x-y labels
ylabel('\rho');
这个实用函数使用mat2gray() 函数将hough矩阵转换为灰度图像。然后,使用imadjust()function. Finally, this function takes the grayscale image as the argument. Theimshow()function displays the output depending on theXDataand theYData`调整灰度图像的亮度。
当我们执行这段代码时,我们得到两个正弦波,对应于图像中的两个点,如下图所示。

我们使用houghpeaks() 函数来寻找峰值。使用这个函数,你可以提供需要返回的峰值数量作为输出。如果你没有提供的话,输出将是最高的峰。
hPeaks = houghpeaks(H);
因为我们没有指定峰的数量,所以输出的是最大的峰。要看到这一点,在命令窗口中执行hpeaks 。我们可以在H 矩阵中找到峰值出现的位置。它是通过索引theta(T)、Rho(R)数组和像素位置来完成的,并绘制输出结果,如下所示。
x = T(hPeaks(:,2)); %indexing the theta(T) array
y = R(hPeaks(:,1)); %Indexing the rho(R) array
plot(x,y,'gs')
输出结果是。

绿色方块是峰值位置。峰值位置是穿过两个图像点的线。现在,我们将把同样的逻辑应用于第二幅图像。这里唯一的区别是,我们提取线段来重新绘制检测到的线条。让我们首先绘制线段。
b = eye(150);
subplot(2,2,3)
imshow(b)
title('Image with a line')
在这里,我们使用函数eye() ,给出一个MxN矩阵,其中主对角线上有1,其他部分有0。当我们使用这个函数时,我们得到如下图所示的图。

在图像中,有许多正弦波。这些正弦波中的每一个都对应于一条线上的一个点。最后一步是将峰值映射回图像平面并提取线段。这可以用houghlines() 函数来完成。这个函数将原始图像作为图像参考的输入,一个T、R值的数组,以及必须被标记回图像平面的峰值作为参数。
hlines = houghlines(b, T, R, hPeaks);
使用这些hline 值,我们可以在原始图像上重新绘制检测到的线条。这有助于我们看到检测是否成功。要做到这一点,我们使用下面的代码。
xy = [hlines.point1; hlines.point2];
figure;
imshow(b)
hold on
plot(xy(:,1), xy(:,2), 'g--', 'Linewidth', 5)
title('Detected line')
这里,我们使用hlines 结构来创建两个点,即hlines.point1 和hlines.point2 。在原始图像上,我们用不同的线型(-)、颜色(g)和线宽(5)来绘制这些点。它给出了下面的图。

我们在图中看到的是原始线,虚线代表检测到的线。现在使用这种方法,我们可以从图像中提取线条。
总结
Hough变换形成了一种算法,使得检测图像中的线条变得容易。同时,这种算法也可以用来检测视频中的线条。这是因为视频是视频帧的组合。视频帧是一个部分的图像部分。这意味着我们可以用图像来训练算法,然后在视频中实现它。这使得它在机器人领域广泛适用。