2016-09-07 100 views
2

我正在处理具有文字的图像。问题是这些图像是收据,经过很多转换后,文字质量下降。 我正在使用python和opencv。 我尝试了很多来自文档Morphological Transformations的形态转换的组合,但我没有得到满意的结果。提高图像中字母的质量

我现在这样做的权利(我要评论什么,我已经试过了,只是让注释掉我使用的是什么):

kernel = np.ones((2, 2), np.uint8) 
# opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) 
# closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) 
# dilation = cv2.dilate(opening, kernel, iterations=1) 
# kernel = np.ones((3, 3), np.uint8) 
erosion = cv2.erode(img, kernel, iterations=1) 
# gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) 
# 
img = erosion.copy() 

有了这个,从这个原始图像:

enter image description here

我得到这个:

enter image description here

好像你看到的那样好一点。但它仍然太糟糕了。 OCR(tesseract)不能很好地识别这些字符。我已经训练过,但正如你可以注意到的,每个“e”都是不同的,等等。

我得到了很好的结果,但我想,如果我解决了这个问题,他们会更好。

也许我可以做另一件事,或者使用形态转换的更好的组合。如果还有其他工具(PIL,imagemagick等)可以使用,我可以使用它。

这里的整体形象,所以你可以看到它的外观:

enter image description here

正如我所说,这是没有那么糟糕,但有点是字母的更“优化”将是完美的。

+1

尝试使用形态闭合而不是侵蚀。至于这些字母,它们看起来与一开始有所不同,所以我认为用简单的算法就可以做很多事情。一些扫描仪用完全相同的位图替换类似的字母,所以也许你可以复制这种行为。但请注意:施乐机器中存在一个非常丑陋的错误,使图书馆员的生活非常不舒服 – meetaig

回答

0

经过多年研究这个主题,我现在可以告诉我,我想要做的事情需要付出很大的努力,速度很慢,从未像我预期的那样工作。字符中像素的不规则性总是不可预知的,这就是“简单算法”不起作用的原因。

问题:这是不可能的,那么有一个体面的OCR,它可以读取损坏的字符?

答:不,这不是不可能的。但是,这需要“一点点”,而不仅仅是使用侵蚀,形态学关闭或类似的东西。

那么,怎么样?神经网络:)

这里有两个惊人的论文,帮助我很多:

Can we build language-independent OCR using LSTM networks?

Reading Scene Text in Deep Convolutional Sequences

对于那些谁不熟悉RNN,我可以建议是:

Understanding LSTM Networks

还有一个python库,它工作得很好(不幸的是,甚至更好的为C++):

ocropy

我真的希望这可以帮助别人。

0

您是否考虑过相邻像素并添加它们的总和?

例如:

n = numpy.zeros((3,3)) 
s = numpy.zeros((3,3)) 
w = numpy.zeros((3,3)) 
e = numpy.zeros((3,3)) 

n[0][1] = 1 
s[2][1] = 1 
w[1][0] = 1 
e[1][2] = 1 

img_n = cv2.erode(img, n, iterations=1) 
img_s = cv2.erode(img, s, iterations=1) 
img_w = cv2.erode(img, w, iterations=1) 
img_e = cv2.erode(img, e, iterations=1) 

result = img_n + img_s + img_w + img_e + img 

此外,既可以numpy的或CV2添加的阵列。

+0

谢谢,我会寻找_a相邻像素算法_左右。 但是在你提出的答案中,我认为用'n [4]'表示'n [1] [0]'或?由于n是3行3列的矩阵。 但是,它不工作。 _result_看起来完全如_img_。也许应该改变一些东西。 –

+0

用修改后的蒙版更新了答案。基本上'n'在北方有更大的权重,'南方有更多的权重等等。你可以增加卷积蒙版的大小并尝试。 –

0

以我的经验腐蚀损害OCR质量。如果你有灰度图像(不是二进制),你可以使用更好的二值化算法。我使用SAUVOLA算法进行二值化。如果你只有二进制图像,你可以做的最好的事情是消除噪音(去除所有小点)。

+0

谢谢你的回答。 你如何使用Sauvola? Leptonica?我使用OpenCV中提出的otsu二值化,但如果我找到如何在python上实现(或使用它),也可以使用Sauvola进行测试。 –

+0

我使用SAUVOLA算法的C++实现。 https://github.com/benob/opencv-utils/blob/master/include/binarize.h 你也可以尝试使用MEAN的adaptiveThreshold(http://docs.opencv.org/3.1.0/d7/ D4D/tutorial_py_thresholding.html)。这种二值化表现出与SAUVOLA类似的结果。 –