理解霍夫变换

3

我正在尝试理解MATLAB用于Hough变换的代码。

enter image description here

这张图片中有一些我已经明白的内容:

  1. binary_imageinput_image 的单色版本。
  2. hough_lines 是包含图像中检测到的直线的向量。我看到已检测到四条直线。
  3. T 包含图像在 (ϴ, ρ) 空间中的θ值。
  4. R 包含图像在 (ϴ, ρ) 空间中的ρ值。

我有以下问题:

  1. Why is the image rotated before applying Hough Transform?
  2. What do the entries in H represent?
  3. Why is H(Hough Matrix) of size 45x180? Where does this size come from?
  4. Why is T of size 1x180? Where does this size come from?
  5. Why is R of size 1x45? Where does this size come from?
  6. What do the entries in P represent? Are they (x, y) or (ϴ, ρ) ?
    29 162
    29 165
    28 170
    21  5
    29 158
    
  7. Why is the value 5 passed into houghpeaks()?
  8. What is the logic behind ceil(0.3*max(H(:)))?

相关源代码

%   Read image into workspace.
input_image  = imread('Untitled.bmp');

%Rotate the image.
rotated_image = imrotate(input_image,33,'crop');

% convert rgb to grascale
rotated_image = rgb2gray(rotated_image);

%Create a binary image.
binary_image = edge(rotated_image,'canny');

%Create the Hough transform using the binary image.
[H,T,R] = hough(binary_image);

%Find peaks in the Hough transform of the image.
P  = houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));

%Find lines
hough_lines = houghlines(binary_image,T,R,P,'FillGap',5,'MinLength',7);    

% Plot the detected lines
figure, imshow(rotated_image), hold on
max_len = 0;

for k = 1:length(hough_lines)
   xy = [hough_lines(k).point1; hough_lines(k).point2];
   plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');

   % Plot beginnings and ends of lines
   plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
   plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');

   % Determine the endpoints of the longest line segment
   len = norm(hough_lines(k).point1 - hough_lines(k).point2);
   if ( len > max_len)
      max_len = len;
      xy_long = xy;
   end
end

% Highlight the longest line segment by coloring it cyan.
plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','cyan');
1个回答

10
这些是一些好问题。以下是我的回答:

为什么在应用霍夫变换之前要旋转图像?

我不认为这是MATLAB的“官方示例”。我只是快速查看了该函数的文档页面。我认为您从我们无法访问的其他网站上提取了此代码。总的来说,在使用霍夫变换之前旋转图像并不是必要的。霍夫变换的目标是在任何方向上找到图像中的直线。旋转它们不应该影响结果。但是,如果我要猜测,旋转是作为预防性措施执行的,因为“示例图像”中的线条很可能以顺时针33度的角度定位。反向旋转会使这些线条更加直或更少弯曲。

H 中的条目代表什么?

H是所谓的累加器矩阵。在了解H的目的和如何解释该矩阵之前,您需要了解Hough变换的工作原理。使用Hough变换时,我们首先对图像进行边缘检测。在您的情况下,这是使用Canny边缘检测器完成的。如果您回忆一下Hough变换,我们可以使用以下关系将线条参数化:

rho = x*cos(theta) + y*sin(theta)

xy是图像中的点,通常它们是边缘点。theta是从原点出发的一条线与通过边缘点的线相交所形成的角度。rho是从原点到在角度theta处通过(x, y)的线的垂直距离

请注意,该方程可以产生无数条位于(x, y)的直线,因此通常将可能的角度总数分组或离散化为预定义数量。MATLAB默认假定有180个可能的角度,范围从[-90, 90),采样因子为1。因此为[-90, -89, -88, ..., 88, 89]。通常情况下,对于每个边缘点,您会搜索预定义数量的角度,确定相应的rho。之后,我们计算每个rhotheta对出现的次数。以下是从维基百科摘录的一个快速示例:

来源:霍夫变换-维基百科

在这里,我们看到三个黑点沿着一条直线。理想情况下,霍夫变换应该确定这些黑点共同形成一条直线。为了让您了解计算过程,请看以下30度的示例。回顾一下之前的内容,当我们通过每个点延伸一个角度与原点到该直线所成的角度为30度的直线时,我们找到了从这条直线到原点的垂直距离。

现在有趣的是,如果您看到60度的垂直距离对于每个点都是大约80个像素左右,那么这对于每个点的rho和theta是霍夫变换的驱动力。此外,上述公式的好处是它会隐含地为您找到垂直距离。

霍夫变换的过程非常简单。假设我们有一个边缘检测图像I和一组角度theta:

