【问题标题】:Detect horizontal blank lines in .pdf form image with OpenCV使用 OpenCV 检测 .pdf 表单图像中的水平空白行
【发布时间】:2019-12-07 05:02:42
【问题描述】:

我有.pdf 文件已转换为该项目的.jpg 图像。我的目标是识别您通常会在 .pdf 表单中找到的空白(例如 ____________),这些空白表示用户填写某种信息的签名空间。我一直在使用cv2.Canny()cv2.HoughlinesP() 函数进行边缘检测。

这工作得相当好,但有不少误报似乎不知从何而来。当我查看“边缘”文件时,它会在其他单词周围显示一堆噪音。我不确定这种噪音是从哪里来的。

我应该继续调整参数,还是有更好的方法来找到这些空白的位置?

【问题讨论】:

  • 您是要查找空白条目以最终填写它们,还是出于其他目的?您可以使用pdfrw 填写空白 PDF 表格。如果相关,请查看 this 博客文章。
  • 目前,pdf 不可填写。这只是文字。我正在尝试确定应该可填充的区域,然后创建一个文档导出以生成可填充部分。
  • 将示例发布到一些免费托管服务并将 URL 放在这里。您可以使用形态学搜索某些最小长度的水平线。
  • 一种方法是使用特殊的水平内核和形态变换来隔离线条。添加输入和预期输出图像会很有帮助

标签: python image opencv image-processing computer-vision


【解决方案1】:

假设您要在.pdf 表单上查找水平线,这里有一个简单的方法:

  • 将图像转换为灰度和自适应阈值图像
  • 构造特殊内核以仅检测水平线
  • 执行形态转换
  • 查找轮廓并在图像上绘制

使用此示例图片

转换为灰度和自适应阈值得到二值图像

gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

然后我们用cv2.getStructuringElement() 创建一个内核并执行形态变换以隔离水平线

horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)

从这里我们可以使用cv2.HoughLinesP()来检测线条,但是由于我们已经对图像进行了预处理并隔离了水平线,所以我们可以找到轮廓并绘制结果

cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (36,255,12), 3)

完整代码

import cv2

image = cv2.imread('2.png')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)

cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (36,255,12), 3)

cv2.imshow('thresh', thresh)
cv2.imshow('detected_lines', detected_lines)
cv2.imshow('image', image)
cv2.waitKey()

【讨论】:

  • 谢谢,这很有帮助。正是我想要的。
  • 但是,现在我遇到了文本中带下划线的单词的误报问题。知道如何解决这个问题吗?
  • 您可以使用cv2.getStructuringElement() 内核大小,因此将(15,1) 更改为(11,1) 将“松开”过滤器。还可以更改 cv2.morphologyEx() 中的迭代次数可能会有所帮助
  • @nathancy - 感谢您提供出色的解决方案。但是,我使用的是 PyPDF2 并坚持能够将 PDF 中的页面作为图像读取。你能帮忙吗?也许在上面的答案中添加代码? TNX!
猜你喜欢
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 2021-07-03
  • 1970-01-01
  • 2023-03-11
  • 2021-02-17
相关资源
最近更新 更多