如何防止HoughLines多次检测到某些行

时间:2019-08-02 21:54:16

标签: python opencv hough-transform canny-operator houghlines

因此,我正在处理这段代码,以从图像中的某些图形中提取数据。这些图像都是从书本中扫描的。由于我们在这里谈论的是100幅以上的图像,因此我想自动执行该过程。我的第一步是确保所有图像对齐。因为书的页面是手工扫描的,所以扫描彼此之间都略有偏移或旋转。幸运的是,图像上有一些虚线,可用作将它们对齐的参考点。然后,通过在这些虚线上将图像切片,我可以将图像划分为较小的子图像。这样,所有子图像对于所有扫描图像将是相等的。

因此,当然第一步是检测这些虚线。我的策略可分为4个步骤:

  • 使用形态转换将虚线变为实线
  • 使用Canny Edge Detection检测所有边缘
  • 使用HoughLines识别线
  • 在面具上画这些线以备将来使用

现在可能会出现几个问题。有时HoughLines会检测到错误的行(例如书中下一页的折页),但是可以通过在右侧略微裁剪图像来解决此问题(始终欢迎使用更好的解决方案)。第二个(也是最大的)问题是HoughLines有时倾向于将单行标识为多行。我认为这与Canny Edge Detection的边缘过于粗糙或含糊不清有关,因此HoughLines实际上会看到多条线。有什么办法可以使Canny的输出“平滑”,以便HoughLines可以一次检测到每一行?

在此特定图像的情况下,中间的垂直虚线未被识别,而书中下一页的折叠被识别。此外,垂直虚线被识别为多条线。 (左源图像,检测到中间边缘,检测到右线)

enter image description here

# load image
img_large = cv2.imread("image.png")
# resize for ease of use
img_ori = cv2.resize(img_large, None, fx=0.2, fy=0.2, interpolation=cv2.INTER_CUBIC)
# create grayscale
img = cv2.cvtColor(img_ori, cv2.COLOR_BGR2GRAY)
# create mask for image size
mask = np.zeros((img.shape[:2]), dtype=np.uint8)
# do a morphologic close to merge dotted line
kernel = np.ones((8, 8))
res = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
# detect edges for houghlines
edges = cv2.Canny(res, 50, 50)
# detect lines
lines = cv2.HoughLines(edges, 1, np.pi/180, 200)
# draw detected lines
for line in lines:
    rho, theta = line[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(mask, (x1, y1), (x2, y2), 255, 2)
    cv2.line(img, (x1, y1), (x2, y2), 127, 2)

1 个答案:

答案 0 :(得分:2)

在您的脚本中,像素仓和旋转仓对于设置的阈值来说太精细了:

public class MangasViewModel{
  public List<WN> WN{get;set;}
  public List<LN> LN {get;set;}
  public List<Manga> Manga {get;set;}
}

因此,您可以调整阈值参数(200)仅获得一行,或者调整rho(1)和theta(np.pi / 180)参数,或者调整所有这些参数。您可以从图像中选择一组仅包含一条水平线或垂直线的图像。然后进行网格搜索以找到仅检测一组测试图像中的一行的参数。