For each point (x, y) in the image:
    For each angle A in the angles theta:
        Substitute theta into: rho = x*cos(theta) + y*sin(theta)
        Solve for rho to find the perpendicular distance
        Remember this rho and theta and count up the number of times you see this by 1

理想情况下,如果我们有遵循一条直线的边缘点,我们应该能够看到一个 rhotheta 的组合,其中这个组合出现的次数相对较高。这就是累加器矩阵 H 的目的。每行代表唯一的 rho 值,每列代表唯一的 theta 值。
下面是一个示例:

enter image description here

来源:Google专利

因此,以矩阵中的一个示例为例,在theta为25-30、rho为4-4.5之间,我们发现有8个边缘点会被描述为一条线,给定这个rho, theta范围对。

请注意,rho 的范围也是无限多个值,因此您不仅需要限制您拥有的rho 范围,还需要用采样间隔离散化rho。MATLAB中的默认值为1。因此,如果您计算了一个rho 值,则它将不可避免地具有浮点值,因此您需要删除小数精度以确定最终的rho。对于上述示例,rho 分辨率为0.5,这意味着例如,如果您计算出介于2到2.5之间的rho 值,则它位于第一列。还要注意,theta 值按照5的间隔进行分组。传统上,您会使用theta 采样间隔为1来计算Hough变换,然后合并箱子。但是对于MATLAB的默认值,箱子大小为1。此累加器矩阵告诉您边缘点适合特定rhotheta 组合的次数。因此,如果我们看到许多映射到特定rhotheta 值的点,这是检测到线条的巨大潜力,由rho = x*cos(theta) + y*sin(theta)定义。
为什么H(霍夫矩阵)的大小是45x180?这个大小是从哪里来的?
这是前面一点的结果。请注意,我们期望从原点到图像中任何点的最大距离受图像对角线的限制。这很有道理,因为从左上角到右下角或者从左下角到右上角会给你预期图像中最大的距离。通常情况下,这被定义为D = sqrt(rows^2 + cols^2),其中rowscols是图像的行和列。
对于MATLAB默认值,rho的范围跨越了从-round(D)round(D)的步长为1的范围。因此,你的行和列都是16,所以D = sqrt(16^2 + 16^2) = 22.45...因此D范围将从-2222,因此会产生45个唯一的rho值。请记住,默认分辨率theta的范围从[-90, 90)(步长为1)开始,导致有180个唯一的角度值。根据这个,我们在累加器矩阵中有45行和180列,因此H45 x 180

为什么T的大小为1x180?这个尺寸来自哪里?

这是一个告诉你霍夫变换中使用的所有角度的数组。这应该是一个从-9089的步长为1的数组。

这是一个数组,告诉你在Hough变换中使用的所有rho值。它应该是一个从-22到22步长为1的数组,大小为1x45。
你需要明白的是,H 中的每个值都代表我们观察到特定的 rhotheta 对出现的次数。对于 R(i) <= rho < R(i + 1) 以及 T(j) <= theta < T(j + 1),其中 i 的范围从 1 到 44,j 的范围从 1 到 179,在先前定义的特定 rhotheta 范围内,这决定了我们观察到边缘点的次数。请注意,保留 HTML 标签。

P 中的条目代表什么?它们是 (x, y) 还是 (ϴ, ρ)

Phoughpeaks 函数的输出。基本上,这通过查找累加器矩阵中发生峰值的位置来确定可能的直线。这给出了实际物理位置,在 P 中有一个峰值。这些位置是:


29 162
29 165
28 170
21  5
29 158

每一行都给出了生成检测到的直线所需的rhotheta参数的入口。具体来说,第一行的特征是rho = R(29)theta = T(162)。第二行的特征是rho = R(29)theta = T(165)等等。回答您的问题,P中的值既不是(x, y)也不是(ρ, ϴ)。它们表示在P中的物理位置,在交叉引用RT时,可以得到表征图像中检测到的直线的参数。

为什么将值5传递给houghpeaks()

houghpeaks中的额外5返回您想要理想地检测到的总线数。我们可以看到P有5行,对应于5条直线。如果找不到5条线,则MATLAB将返回尽可能多的线。
这里的逻辑是,如果想要确定累加器矩阵中的峰值,必须定义一个最小阈值,以告诉您特定的rho和theta组合是否被视为有效线。将此阈值设置得太低会报告许多错误的线条,将此阈值设置得太高则会错过许多线条。在这里他们决定找到累加器矩阵中最大的bin计数,取其30%,取数学上的ceiling,累加器矩阵中任何大于此数量的值都将成为候选线。
希望这有所帮助!

我不认为这是MATLAB的“官方示例”,而是来自Mathworks的三个不同示例的组合。请参阅hough()houghpeaks()houghlines() - user366312
啊,那就说得通了。谢谢! - rayryeng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接