SIM*_*SIM 6 python web-scraping python-3.x python-tesseract
我已经写在一个脚本python使用pytesseract以获得嵌入图像中的文本.当我运行我的脚本时,刮刀很奇怪地完成它的工作,这意味着我得到的文本与图像中的文本完全不同.
我试过的脚本:
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)
Run Code Online (Sandbox Code Playgroud)
图像中的文字如下:
结果我有:
Adresse WM 0an Hanssensm 7 A
4u21 Slavanqer
warm 52 m so no
Te‘efaks 52 m 90 m
E'Dus‘x Van’s strand?anlmu
Run Code Online (Sandbox Code Playgroud)
我怎样才能得到准确的结果?
TL;博士:
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)
Run Code Online (Sandbox Code Playgroud)
结果是:
Adresse教授Olav Hanssens vei 7 A
4021 StavangerTelefon 52 70 90 00
Telefaks 52 70 90 01
电子邮件vanja.strand@aof.no
OCR设计用于扫描以高分辨率扫描的打印,手写或打印文档中的字母,基本上没有模糊 - 可能存在一些专用于扫描具有低分辨率和大量模糊的数字图像的工具,但是一般来说,它们无法以任何合理的速率猜测来自这些输入数据的字母 - 它太模糊,而且像素太少,以至于OCR工具可以使这些数据变得有用.
这可能听起来似乎没有机会让它工作 - 尽管只是在不进行任何进一步处理的情况下进行扩展并不能解决问题,正如您稍后将会看到的那样,图像仍然离类似的东西太远打印/打印文本.
我用缩放因子做了一些试验和错误,发现6对这个图像效果最好,所以:
width, height = img.size
new_size = width*6, height*6
Run Code Online (Sandbox Code Playgroud)
按系数6进行扩展,无需重新采样:
img = img.resize(new_size)
Run Code Online (Sandbox Code Playgroud)
为我们提供了这个形象,这是非常无用的,因为它基本上是完全相同的不可读的形象和以前一样,只是1px的*1px的是现在6像素*6像素(注意其中的字母之间几乎相交的灰色地带-尤其是Pr,s并k会导致大问题):
幸运的是,有一些重新采样公式给出了非常好的结果,对于PIL,有PIL.Image.LANCZOS(其中)应用Lanczos重采样公式:
img = img.resize(new_size, Image.LANCZOS)
Run Code Online (Sandbox Code Playgroud)
起初差异可能不是那么大 - 但现在我们有更好的填充字母而不是那些黑色和灰色的块 - 以及更自然的模糊,我们可以在下一步中使用.现在来看Pr,s和k我们看到,他们不相交这个厉害了.
接下来需要做什么才能使图像看起来更像实际打印的文档,通过去除模糊使其成为黑白 - 第一步是使图像工作mode L(8位像素b/w)
img = img.convert('L')
Run Code Online (Sandbox Code Playgroud)
当然,由于源图像是白色背景上的黑色文本,因此几乎没有区别 - 但您仍需要此步骤才能使用亮度阈值将其转换为ab/w图像.
这是通过评估图像中的每个像素通过其8位值来完成的 - 开始尝试的一个好值128是50%黑色:
img = img.point(lambda x: 0 if x < 128 else 255, '1')
Run Code Online (Sandbox Code Playgroud)
这给了我们一个文本就是显得过于单薄-的OCR工具将识别大多数5为S一些0的如O:
现在设置亮度阈值,200我们得到以下图像:
OCR工具可以处理这个文本,因为它看起来就像一个粗体字 - 但如前所述,OCR工具的目的是扫描正常打印的文本,因此很可能无法识别图像中的实际粗体文本,因为它会是与普通文本相比过于大胆的方式.
让我们设置介于两者之间的阈值128,200以便我们得到一个自然的印刷文本 - 通过做一些试验和错误我发现155工作得很好,使它看起来像原始图像中相同的字体重量:
由于这看起来非常类似于打印不良的黑白文档的高分辨率扫描,因此OCR工具现在可以正常工作.
| 归档时间: |
|
| 查看次数: |
1322 次 |
| 最近记录: |