Tesseract OCR 无法检测到不同的字体大小和未水平对齐的字母

Posted

技术标签:

【中文标题】Tesseract OCR 无法检测到不同的字体大小和未水平对齐的字母【英文标题】:Tesseract OCR fails to detect varying font size and letters that are not horizontally aligned 【发布时间】:2018-09-07 05:13:12 【问题描述】:

我正在尝试检测这些价格标签文本,这些文本总是经过清晰的预处理。虽然它可以很容易地阅读上面写的文字,但它无法检测价格值。我正在使用 python 绑定pytesseract,尽管它也无法从 CLI 命令中读取。大多数情况下,它会尝试将价格识别为一两个字符的部分。

示例 1:

tesseract D:\tesseract\tesseract_test_images\test.png output

样本图像的输出是这样的。

je Beutel

13

但是,如果我裁剪并拉伸价格以使其看起来像是分开的并且字体大小相同,那么输出就很好了。

处理后的图片(裁剪和缩小的价格):

je Beutel

1,89

如何让 OCR tesseract 按我的预期工作,因为我将查看很多类似的图像? 编辑:添加更多价格标签:sample5sample6sample7

【问题讨论】:

尝试提出一个使用例如的算法。 cv2.connectedComponentscv2.boundingRect 函数用于检测在同一水平区域上大小不同的连接区域。然后,您可以在扩大较小区域、缩小较大区域或隔离不同区域并单独调用之后调用tesseract 你能写一个例子来说明它是如何工作的吗?也许我可以一个一个地输入组件,它仍然可以工作,但是 connectedComponent 返回一个黑色图像 见***.com/questions/43547540/… 【参考方案1】:

问题是您使用的图像尺寸过小。现在,当 tesseract 处理图像时,它会将 '8'、'9' 和 ',' 视为单个字母,因此将其预测为 ' 3' 或者可以将 '8' 和 ',' 视为一个字母,而将 '9' 视为不同的字母letter 等会产生错误的输出。下图说明了这一点。

一个简单的解决方案可能是根据原始图像的大小将其大小增加 2 或 3 倍甚至更多,然后传递给 tesseract 以便它单独检测每个字母,如下所示。 (这里我将它的大小增加了 2 倍)

Bellow 是一个简单的 Python 脚本,可以解决您的目的

import pytesseract
import cv2

img = cv2.imread('dKC6k.png')
img = cv2.resize(img, None, fx=2, fy=2)

data = pytesseract.image_to_string(img)
print(data)

检测到的文字:

je Beutel

89
1.

现在您可以简单地从文本中提取所需的数据并根据您的要求对其进行格式化。

data = data.replace('\n\n', '\n')
data = data.split('\n')

dollars = data[2].strip(',').strip('.')
cents = data[1]

print('.'.format(dollars, cents))

所需格式:

1.89

【讨论】:

提问者已明确提到他/她正在尝试检测价格标签文本,这些文本始终以所示格式进行了明确的预处理。 我正在用更多的测试用例更新这个问题,并且几乎所有这些都不起作用,并且在你的答案中,89 在 1 前面被识别是说它也有问题(他们应该是在同一行中,1 不低于 89,逗号也被识别为点)。我真的更关注逗号顶部有数字的部分。 这就是tesseract的工作原理,它识别字符并根据识别它们的位置打印文本。您必须以某种方式理解这一点,或者需要训练自己的模型,该模型可以根据您的说服力完美运行,我认为这在您的场景中更可取,因为您需要处理具有相同格式的图像。 @NONONONONO 您可以将图片上传到 GitHub 存储库并分享链接,以便我更清楚地了解您的数据集并相应地建议您。 我真的不能,因为它们确实是我不应该分享的东西,但是无论如何添加了一些测试用例。我不确定您所说的“位置”是什么意思,因为正如您所看到的,尽管 89 位于同一行并且位于 1 的右侧,但它未能被识别为 1,89(就像阅读一样)。此外,图像大小显然不是问题,因为价格数字上方的字母(对于我拥有的所有图像)都被正确识别。我转向了一个全新的架构来识别价格数字。【参考方案2】:

问题在于 Tesseract 引擎没有接受过阅读这种文本拓扑结构的训练。

你可以:

训练您自己的模型,您尤其需要提供具有不同拓扑结构(字符位置)的图像。您实际上可以使用相同的图像,并打乱字符的位置。 将图像重新组织成文本簇并使用 tesseract,特别是,我会考虑美分部分并将其移动到 coma 的右侧,在这种情况下,您可以使用 tesseract 开箱即用。很少有相关标准是簇的高度(用于区分美分和整数)和簇的位置(从左到右读取)。李>

一般来说,计算机视觉算法(包括 CNN)为您提供了一种工具,可以让您获得更高的图像表示(特征或描述符),但它们无法创建逻辑或算法来以某种方式处理中间结果。

你的情况是:

“如果这些字母的高度较小,则为美分”, "如果高度和垂直位置相同,大约是 相同的数字,要么在昏迷的左边,要么在昏迷的右边”。

问题在于,通过训练很难达到这一点,同时,为人类编写这个算法非常简单。很抱歉没有给你一个实际的实现,但我的文字伪代码。

TrainingTesseract2

TrainingTesseract4

Joint Unsupervised Learning of Deep Representations and Image Clusters

【讨论】:

以上是关于Tesseract OCR 无法检测到不同的字体大小和未水平对齐的字母的主要内容,如果未能解决你的问题,请参考以下文章

显式设置用于 Tesseract-OCR 识别的字体

配置 Tesseract OCR 以读取相同字体大小的单词

使用 Tesseract-OCR 获取已识别字符的字体

OCR的理想字体是什么?

iOS .Tesseract OCR 为啥识别如此纯粹。发动机原理

进行 OCR 之前的预处理(tesseract、OpenCV)