tesseract 的 OCR 结果高度不一致

Posted

技术标签:

【中文标题】tesseract 的 OCR 结果高度不一致【英文标题】:Highly inconsistent OCR result for tesseract 【发布时间】:2018-02-22 15:15:29 【问题描述】:

这是原始屏幕截图,我将图像裁剪为 4 个部分,并尽可能清除图像的背景,但 tesseract 仅检测到此处的最后一列而忽略其余部分。

tesseract 的输出显示为有空格,我在处理结果时删除了这些空格

  Femme—Fatale.



  DaRkLoRdEIa
  aChineseN1gg4

  Noob_Diablo_

tesseract 的输出显示为有空格,我在处理结果时删除了这些空格

Kicked.

NosNoel
ChikiZD
Death_Eag|e_42

Chai—.

3579 10 1 7 148

2962 3 O 7 101

2214 2 2 7 99

2205 1 3 6 78

8212

7198

6307

5640

4884

15

40

40

6O

80

80

我只是在转储

的输出
result = `pytesseract.image_to_string(Image.open("D:/newapproach/B&W"+str(i)+".jpg"),lang="New_Language")`

但我不知道如何从这里开始以获得一致的结果。无论如何,我可以强制 tesseract 识别文本区域并使其扫描。因为在训练器(SunnyPage)中,默认为 tesseract识别扫描它无法识别某些区域,但是一旦我手动选择,所有内容都会被检测并正确翻译为文本

Code

【问题讨论】:

你能分享原始未处理的图像。数据是表格吗? @AmarpreetSinghSaini 添加了原始图像以及清理和裁剪的图像及其各自的输出,我现在只是将数据转储到文本文件中。我计划稍后在输出更准确时编写使用数据库可靠 @Divaker 检查更新的答案 您可以尝试使用页面分割方法。这里有一个列表,其中一个可能比默认更适合您的问题:github.com/tesseract-ocr/tesseract/wiki/ImproveQuality 我查看了该页面,您是否有任何关于其实现的 python 文档或任何想法在哪里指定分段属性 【参考方案1】:

尝试使用命令行来决定使用哪个 psm 值。

你可以试试这个吗:

pytesseract.image_to_string(image, config='-psm 6')

用你提供的图片试了一下,结果如下:

Extracted Text Out of Image

我面临的唯一问题是我的 tesseract 字典将图像中提供的“1”解释为“I”。

以下是可用的 psm 选项列表:

pagesegmode 值为: 0 = 仅方向和脚本检测 (OSD)。

1 = 使用 OSD 自动分割页面。

2 = 自动页面分割,但没有 OSD 或 OCR

3 = 全自动页面分割,但没有 OSD。 (默认)

4 = 假设有一列大小可变的文本。

5 = 假设一个统一的垂直对齐文本块。

6 = 假设一个统一的文本块。

7 = 将图像视为单个文本行。

8 = 将图像视为一个单词。

9 = 将图像视为圆圈中的单个单词。

10 = 将图像视为单个字符。

【讨论】:

让我检查一下并回复你 我一直在寻找的是如何传递这个 psm 参数。我觉得这很有趣,因为我不只是 google image_to_string 参数。尝试了一切,但没有。 github.com/tesseract-ocr/tesseract/wiki/ImproveQuality 曾经检查过这个,但从未见过文档。 这里有一个类似的答案:***.com/questions/44619077/… 有一个小(大)的区别,psm 之前是一个破折号而不是两个破折号。我尝试了--psm,但一无所获,然后使用-psm,配置选项产生了巨大的变化。我正在使用 python 2.7 和 tesseract 3.04.01。【参考方案2】:

我用了这个链接

https://www.howtoforge.com/tutorial/tesseract-ocr-installation-and-usage-on-ubuntu-16-04/

