了解霍夫变换
Understanding Hough Transform
我正在尝试理解 MATLAB 的霍夫变换代码。
这张图有些东西我看清楚了,
binary_image
是 input_image
的单色版本。
hough_lines
是包含图像中检测到的线条的向量。我看到了,已经检测到四行了。
T
包含图像 (ϴ, ρ)
space 中的 thetas。
R
包含图像 (ϴ, ρ)
space 中的 rhos。
我有以下问题,
- 为什么在应用 Hough 变换之前旋转了图像?
H
中的条目代表什么?
- 为什么
H
(霍夫矩阵)的大小是 45x180?这个尺寸从哪里来的?
- 为什么
T
的大小是 1x180?这个尺寸从哪里来的?
- 为什么
R
的大小是 1x45?这个尺寸从哪里来的?
P
中的条目代表什么?他们是 (x, y)
还是 (ϴ, ρ)
?
29 162
29 165
28 170
21 5
29 158
- 为什么值5传入
houghpeaks()
?
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)
x
和 y
是图像中的点,通常它们是边缘点。 theta
是从原点画出的线与通过边缘点画出的线的交点所成的角度。 rho
将是从原点到以 theta
角通过 (x, y)
绘制的这条线的 垂直 距离。
请注意,方程可以产生位于 (x, y)
处的无穷多条线,因此通常将可能的角度总数分类或离散化为预定义的数量。默认情况下,MATLAB 假设有 180 个可能的角度,范围从 [-90, 90)
,采样因子为 1。因此 [-90, -89, -88, ... , 88, 89]
。你通常做的是对于每个边缘点,你搜索预定义的角度数,确定相应的 rho
是什么。之后,我们计算您看到每个 rho
和 theta
对的次数。这是从维基百科中提取的一个简单示例:
这里我们看到三个黑点沿着一条直线。理想情况下,霍夫变换应该确定这些黑点一起形成一条直线。为了让您了解计算,请查看 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
所以理想情况下,如果我们有沿直线的边缘点,我们应该看到 rho
和 theta
对,我们看到这对的次数相对较高。 这就是累加器矩阵的目的H
。行表示唯一的 rho
值,列表示唯一的 theta
值。
示例如下所示:
因此使用此矩阵中的示例,位于 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。此累加器矩阵告诉您 多少次 边缘点适合特定的 rho
和 theta
组合。因此,如果我们看到许多点映射到特定的 rho
和 theta
值,则很有可能在这里检测到一条由 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)
,其中 rows
和 cols
是图像的行和列。
对于 MATLAB 默认值,rho
的范围是从 -round(D)
到 round(D)
,步长为 1。因此,您的行和列都是 16,所以 D = sqrt(16^2 + 16^2) = 22.45
... 所以 D
的范围将从 -22
到 22
,因此这会产生 45 个唯一的 rho
值。请记住,theta
的默认分辨率从 [-90, 90)
(步长为 1)产生 180 个独特的角度值。这样,我们在累加器矩阵中有 45 行和 180 列,因此 H
是 45 x 180
.
Why is T
of size 1x180? Where does this size come from?
这是一个数组,告诉您霍夫变换中使用的所有角度。这应该是一个从 -90
到 89
的数组,步长为 1.
Why is R
of size 1x45? Where does this size come from?
这是一个数组,告诉您霍夫变换中使用的所有 rho
值。这应该是一个从 -22
到 22
的数组,步长为 1.
你应该从中得到的是 H
中的每个值决定了我们看到一对特定的 rho
和 theta
的次数,这样对于 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 (ϴ, ρ)
?
P
是 houghpeaks
函数的输出。基本上,这通过查找累加器矩阵中的峰值发生位置来确定可能的线是什么。这为您提供了 P
中存在峰值的实际物理位置。这些位置是:
29 162
29 165
28 170
21 5
29 158
每一行都为您提供了生成检测到的行所需的 rho
和 theta
参数的入口。具体来说,第一行的特征是rho = R(29)
和theta = T(162)
。第二行的特征是 rho = R(29)
和 theta = T(165)
等。为了回答你的问题,P
中的值既不是 (x, y)
也不是 (ρ, ϴ)
。它们代表 P
中的物理位置,其中交叉引用 R
和 T
,它将为您提供参数来表征图像中检测到的线条。
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(:)))
?
这背后的逻辑是,如果你想确定累加器矩阵中的峰值,你必须定义一个最小阈值来告诉你特定的 rho
和 theta
组合是否是被认为是有效的行。将此阈值设置得太低会报告很多错误行,而将此阈值设置得太高会错过很多行。他们决定在这里做的是找到累加器矩阵中最大的 bin 计数,取其中的 30%,取数学上限和累加器矩阵中任何大于此数量的值,这些将是候选行。
希望对您有所帮助!
我正在尝试理解 MATLAB 的霍夫变换代码。
这张图有些东西我看清楚了,
binary_image
是input_image
的单色版本。hough_lines
是包含图像中检测到的线条的向量。我看到了,已经检测到四行了。T
包含图像(ϴ, ρ)
space 中的 thetas。R
包含图像(ϴ, ρ)
space 中的 rhos。
我有以下问题,
- 为什么在应用 Hough 变换之前旋转了图像?
H
中的条目代表什么?- 为什么
H
(霍夫矩阵)的大小是 45x180?这个尺寸从哪里来的? - 为什么
T
的大小是 1x180?这个尺寸从哪里来的? - 为什么
R
的大小是 1x45?这个尺寸从哪里来的? P
中的条目代表什么?他们是(x, y)
还是(ϴ, ρ)
?29 162 29 165 28 170 21 5 29 158
- 为什么值5传入
houghpeaks()
? 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)
x
和 y
是图像中的点,通常它们是边缘点。 theta
是从原点画出的线与通过边缘点画出的线的交点所成的角度。 rho
将是从原点到以 theta
角通过 (x, y)
绘制的这条线的 垂直 距离。
请注意,方程可以产生位于 (x, y)
处的无穷多条线,因此通常将可能的角度总数分类或离散化为预定义的数量。默认情况下,MATLAB 假设有 180 个可能的角度,范围从 [-90, 90)
,采样因子为 1。因此 [-90, -89, -88, ... , 88, 89]
。你通常做的是对于每个边缘点,你搜索预定义的角度数,确定相应的 rho
是什么。之后,我们计算您看到每个 rho
和 theta
对的次数。这是从维基百科中提取的一个简单示例:
这里我们看到三个黑点沿着一条直线。理想情况下,霍夫变换应该确定这些黑点一起形成一条直线。为了让您了解计算,请查看 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
所以理想情况下,如果我们有沿直线的边缘点,我们应该看到 rho
和 theta
对,我们看到这对的次数相对较高。 这就是累加器矩阵的目的H
。行表示唯一的 rho
值,列表示唯一的 theta
值。
示例如下所示:
因此使用此矩阵中的示例,位于 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。此累加器矩阵告诉您 多少次 边缘点适合特定的 rho
和 theta
组合。因此,如果我们看到许多点映射到特定的 rho
和 theta
值,则很有可能在这里检测到一条由 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)
,其中 rows
和 cols
是图像的行和列。
对于 MATLAB 默认值,rho
的范围是从 -round(D)
到 round(D)
,步长为 1。因此,您的行和列都是 16,所以 D = sqrt(16^2 + 16^2) = 22.45
... 所以 D
的范围将从 -22
到 22
,因此这会产生 45 个唯一的 rho
值。请记住,theta
的默认分辨率从 [-90, 90)
(步长为 1)产生 180 个独特的角度值。这样,我们在累加器矩阵中有 45 行和 180 列,因此 H
是 45 x 180
.
Why is
T
of size 1x180? Where does this size come from?
这是一个数组,告诉您霍夫变换中使用的所有角度。这应该是一个从 -90
到 89
的数组,步长为 1.
Why is
R
of size 1x45? Where does this size come from?
这是一个数组,告诉您霍夫变换中使用的所有 rho
值。这应该是一个从 -22
到 22
的数组,步长为 1.
你应该从中得到的是 H
中的每个值决定了我们看到一对特定的 rho
和 theta
的次数,这样对于 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(ϴ, ρ)
?
P
是 houghpeaks
函数的输出。基本上,这通过查找累加器矩阵中的峰值发生位置来确定可能的线是什么。这为您提供了 P
中存在峰值的实际物理位置。这些位置是:
29 162
29 165
28 170
21 5
29 158
每一行都为您提供了生成检测到的行所需的 rho
和 theta
参数的入口。具体来说,第一行的特征是rho = R(29)
和theta = T(162)
。第二行的特征是 rho = R(29)
和 theta = T(165)
等。为了回答你的问题,P
中的值既不是 (x, y)
也不是 (ρ, ϴ)
。它们代表 P
中的物理位置,其中交叉引用 R
和 T
,它将为您提供参数来表征图像中检测到的线条。
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(:)))
?
这背后的逻辑是,如果你想确定累加器矩阵中的峰值,你必须定义一个最小阈值来告诉你特定的 rho
和 theta
组合是否是被认为是有效的行。将此阈值设置得太低会报告很多错误行,而将此阈值设置得太高会错过很多行。他们决定在这里做的是找到累加器矩阵中最大的 bin 计数,取其中的 30%,取数学上限和累加器矩阵中任何大于此数量的值,这些将是候选行。
希望对您有所帮助!