使用OpenCV检测水平线
image-processing
opencv
6
0

我正在尝试从来自“文档”的图像中查找水平和垂直线。这些文档是来自合同的扫描页面,因此这些行看起来就像您在表格或合同块中看到的一样。

我一直在尝试OpenCV来完成这项工作。 OpenCV中的Hough变换实现对于这项工作似乎很有用,但是我找不到任何可以使它清晰地找到垂直线和水平线的参数组合。我尝试了有无边缘检测。没运气。如果有人做了类似的事情,我会对如何做感兴趣。

在这里查看我在OpenCV中使用HoughP之前和之后的图像。这是我能做的最好的事情, http://dl.dropbox.com/u/3787481/Untitled%201.png

因此,现在我想知道是否可以使用另一种转换方式,使我能够可靠地找到水平线和垂直线(最好也可以是虚线)。

我知道此问题是可以解决的,因为我拥有Nuance和ABBYY OCR工具,它们可以可靠地提取水平和垂直线,并向我返回这些线的边界框。

谢谢!帕特里克

参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

您是否看到过HoughLinesP函数文档中的代码示例?

我认为您可以将其用作算法的起点。要拾取水平和垂直线,您只需要按线角过滤掉其他线即可。

更新:

如我所见,您无需查找线条,而是需要在页面上水平放置垂直边缘。对于此任务,您需要结合多个处理步骤才能获得良好的效果。

对于您的图像,通过将Canny边缘检测与HoughLinesP结合使用,可以获得很好的效果。这是我的代码(我使用过python,但我认为您已经明白了):

img = cv2.imread("C:/temp/1.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 80, 120)
lines = cv2.HoughLinesP(edges, 1, math.pi/2, 2, None, 30, 1);
for line in lines[0]:
    pt1 = (line[0],line[1])
    pt2 = (line[2],line[3])
    cv2.line(img, pt1, pt2, (0,0,255), 3)
cv2.imwrite("C:/temp/2.png", img)

结果看起来像:

收藏
评论

不要将RGB转换为灰度。有时,RGB中的不同颜色可以合并为相同的灰度值,因此可能会丢失某些轮廓。您应该分别分析每个RGB通道。

收藏
评论

您可能要考虑退出霍夫线检测,因为此方法查找“全局”线,而不是线段。我最近实现了一个应用程序,该应用程序可识别“平行四边形”-本质上是可以旋转的正方形,并且由于视角的原因,透视图也有所缩短。您可能会考虑类似的事情。我的管道是:

  1. 从RGB转换为灰度(cvCvtColor)
  2. 平滑(cvSmooth)
  3. 阈值(cvThreshold)
  4. 检测边缘(cvCanny)
  5. 查找轮廓(cvFindContours)
  6. 具有线性特征的近似轮廓(cvApproxPoly)

在您的应用程序中,结果轮廓列表可能会很大(取决于平滑的“积极性”和Canny边缘检测器的功能增强。您可以通过多种参数来修剪此列表:从轮廓查找器返回的点数,轮廓的面积(cvContourArea)等。根据我的经验,我希望您的应用程序中的“有效”线具有明确定义的面积和顶点计数属性。此外,您还可以根据端到端之间的距离过滤轮廓点,由连接端点的线定义的角度等。

根据您拥有多少CPU“时间”,您始终可以将Hough算法与上述算法配对,以可靠地识别水平线和垂直线。

收藏
评论

如果您只需要“线”而不是“线段”,那么我将避免使用Canny,Hough,FindContours或任何其他此类函数,以防您希望提高代码速度。如果您的图像没有旋转,而您要查找的始终是垂直或水平的,则只需使用cv :: Sobel(一个用于垂直,另一个用于水平)并为列和行创建累积数组。然后,您可以搜索此类累加或配置文件中的最大值,例如通过设置阈值,您将知道其中有垂直或水平边缘线的行或列。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号