Tesseract OCR 输出错误

Tesseract OCR gives bad output

我正在使用 Tesseract 库的 c# 包装器(如果我没记错的话是 3.02)(https://github.com/charlesw/tesseract)。我得到它 运行 并提供输出,但该输出基本上是垃圾。通常它什么都不给,而当它确实给了一些东西时,它通常是一团糟。我知道它在理论上是有效的,因为我已经在一些非常完美的图像上尝试过它并且它有效。我想知道是否有人可以帮助我诊断问题并提出一些可以提高 Tesseract 准确性的方法。我已经将所有图像转换为黑白图像,分辨率设置为 300x300。我没有以编程方式拉直任何直线,但正如您在下面看到的那样,它们非常直。

这张图片效果很好

这个根本不起作用,要么产生乱码,要么什么都不产生

我尝试翻转颜色,认为它可能会产生更大的对比度(因为大多数文本是白底黑字,而有效的是黑底白字)。但是:

根本不起作用,而

再次完美运行。

我怀疑这与 "INVOICE." 中字母之间的额外间距有关,但必须有某种方法可以使用更紧凑的字体获得不错的结果。欢迎任何建议,我是这里的相对菜鸟。

如果可能,您应该考虑使用分辨率更高的图片。 Lockheed Martin 和 Payments 图像的另一个问题可能是字母之间的间隙太小。如果单个字母(几乎)连接到单词的下一个字母,则 Tesseract 无法检测到它们。 我会建议像 openCV 这样的图像处理库来改善你的结果。 你可以试试 erosion/dilation。如果内核使用了正确的参数,这将分隔字母。使用不同的内核,看看哪种内核最适合您。

Mat element = getStructuringElement(erosion_type,
                                   Size(2 * erosion_size + 1, 2 * erosion_size + 1),
                                   Point(erosion_size, erosion_size));

erode(src, erosion_dst, element);

当我在做我的项目时,使用自适应阈值对我帮助很大。我发现这比将其转换为灰度或二值图像更有效。 注意:Java 代码,虽然在 C 中应该非常相似。

Imgproc.adaptiveThreshold(cropedIm, cropedIm, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 29, 10);

这是我在 Pixtern 中选择您的一张图片后得到的结果,Pixtern 是我的一个 android 项目(github 上的源代码)。我使用的是自适应阈值,但没有 dilation/erosion,结果已经很好了。

Image after applying adaptive threshold

Result (图片=洛克希德马丁航空公司)

对于付款图片和类似图片: 尝试使用正常阈值并反转图像(黑色字体,白色背景)。同样,dilation/erosion 之后可以使用。 Java代码:

//results in binary image
Imgproc.threshold(cropedIm, cropedIm, 127, 255, Imgproc.THRESH_BINARY);
//Inverting image
Core.bitwise_not(cropedIm, cropedIm);

Tesseract 需要整个页面,或者更确切地说,它是在这些页面上进行训练的。 如果你给它一两个字符或单词,它就不会很好地工作。

我假设你有更多这样的图片。将它们作为文本行拼接在一起:就像每个图像都是前一个图像之后的一行文本一样,它应该会更好。


此外,确保在使用 tesseract 时正确设置 psm 参数。更多相关信息:https://www.pyimagesearch.com/2021/11/15/tesseract-page-segmentation-modes-psms-explained-how-to-improve-your-ocr-accuracy/