在巴西,为医院的每个新生儿(手工)填写标准表格。这种表格被称为“DNV”(葡萄牙语为“Born Alive Declaration”)。还有一种表格叫做“DO”(葡萄牙语为“死亡声明”之后)。在我所在的州,医院向我工作的机构发送了近一百万份这样的表格,在那里我们计算了一个名为“生命统计”的数据库。我正在调查是否可以使工作自动化。由于商业 ICR 解决方案花费大量资金,没有人相信它可以在内部完成,因此它是一个草根项目。
我得到了从几家医院发送的 100K PDF 文件,并且能够使用一种简单的算法将它们分类为两种类型(DNV 或 DO)中的一种:首先,我找到包含文档类型的黑色矩形(使用cv2.findContours
和一些启发式方法)并应用 OCR(pytesseract.image_to_string
)。我找到了 20k“死亡声明”(DO)和 80k“生前声明”。
使用类似的算法,我能够对黑色矩形右侧的数字进行 OCR,并将 55k 表单图像与专业打字员根据这些文档填写的数据库中的相应记录链接起来。
现在我想找到日期字段(红色),以便尝试一些机器学习来识别数字 - 该字段在下面突出显示:
这很有效,但前提是模板和表单图像具有相同的比例和角度。该cv2.matchTemplate
方法对规模非常敏感。我尝试了使用 SURF 的特征匹配算法,但我很难让它工作(感觉有点矫枉过正)。
由于很容易找到左侧的黑色矩形,我正在考虑一些选项来定位数字:
根据黑色矩形对比例和角度进行归一化并尝试
cv2.matchTemplate
。试图定位轮廓,使用简化
cv2.approxPolyDP
并猜测数字位置。
我的问题是:关于如何解决问题的任何建议?如果输入未根据分辨率/角度进行标准化,我可以使用什么其他算法来定位此表单字段?
[更新#1]
给定 (x, y, w, h) 作为左侧黑色矩形的位置和大小,我可以以合理的信心缩小搜索范围。
尝试随机样本,这个公式给了我:
img.crop((x+w, y+h/3, x+h*3.05, y+2*h/3))
[更新#2]
我刚刚了解到erode
和dilate
,现在他们是我最好的新朋友。
horizontal = edges.copy()
vertical = edges.copy()
kv = np.ones((25, 1), np.uint8)
kh = np.ones((1, 30), np.uint8)
horizontal = cv2.dilate(cv2.erode(horizontal, kh, iterations=2), kh, iterations=2)
vertical = cv2.dilate(cv2.erode(vertical, kv, iterations=2), kv, iterations=2)
grid = horizontal | vertical
plt.imshow(edges, 'gray')
plt.imshow(grid, 'gray')
顺便说一句,我对计算机视觉一无所知。让我们回到谷歌...