python - 预处理扫描不良的手写数字

标签 python opencv ocr

我有几千个 PDF 文件,其中包含来自数字化纸质表格的黑白图像(1 位)。我正在尝试对某些字段进行 OCR,但有时文字太模糊:

enter image description here

我刚刚学习了形态变换。他们真的很酷!!!我觉得我在滥用它们(就像我在学习 Perl 时对正则表达式所做的那样)。

我只对日期 07-06-2017 感兴趣:

im = cv2.blur(im, (5, 5))
plt.imshow(im, 'gray')

enter image description here

ret, thresh = cv2.threshold(im, 250, 255, 0)
plt.imshow(~thresh, 'gray')

enter image description here

填写此表格的人似乎对网格有些无视,所以我试图摆脱它。我可以用这个变换来隔离水平线:

horizontal = cv2.morphologyEx(
    ~thresh, 
    cv2.MORPH_OPEN, 
    cv2.getStructuringElement(cv2.MORPH_RECT, (100, 1)),
)
plt.imshow(horizontal, 'gray')

enter image description here

我也可以得到垂直线:

plt.imshow(horizontal ^ ~thresh, 'gray')

ret, thresh2 = cv2.threshold(roi, 127, 255, 0)
vertical = cv2.morphologyEx(
    ~thresh2, 
    cv2.MORPH_OPEN, 
    cv2.getStructuringElement(cv2.MORPH_RECT, (2, 15)), 
    iterations=2
)
vertical = cv2.morphologyEx(
    ~vertical, 
    cv2.MORPH_ERODE, 
    cv2.getStructuringElement(cv2.MORPH_RECT, (9, 9))
)
horizontal = cv2.morphologyEx(
    ~horizontal, 
    cv2.MORPH_ERODE, 
    cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
)
plt.imshow(vertical & horizontal, 'gray')

enter image description here

现在我可以去掉网格了:

plt.imshow(horizontal & vertical & ~thresh, 'gray')

enter image description here

我得到的最好的是这个,但是 4 仍然分成 2 block :

plt.imshow(cv2.morphologyEx(im2, cv2.MORPH_CLOSE, 
    cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))), 'gray')

enter image description here

可能此时最好使用 cv2.findContours 和一些启发式方法来定位每个数字,但我想知道:

  1. 我应该放弃并要求以灰度模式重新扫描所有文档吗?
  2. 是否有更好的方法来隔离和定位微弱数字?
  3. 你知道连接像“4”这样的格的任何形态变换吗?

[更新]

Is rescanning the documents too demanding? If it is no great trouble I believe it is better to get higher quality inputs than training and trying to refine your model to withstand noisy and atypical data

一点背景知识:我在巴西的一家公共(public)机构工作,是个无名小卒。 ICR 解决方案的价格从 6 位数开始,因此没有人相信一个人可以在内部编写 ICR 解决方案。我天真到相信我能证明他们是错的。那些 PDF 文档位于 FTP 服务器上(大约 100K 个文件)并且被扫描只是为了摆脱死树版本。也许我可以自己拿到原始表格并再次扫描,但我必须寻求一些官方支持——因为这是公共(public)部门,我想尽可能地将这个项目保密。我现在拥有的是 50% 的错误率,但如果这种方法是死胡同,那么尝试改进它就没有意义了。

最佳答案

也许用Active contour model某种? 例如,我找到了这个图书馆:https://github.com/pmneila/morphsnakes

拿你最后的“4”号:

enter image description here

经过一些快速调整(没有真正理解参数,所以可能会得到更好的结果)我得到了这个:

enter image description here

使用以下代码(我还对 morphsnakes.py 进行了一些修改以保存图像):

import morphsnakes

import numpy as np
from scipy.misc import imread
from matplotlib import pyplot as ppl

def circle_levelset(shape, center, sqradius, scalerow=1.0):
    """Build a binary function with a circle as the 0.5-levelset."""
    grid = np.mgrid[list(map(slice, shape))].T - center
    phi = sqradius - np.sqrt(np.sum((grid.T)**2, 0))
    u = np.float_(phi > 0)
    return u

#img = imread("testimages/mama07ORI.bmp")[...,0]/255.0
img = imread("four.png")[...,0]/255.0

# g(I)
gI = morphsnakes.gborders(img, alpha=900, sigma=3.5)

# Morphological GAC. Initialization of the level-set.
mgac = morphsnakes.MorphGAC(gI, smoothing=1, threshold=0.29, balloon=-1)
mgac.levelset = circle_levelset(img.shape, (39, 39), 39)

# Visual evolution.
ppl.figure()
morphsnakes.evolve_visual(mgac, num_iters=50, background=img)

关于python - 预处理扫描不良的手写数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45021559/

相关文章:

python - 使用自定义字体的 Pytesseract 错误地对数字进行分类

python - 字符串替换条件

python - for 之后无法绘制数据

python - 使用 Python 快速搜索驱动器

c# - 如何使用 Emgu CV 检测图像中的箭头?

matlab - 使用 OpenCV 和 python 从图像中提取对象(指纹和签名)

python - 使用 opencv 或创建线性渐变蒙版

ocr - 通过Tesseract OCR在七段显示器上进行文本检测

使用列表作为值的 Python 字典,查找具有相同值的其他键

matlab - 车牌自动识别系统