无法提取图像中嵌入的accuarte文本

2024-04-19 20:16:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我在python中编写了一个脚本,使用pytesseract来获取嵌入在图像中的文本。当我运行我的脚本时,scraper的工作很奇怪,这意味着我得到的结果文本与图像中的文本完全不同。在

我尝试过的脚本:

import requests, io, pytesseract
from PIL import Image

response = requests.get('http://skoleadresser.no/4DCGI/WC_Pedlex_Adresse/864928.jpg')
img = Image.open(io.BytesIO(response.content))
imagetext = pytesseract.image_to_string(img)
print(imagetext)

图像中的文本如下所示:

enter image description here

结果我得到了:

^{pr2}$

我怎样才能得到准确的结果?在


Tags: fromio图像image文本import脚本img
1条回答
网友
1楼 · 发布于 2024-04-19 20:16:18

tl;dr:

import requests
import io
import pytesseract
from PIL import Image

response = requests.get('http://skoleadresser.no/4DCGI/WC_Pedlex_Adresse/864928.jpg')
img = Image.open(io.BytesIO(response.content))
width, height = img.size
new_size = width*6, height*6
img = img.resize(new_size, Image.LANCZOS)
img = img.convert('L')
img = img.point(lambda x: 0 if x < 155 else 255, '1')
imagetext = pytesseract.image_to_string(img)

print(imagetext)

结果:

Adresse Prof. Olav Hanssens vei 7 A
4021 Stavanger

Telefon 52 70 90 00

Telefaks 52 70 90 01

E-post vanja.strand@aof.no

说明/操作方法

OCR的设计目的是扫描打印、手写或打印的文档中的字母,这些文档以高分辨率扫描,基本上没有模糊-可能存在一些工具专门扫描低分辨率和大量模糊的数字图像,但一般情况下,他们无法以任何合理的速度从这些输入数据中猜出字母-只是太模糊,像素太少,OCR工具可以利用这些数据做出有用的东西。在

这听起来好像没有什么机会让它工作-只是放大而不做任何进一步的处理并不能做到这一点,正如您稍后将看到的那样,图像仍然离打印/打印文本之类的任何东西都太远了。在

我对缩放因子做了一些尝试和错误的尝试,发现6对这张图片的效果最好,因此:

^{pr2}$

在不进行任何重新采样的情况下将其放大6倍:

img = img.resize(new_size)

给我们这个图像,这是非常无用的,因为它基本上是与以前完全相同的不可读图像,只是1px*1px现在是6px*6px(请注意几乎相交于字母之间的灰色区域-尤其是Prs和{}会导致大问题):

Scaled up by factor 6 without resampling

幸运的是,有一些重采样公式给出了非常好的结果,对于PIL,有PIL.Image.LANCZOS(其中之一)应用了Lanczos resampling formula

img = img.resize(new_size, Image.LANCZOS)

Scaled up by factor 6 with LANCZOS resampling

一开始看起来差别不大,但是现在我们有了一个更好的字母填充,而不是那些黑色和灰色的块-并且一个更自然的模糊,我们可以在下一步工作。现在看一下Prs和{},我们发现它们不再严重相交。在

为了使图像看起来更像实际打印的文档,通过去除模糊使其变成黑白的,接下来需要做的是使图像使用mode L(8位像素黑白)

img = img.convert('L')

Converted to 8 bit b/w

当然,这几乎没有区别,因为源图像是白色背景上的黑色文本,但仍然需要这一步来处理亮度阈值,将其转换为黑白图像。在

这是通过计算图像中的每个像素的8位值来完成的-开始尝试的一个好值是128,它是50%黑色:

img = img.point(lambda x: 0 if x < 128 else 255, '1')

这给了我们一个太薄的文本-OCR工具将大多数5识别为S,而一些{}则识别为O

b/w conversion at threshold 128

现在将亮度阈值设置为200,我们得到以下图像:

b/w conversion at threshold 200

OCR工具可以处理这些文本,因为它看起来就像一个粗体字体—但是正如前面所说,OCR工具的目标是扫描正常打印的文本,因此它很可能无法识别图像中的实际粗体文本,因为与普通文本相比,粗体文本太过粗体。在

让我们将阈值设置在128200之间,这样我们就得到了一个自然的打印文本—通过做一些尝试和错误,我发现{}工作得很好,并使其看起来与原始图像中的字体权重相同:

b/w conversion at threshold 155

由于这看起来很像是对打印不良的黑白文档进行高分辨率扫描,OCR工具现在可以正常工作了。在

相关问题 更多 >