Python 提高图像中字母的质量

Python 提高图像中字母的质量,python,image,opencv,letters,Python,Image,Opencv,Letters,我正在处理包含文本的图像。问题是这些图像是收据,经过大量转换后,文本质量下降。 我正在使用python和opencv。 我尝试了很多来自doc的形态学转换组合,但没有得到令人满意的结果 我现在正在做这件事(我将对我尝试过的内容进行评论,并让未注释的人对我正在使用的内容进行注释): 使用此选项,从原始图像: 我明白了: 正如你所看到的,它稍微好一点。但还是太糟糕了。OCR(tesseract)不能很好地识别此处的字符。我受过训练,但正如你所注意到的,每个“e”都是不同的,等等 我得到了很好的结

我正在处理包含文本的图像。问题是这些图像是收据,经过大量转换后,文本质量下降。 我正在使用python和opencv。 我尝试了很多来自doc的形态学转换组合,但没有得到令人满意的结果

我现在正在做这件事(我将对我尝试过的内容进行评论,并让未注释的人对我正在使用的内容进行注释):

使用此选项,从原始图像:

我明白了:

正如你所看到的,它稍微好一点。但还是太糟糕了。OCR(tesseract)不能很好地识别此处的字符。我受过训练,但正如你所注意到的,每个“e”都是不同的,等等

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

也许我可以做另一件事,或者使用更好的形态学变换组合。如果我可以使用另一个工具(PIL、imagemagick等),我可以使用它

这是整个图像,您可以看到它的外观:


正如我所说,这并没有那么糟糕,但稍微“优化”一下这些字母就完美了

> P>你考虑相邻像素并加上它们的总和。< /P> 例如:

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添加阵列

根据我的经验,腐蚀会降低OCR质量。如果你有灰度图像(不是二值图像),你可以使用更好的二值化算法。我使用SAUVOLA算法进行二值化。如果你只有二值图像,你能做的最好的事情就是去除噪声(去除所有的小点)

我在Haskell中找到了我正在尝试为闭合多边形实现的方法。也许它能解决一些问题

在这个主题上工作了多年后,我现在可以说,我想做的事情需要付出很大的努力,它非常缓慢,而且从来没有像我预期的那样奏效。字符中像素的不规则性总是不可预测的,这就是为什么“简单算法”不起作用

问:那就不可能有一个像样的OCR,它可以读取损坏的字符

回答:不,这不是不可能的。但它需要的不仅仅是侵蚀、形态闭合或类似的东西

那怎么办?神经网络:)

以下是两篇非常有帮助的论文:

对于那些不熟悉RNN的人,我可以建议:

还有一个python库,它运行得非常好(不幸的是,对于C++,它甚至更好):


我真的希望这能帮助别人

尝试使用形态闭合代替侵蚀。至于字母,它们似乎与开始时不同,所以我认为仅仅使用简单的算法并不能做很多事情。有些扫描仪用完全相同的位图替换相似的字母,所以也许您可以复制这种行为。但是要小心:施乐电脑中有一个非常丑陋的错误,它让图书馆员的生活非常不舒服。谢谢你,我会寻找一种邻近像素的算法。但是在你向我提出的答案中,我认为
n[4]
你的意思是
n[1][0]
还是?因为n是一个3行3列的矩阵。但是,它不起作用。结果与img完全相同。也许应该做些改变。用修改过的面具更新答案。基本上,“n”在北方向的权重更大,“s”在南方向的权重更大,依此类推。你能增加卷积掩模的尺寸并尝试一下吗?谢谢你的回答。你如何使用Sauvola?和Leptonica?我使用OpenCV提出的Otsu二值化,但是如果我发现如何在Python上实现(或使用),也可以用Sauvola来测试它。C++的SoulVa算法实现。也可以尝试使用MEAN的adaptiveThreshold()。这种二值化显示了与SAUVOLA类似的结果。
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