python - 使用hough_line后关于hough_line_peaks的说明

标签 python hough-transform

有人可以解释一下为什么在使用 h,theta,d = hough_line(image) 来检测图像中的角度之后,我们必须使用这个 for 循环 for _, a , zip(*hough_line_peaks(h, theta, d)) 中的 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 检测图像上的所有线条。
    • 这会返回累加器值、角度(以弧度为单位)以及距原点的距离,假设霍夫空间中的 1000 个峰值被识别为线。
  • 仅选择所有检测到的线条中最突出的线条
    • 那些与原点距离至少与另一个相似峰相距 9“分辨率”步的峰
    • theta 坐标与另一个类似峰至少有 10 个角度“分辨率”步距的峰
    • 整个霍夫空间中累加器计数大于 max_count/2 的那些
    • 这会从原始 1000 条线中选出 200 条,因为这实际上更有可能是图像中的线。
    • 这实际上是对所有返回的 hough_lines 的过滤器选择那些最有可能成为线路的线路。因此,您还可以获得累加器值、角度(以弧度为单位)以及距原点的距离。
  • 然后复制从 hough_line_peaks 返回的所有角度进入新lista
  • 然后你使用另一个 for循环遍历 a 并创建一个名为 angle 的新列表其中存储 a 中的值转换为degrees

正如您所见,可能还有改进的空间。首先,不需要复制整个角度列表。其次,您实际上造成了更多的伤害,因为现在您无法使用 numpy 为您提供的矢量化操作。从 hough_line_peaks 返回的数组是一个 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))应该始终受到怀疑,因为 *称为“拆包”运算符。因此,给定一个元组、列表或任何其他可迭代的 (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])

所以mean轴 0 上正在执行 (1+3)/2=2(2+4)/2=3 - 非常有效axis=0a 的垂直切片。 axis=1则为 a 的水平切片这样(1+2)/2=1.5(3+4)/2=3.5 。对于任何具有附录的更大维度元素矩阵也是如此,您只是拥有更多维度。因此,对于 2D 矩阵,其垂直+水平;对于 3D,它将是垂直+水平+深度。所以轴 2 在“深度”上求和。

为什么这是必要的,因为 hough_lines只能使用强度数据。它不理解颜色。但在彩色图像中,每个像素实际上是 3 个数字 (r, b, g)代表红色、蓝色和绿色 channel 强度。这些强度的混合最终会在显示上产生颜色。所以mean(axis=2) line 指示 numpy 获取表示图像的 3D 矩阵,并返回给您一个 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 |  .   .
    |  .    .
    |  .     .
    | 

关于python - 使用hough_line后关于hough_line_peaks的说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56283580/

相关文章:

c++ - 保存由 OpenCV 上的 Hough Circle 检测到的圆圈内的内容

image-processing - 从一组随机线段中检测四边形形状

python - 如果 np.arange 喂养,为什么 np.arccos(1.0) 会给出 nan?

python - Pandas : balancing data

python - 使用 OpenCV 检测数字的小点或小数点

c# - 霍夫变换问题

python - 视频上的霍夫圆变换

Python网络驱动程序: reusing setUp and tearDown

python - 如何混合tensorflow keras模型和变压器

python - 使用两个文件导入并且都需要导入