只需使用以下命令即可将准确率提高到 50%`

sudo apt update

sudo apt install tesseract-ocr

sudo apt-get install tesseract-ocr-eng

sudo apt-get install tesseract-ocr-all

sudo apt install imagemagick

convert -h

tesseract [image_path] [file_name]

convert -resize 150% [input_file_path] [output_file_path]

convert [input_file_path] -type Grayscale [output_file_path]

tesseract [image_path] [file_name]

它只会显示粗体字

谢谢

【讨论】:

【参考方案3】:

我的建议是对完整图像执行 OCR。

我已经对图像进行了预处理以获得灰度图像。

import cv2
image_obj = cv2.imread('1D4bB.jpg')
gray = cv2.cvtColor(image_obj, cv2.COLOR_BGR2GRAY)
cv2.imwrite("gray.png", gray)

我已经从终端对图像运行了 tesseract,在这种情况下,准确率似乎也超过了 90%。

tesseract gray.png out

3579 10 1 7 148
3142 9 o 5 10
2962 3 o 7 101
2214 2 2 7 99
2205 1 3 6 78
Score Kills Assists Deaths Connection
8212 15 1 4 4o
7198 7 3 6 40
6307 6 1 5 60
5640 2 3 6 80
4884 1 1 5 so

以下是一些建议 -

    请勿直接使用 image_to_string 方法,因为它将图像转换为 bmp 并以 72 dpi 保存。 如果您想使用 image_to_string,请覆盖它以将图像保存为 300 dpi。 您可以使用 run_tesseract 方法,然后读取输出文件。

我运行 OCR 的图像。

解决这个问题的另一种方法是裁剪数字并深入到神经网络进行预测。

【讨论】:

你能添加你运行 tesseract 扫描的图像吗?关于 1、2、3,我已经读取了转换为灰度的图像,然后将其保存为 300+ dpi,然后进行了扫描,所以你告诉如果我将 300 dpi 图像传递给 image_to_string 它会被转换为 72 dpi? 不,image_to_string 函数不接受自定义 dpi 的参数。你需要覆盖它。 我可能会从以下灰度中得到一个文本。我从那里开始然后冒险深入并尝试了很多东西。所以为了这对我有用,我必须清除背景并将图像分成 4 裁剪团队名称和其他得分值的照片。我现在所拥有的不是您刚才所说的问题。我正在尝试解决其他问题,这就是为什么无法识别纯空白图像的原因。请参阅我使用 Sunnypage 来识别和训练新语言。使用它时,如果您尝试识别仅 2 列,即使图像是 300dpi 或 1000dpi。 但是如果我手动选择要识别的区域,那么它会给我完美的输出。手头的问题是 tesseract 实际上在处理图像时跳过了随机区域,即使它的 300 dpi 和清晰背景只剩下文本。我从你所做的从灰度中提取数据开始,但它始终如一地工作是非常不准确的。你需要做我所做的,关于球员姓名,我大部分时间都得到 99.9% 的准确率,但是.我在随机跳过检测列时遇到了关于团队分数的问题。 谁对答案投了反对票,请说明原因【参考方案4】:

我认为您必须先对图像进行预处理,对我有用的更改是: 假设

import PIL
img= PIL.Image.open("yourimg.png")

把图片放大,我一般把图片放大一倍。

img.resize(img.size[0]*2, img.size[1]*2)

灰度图像

img.convert('LA')

让字符加粗,你可以在这里看到一种方法:https://blog.c22.cc/2010/10/12/python-ocr-or-how-to-break-captchas/ 但是这种方法比较慢,如果你使用它,我建议使用另一种方法

使用 gimpfu 选择、反转选择、填充黑色、白色

图像 = pdb.gimp_file_load(文件,文件) 层 = pdb.gimp_image_get_active_layer(image) 替换= 2 pdb.gimp_by_color_select(layer,"#000000",20,REPLACE,0,0,0,0) pdb.gimp_context_set_foreground((0,0,0)) pdb.gimp_edit_fill(层,0) pdb.gimp_context_set_foreground((255,255,255)) pdb.gimp_edit_fill(layer,0)

pdb.gimp_selection_invert(图像) pdb.gimp_context_set_foreground((0,0,0))

【讨论】:

在我尝试清理图像之前检查我制作图像的 3 倍大小的代码。请在回复之前检查代码。查看屏幕截图和示例图像。我清除了所有内容,使其变成黑白已经完成了一切你只是输入了答案我现在面临的问题是当像这样的清晰背景图像i.stack.imgur.com/tytSQ.jpg 作为输入输入到 tesseract 时,它无法检测到除 2 列之外的其他列,而在此图像的情况下i.stack.imgur.com/tytSQ.jpg 它正确识别它。我的问题是奇怪行为的具体原因 如果有人可以给我解释它和可能的修复它【参考方案5】:
fn = 'image.png'
img = cv2.imread(fn, 0)
img = cv2.bilateralFilter(img, 20, 25, 25)
ret, th = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Image.fromarray(th)
print(pytesseract.image_to_string(th, lang='eng'))

【讨论】:

请始终将您的答案放在上下文中,而不仅仅是粘贴代码。有关详细信息,请参阅here。

以上是关于tesseract 的 OCR 结果高度不一致的主要内容,如果未能解决你的问题,请参考以下文章

如何提高tesseract的OCR结果

使用模糊文本改进 Tesseract OCR 结果

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

没有从 Tesseract OCR 中获得有效的结果作为 newocr 生产

通过删除特殊字符改进 Tesseract OCR 结果

使用 tesseract 识别车牌