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

Pau*_*ine 17 python ocr opencv

我有几千个包含数字化纸张形式的黑白图像(1位)的PDF文件.我正在尝试OCR一些字段,但有时写作太微弱了:

在此输入图像描述

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

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

im = cv2.blur(im, (5, 5))
plt.imshow(im, 'gray')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

ret, thresh = cv2.threshold(im, 250, 255, 0)
plt.imshow(~thresh, 'gray')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

horizontal = cv2.morphologyEx(
    ~thresh, 
    cv2.MORPH_OPEN, 
    cv2.getStructuringElement(cv2.MORPH_RECT, (100, 1)),
)
plt.imshow(horizontal, 'gray')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我也可以得到垂直线:

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')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

现在我可以摆脱网格:

plt.imshow(horizontal & vertical & ~thresh, 'gray')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我得到的最好的是这个,但4仍然分为两部分:

plt.imshow(cv2.morphologyEx(im2, cv2.MORPH_CLOSE, 
    cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))), 'gray')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

可能在这一点上最好使用cv2.findContours和一些启发式来定位每个数字,但我想知道:

  1. 我应该放弃并要求以灰度重新扫描所有文件吗?
  2. 有没有更好的方法来隔离和定位微弱的数字?
  3. 你知道任何形态变换加入像"4"这样的情况吗?

[更新]

重新扫描文件太苛刻了吗?如果没有大麻烦,我相信获得比培训更高质量的输入并尝试优化模型以承受噪声和非典型数据更好

一点背景:我是一个在巴西的公共机构工作的人.ICR解决方案的价格从6位开始,因此没有人相信一个人可以在内部编写ICR解决方案.我天真地认为我可以证明他们是错的.这些PDF文档位于FTP服务器(大约100K文件),并进行扫描,以摆脱死树版本.可能我可以获得原始形式并再次扫描,但我不得不要求一些官方支持 - 因为这是公共部门,我想尽可能地将这个项目保留在地下.我现在所拥有的是50%的错误率,但如果这种方法是死路一条,那么试图改进它就没有意义.

Hea*_*rab 8

也许有某种活动轮廓模型?例如,我找到了这个库:https://github.com/pmneila/morphsnakes

取了你最后的"4"号码:

在此输入图像描述

经过一些快速调整(实际上没有理解参数,因此可能得到更好的结果)我得到了这个:

在此输入图像描述

使用以下代码(我还修改了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)
Run Code Online (Sandbox Code Playgroud)