了解霍夫变换

Understanding Hough Transform

我正在尝试理解 MATLAB 的霍夫变换代码。

这张图有些东西我看清楚了,

  1. binary_imageinput_image 的单色版本。
  2. hough_lines 是包含图像中检测到的线条的向量。我看到了,已经检测到四行了。
  3. T 包含图像 (ϴ, ρ) space 中的 thetas。
  4. R 包含图像 (ϴ, ρ) space 中的 rhos。

我有以下问题,

  1. 为什么在应用 Hough 变换之前旋转了图像?
  2. H 中的条目代表什么?
  3. 为什么 H(霍夫矩阵)的大小是 45x180?这个尺寸从哪里来的?
  4. 为什么 T 的大小是 1x180?这个尺寸从哪里来的?
  5. 为什么 R 的大小是 1x45?这个尺寸从哪里来的?
  6. P 中的条目代表什么?他们是 (x, y) 还是 (ϴ, ρ)
    29 162
    29 165
    28 170
    21  5
    29 158
    
  7. 为什么值5传入houghpeaks()
  8. 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');

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

Why is the image rotated before applying Hough Transform?

我不相信这是 MATLAB 的 "official example"。 I just took a quick look at the documentation page for the function。我相信您是从我们无法访问的另一个网站上提取的。在任何情况下,通常在使用霍夫变换之前您都没有必要旋转图像。霍夫变换的目标是在图像中找到任何方向的线条。旋转它们不应影响结果。但是,如果我猜测旋转是作为先发制人的措施执行的,因为 "example image" 中的线很可能顺时针方向为 33 度角。执行反向旋转会使线条或多或少变直。

What do the entries in H represent?

H 就是所谓的 accumulator matrix。在我们了解 H 的目的是什么以及如何解释矩阵之前,您需要了解霍夫变换的工作原理。通过霍夫变换,我们首先对图像进行边缘检测。这是在您的案例中使用 Canny 边缘检测器完成的。如果你还记得霍夫变换,我们可以使用以下关系参数化一条线:

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 对的次数。这是从维基百科中提取的一个简单示例:

来源:Wikipedia: Hough Transform

这里我们看到三个黑点沿着一条直线。理想情况下,霍夫变换应该确定这些黑点一起形成一条直线。为了让您了解计算,请查看 30 度角的示例。前面查阅过,当我们延伸一条线,其中从原点到这条线的夹角是30度,通过每个点,我们找到从这条线到原点的垂直距离。

现在有趣的是,如果您看到每个点以 60 度显示的垂直距离,则该距离大致相同,约为 80 像素。看到这三个点中的每一个的 rhotheta 对是霍夫变换背后的驱动力。另外,上面公式的优点在于它会隐式地为您找到垂直距离。

霍夫变换的过程非常简单。假设我们有一个边缘检测图像 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 值。

示例如下所示:

来源:Google Patents

因此使用此矩阵中的示例,位于 theta 25 - 30 之间,rho 为 4 - 4.5,我们发现有 8 个边缘点的特征为给定此 rho, theta 范围对的一行。

请注意,rho 的范围也是无限多个值,因此您不仅需要限制您拥有的 rho 的范围,而且还必须离散化 rho 具有采样间隔。 MATLAB默认是1,所以如果你计算一个rho的值,必然会有浮点数,所以你去掉小数精度,确定最后的rho。 对于上面的示例,rho 分辨率为 0.5,这意味着如果您计算的 rho 值介于 2 到 2.5 之间,则它位于第一列。另请注意,theta 值以 5 的间隔进行分箱。传统上,您会使用 theta 采样间隔 1 计算霍夫变换,然后将分箱合并在一起。然而,对于 MATLAB 的默认值,bin 大小为 1。此累加器矩阵告诉您 多少次 边缘点适合特定的 rhotheta 组合。因此,如果我们看到许多点映射到特定的 rhotheta 值,则很有可能在这里检测到一条由 rho = x*cos(theta) + y*sin(theta) 定义的线。

Why is H(Hough Matrix) of size 45x180? Where does this size come from?

这是前一点的结果。请注意,我们期望从原点到图像中任何点的最大距离以图像的对角线为界。这是有道理的,因为从左上角到右下角,或从左下角到右上角会给你图像中预期的最大距离。通常,这定义为 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.

Why is T of size 1x180? Where does this size come from?

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

Why is R of size 1x45? Where does this size come from?

这是一个数组,告诉您霍夫变换中使用的所有 rho 值。这应该是一个从 -2222 的数组,步长为 1.


你应该从中得到的是 H 中的每个值决定了我们看到一对特定的 rhotheta 的次数,这样对于 R(i) <= rho < R(i + 1)T(j) <= theta < T(j + 1),其中 i 跨越 1 到 44,j 跨越 1 到 179,这决定了我们在 [=19= 的特定范围内看到边缘点的次数] 和 theta 之前定义。


What do the entries in P represent? Are they (x, y) or (ϴ, ρ)?

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,它将为您提供参数来表征图像中检测到的线条。

Why is the value 5 passed into houghpeaks()?

houghpeaks return 中额外的 5 是您希望检测到的理想行数。我们可以看到P是5行,对应5行。如果您找不到 5 行,那么 MATLAB 将 return 尽可能多的行。

What is the logic behind ceil(0.3*max(H(:)))?

这背后的逻辑是,如果你想确定累加器矩阵中的峰值,你必须定义一个最小阈值来告诉你特定的 rhotheta 组合是否是被认为是有效的行。将此阈值设置得太低会报告很多错误行,而将此阈值设置得太高会错过很多行。他们决定在这里做的是找到累加器矩阵中最大的 bin 计数,取其中的 30%,取数学上限和累加器矩阵中任何大于此数量的值,这些将是候选行。


希望对您有所帮助!