【问题标题】:Detecting and isolating lines in an image检测和隔离图像中的线条
【发布时间】:2019-05-27 00:05:22
【问题描述】:

我正在尝试编写一段代码来检测和隔离图像中的直线。我正在使用 opencv 库以及 Canny 边缘检测和霍夫变换来实现这一点。到目前为止,我想出了以下几点:

import numpy as np
import cv2

# Reading the image
img = cv2.imread('sudoku-original.jpg')
# Convert the image to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Edge detection
edges = cv2.Canny(gray,50,150,apertureSize = 3)
# Line detection
lines = cv2.HoughLines(edges,1,np.pi/180,200)

for rho,theta in lines[0]:
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a))

    cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)

cv2.imwrite('linesDetected.jpg',img)

理论上这段代码 sn-p 应该可以完成这项工作,但不幸的是它没有。生成的图片清楚地显示只有一条线被发现。我不太确定我在这里做错了什么以及为什么它只检测到一个特定的行。有人能找出这里的问题吗?

【问题讨论】:

  • 它只显示一行,因为您告诉它只显示检测到的第一行 -- lines[0]。事实上,这只是由于 OpenCV 将数据类型从 C++ 映射到 Python 的方式的一个怪癖。如果您正确地遍历整个数组(正如@teng 所建议的那样,尽管在我的评论中提到了修改),它将正确地可视化所有 detected 行。现在,下一个问题是“为什么不能检测到所有行?”
  • 由于您不应该在每个问题帖子中提出多个问题,我建议将标题更改为“为什么只显示一个检测到的行?”。然后创建一个关于为什么它没有检测到所有行的新问题(包括更正的for 循环)。
  • 并将edges 图像保存到文件中并查看它——应该会很好地提示您为什么找不到左起第二行。 IIRC 教程在进一步处理之前做了自适应阈值——图像的不一致照明肯定会导致问题。

标签: python opencv hough-transform canny-operator


【解决方案1】:

尽管opencv的Hough Transform tutorial只使用了一个循环,lines的形状是实际的[None,1,2],因此当你使用lines[0]你只会得到rho的一项和一项对于theta,这只会给你一行。因此,我的建议是使用双循环(如下)或一些 numpy 切片魔术来仅使用 1 个循环来维护。如Dan Masek 所述,要检测到所有网格,您需要使用边缘检测逻辑。也许看到使用HoughLinesPsolution

for item in lines:
    for rho,theta in item:
        ...

【讨论】:

  • 它修复了一些东西...现在它显示了更多行,但仍然不是全部...
  • 第二个循环是不必要的,一个简单的rho, theta = item[0] 就可以了,因为内部列表总是只有一个项目(这是 OpenCV 在 C++ 和 Python 数据结构之间映射方法的一个怪癖)。
  • 还有一些关于 OP 做错了什么的解释,以及为什么应该使用您显示的代码会有所帮助。如果您展示一个 lines 的示例,那就更好了。
  • @DanMašek 可以。感谢您的建议。
猜你喜欢
  • 2014-06-16
  • 1970-01-01
  • 2019-10-28
  • 2013-05-15
  • 1970-01-01
  • 1970-01-01
  • 2015-09-05
  • 1970-01-01
  • 2010-10-15
相关资源
最近更新 更多