使用hough_line后关于hough_line_peaks的解释
Explanation about hough_line_peaks after using hough_line
谁能解释一下为什么在使用 h,theta,d = hough_line(image)
检测图像中的角度后,我们是否必须使用此 for 循环 for _, a, d in zip(*hough_line_peaks(h, theta, d)):
angle.append(a) #angle is a list
将角度添加到列表中?
由于 hough_line(image)
会将角度存储在 theta 变量中,为什么我们不能使用它来检索角度并将它们添加到列表中?
这是检测图像中线条角度的代码片段:
image = imread(file_name)
image = np.mean(image, axis=2)
h, theta, d = hough_line(image)
angle = []
for _, a, d in zip(*hough_line_peaks(h, theta, d)):
angle.append(a)
angle = [a * 180 / np.pi for a in angle]
所以这里发生的事情如下:
- 使用
hough_lines
检测图像上的所有线条。
- 这个 returns 累加器值、角度(以弧度为单位)和与原点的距离,假设 Hough space 中的 1000 个峰被识别为线。
- select 只检测所有检测到的线中最突出的线
- 与原点的距离至少为 9 "resolution" 步的那些峰与另一个相似的峰
- theta 坐标与另一个相似的峰 "resolution" 步距至少 10 角的那些峰
- 整个Hough中累加器计数大于max_count/2的space
- 这个选择可以说是原始 1000 行中的 200 行更有可能是图像中的实际行。
- 这实际上是对所有 returned
hough_lines
的筛选器,它会挑选出最有可能是行的内容。因此,您还可以获得累加器值、角度(以弧度为单位)以及与原点的距离。
- 然后你将从
hough_line_peaks
得到的所有角度复制到一个名为 a
的新 list
- 然后您使用另一个
for
循环遍历 a 并创建一个名为 angle
的新列表,您在其中存储从 a
转换为 degrees
[ 的值=76=]
如您所见,可能还有改进的余地。首先,无需复制整个角度列表。其次,你实际上造成了更多的伤害,因为现在你不能使用 numpy 给你的矢量化操作。从 hough_line_peaks
编辑的数组 return 是一个 numpy ndarray
,你可以直接将其相乘。
import skimage
image = skimage.io.imread(file_name)
image = np.mean(image, axis=2)
h, theta, d = skimage.transform.hough_line(image)
bestH, bestTheta, bestD = skimage.transform.hough_line_peaks(h, theta, d)
angle = bestTheta * (180/np.pi)
应该会得到相同的结果,而且可能会更快一些。整行 zip(*hough_line_peaks(h, theta, d))
应该始终值得怀疑,因为 *
被称为 "unpacking" 运算符。因此,给定一个元组、列表或任何其他可迭代对象 (a, b, c)
,解包运算符将可迭代对象 *(a, b, c) --> a, b, c
解包,然后再次压缩它们只是将它们再次打包 *(a, b, c) --> a, b, c --> (a, b, c)
。这些结构应该总是有点可疑。 for 循环 for _, a, b in...
中的下划线只是将该值作为无名丢弃。最后的 [ a for a in...]
构造称为列表推导式,它的工作方式与 for
循环完全相同,但只是语法糖,可在可能的情况下使内容更具可读性。
编辑
回答评论中的额外问题。让我们说:
>> import numpy as np
>>> a = np.array([[1, 2], [3, 4]])
>>> a
array([[1, 2],
[3, 4]])
>>> a.mean(axis=0)
array([2., 3.])
>>> a.mean(axis=1)
array([1.5, 3.5])
所以轴 0 上的 mean
正在做 (1+3)/2=2
和 (2+4)/2=3
- 因此有效 axis=0
是跨越 a
的垂直切片。 axis=1
是横跨 a
的水平切片,因此 (1+2)/2=1.5
和 (3+4)/2=3.5
。对于具有附录的任何更大维度的元素矩阵也是如此,您只有更多维度。所以对于 2D 矩阵,它的垂直+水平对于 3D 它将是垂直+水平+深度。所以轴 2 在 "depth" 上求和。
为什么这是必要的,因为 hough_lines
只能处理强度数据。它不理解颜色。但在彩色图像中,每个像素实际上是 3 个数字 (r, b, g)
,代表红色、蓝色和绿色通道强度。这些强度的混合最终会在显示器上产生颜色。因此,mean(axis=2)
行指示 numpy 获取表示图像的 3D 矩阵,并向您 return 提供 2D 矩阵,其中每个像素强度值已被 3 种颜色强度值的平均值所取代。
所以彩色图像:
index 1 2 ....
___________________________________
1 | [1, 2, 3] [4, 5, 6] ...
2 | [7, 8, 9] . ...
. | . .
. | . .
. | . .
变成灰度图:
index 1 2
______________________________
1 | 2 5 ...
2 | 8 . ...
3 | . .
| . .
| . .
|
谁能解释一下为什么在使用 h,theta,d = hough_line(image)
检测图像中的角度后,我们是否必须使用此 for 循环 for _, a, d in zip(*hough_line_peaks(h, theta, d)):
angle.append(a) #angle is a list
将角度添加到列表中?
由于 hough_line(image)
会将角度存储在 theta 变量中,为什么我们不能使用它来检索角度并将它们添加到列表中?
这是检测图像中线条角度的代码片段:
image = imread(file_name)
image = np.mean(image, axis=2)
h, theta, d = hough_line(image)
angle = []
for _, a, d in zip(*hough_line_peaks(h, theta, d)):
angle.append(a)
angle = [a * 180 / np.pi for a in angle]
所以这里发生的事情如下:
- 使用
hough_lines
检测图像上的所有线条。- 这个 returns 累加器值、角度(以弧度为单位)和与原点的距离,假设 Hough space 中的 1000 个峰被识别为线。
- select 只检测所有检测到的线中最突出的线
- 与原点的距离至少为 9 "resolution" 步的那些峰与另一个相似的峰
- theta 坐标与另一个相似的峰 "resolution" 步距至少 10 角的那些峰
- 整个Hough中累加器计数大于max_count/2的space
- 这个选择可以说是原始 1000 行中的 200 行更有可能是图像中的实际行。
- 这实际上是对所有 returned
hough_lines
的筛选器,它会挑选出最有可能是行的内容。因此,您还可以获得累加器值、角度(以弧度为单位)以及与原点的距离。
- 然后你将从
hough_line_peaks
得到的所有角度复制到一个名为a
的新 - 然后您使用另一个
for
循环遍历 a 并创建一个名为angle
的新列表,您在其中存储从a
转换为degrees
[ 的值=76=]
list
如您所见,可能还有改进的余地。首先,无需复制整个角度列表。其次,你实际上造成了更多的伤害,因为现在你不能使用 numpy 给你的矢量化操作。从 hough_line_peaks
编辑的数组 return 是一个 numpy ndarray
,你可以直接将其相乘。
import skimage
image = skimage.io.imread(file_name)
image = np.mean(image, axis=2)
h, theta, d = skimage.transform.hough_line(image)
bestH, bestTheta, bestD = skimage.transform.hough_line_peaks(h, theta, d)
angle = bestTheta * (180/np.pi)
应该会得到相同的结果,而且可能会更快一些。整行 zip(*hough_line_peaks(h, theta, d))
应该始终值得怀疑,因为 *
被称为 "unpacking" 运算符。因此,给定一个元组、列表或任何其他可迭代对象 (a, b, c)
,解包运算符将可迭代对象 *(a, b, c) --> a, b, c
解包,然后再次压缩它们只是将它们再次打包 *(a, b, c) --> a, b, c --> (a, b, c)
。这些结构应该总是有点可疑。 for 循环 for _, a, b in...
中的下划线只是将该值作为无名丢弃。最后的 [ a for a in...]
构造称为列表推导式,它的工作方式与 for
循环完全相同,但只是语法糖,可在可能的情况下使内容更具可读性。
编辑
回答评论中的额外问题。让我们说:
>> import numpy as np
>>> a = np.array([[1, 2], [3, 4]])
>>> a
array([[1, 2],
[3, 4]])
>>> a.mean(axis=0)
array([2., 3.])
>>> a.mean(axis=1)
array([1.5, 3.5])
所以轴 0 上的 mean
正在做 (1+3)/2=2
和 (2+4)/2=3
- 因此有效 axis=0
是跨越 a
的垂直切片。 axis=1
是横跨 a
的水平切片,因此 (1+2)/2=1.5
和 (3+4)/2=3.5
。对于具有附录的任何更大维度的元素矩阵也是如此,您只有更多维度。所以对于 2D 矩阵,它的垂直+水平对于 3D 它将是垂直+水平+深度。所以轴 2 在 "depth" 上求和。
为什么这是必要的,因为 hough_lines
只能处理强度数据。它不理解颜色。但在彩色图像中,每个像素实际上是 3 个数字 (r, b, g)
,代表红色、蓝色和绿色通道强度。这些强度的混合最终会在显示器上产生颜色。因此,mean(axis=2)
行指示 numpy 获取表示图像的 3D 矩阵,并向您 return 提供 2D 矩阵,其中每个像素强度值已被 3 种颜色强度值的平均值所取代。
所以彩色图像:
index 1 2 ....
___________________________________
1 | [1, 2, 3] [4, 5, 6] ...
2 | [7, 8, 9] . ...
. | . .
. | . .
. | . .
变成灰度图:
index 1 2
______________________________
1 | 2 5 ...
2 | 8 . ...
3 | . .
| . .
| . .
|