【问题标题】:Unable to extract a word out of an image无法从图像中提取单词
【发布时间】:2018-11-29 08:15:48
【问题描述】:

我在python 中结合pytesseract 编写了一个脚本来从图像中提取一个单词。该图像中只有一个单词TOOLS,这就是我所追求的。目前我的以下脚本给了我错误的输出,即WIS。如何获取文本?

Link to that image

这是我的脚本:

import requests, io, pytesseract
from PIL import Image

response = requests.get('http://facweb.cs.depaul.edu/sgrais/images/Type/Tools.jpg')
img = Image.open(io.BytesIO(response.content))
img = img.resize([100,100], Image.ANTIALIAS)
img = img.convert('L')
img = img.point(lambda x: 0 if x < 170 else 255)
imagetext = pytesseract.image_to_string(img)
print(imagetext)
# img.show()

这是我运行上述脚本时修改后图像的状态:

我得到的输出:

WIS

预期输出:

TOOLS

【问题讨论】:

  • 如果 OCR 就这么简单......

标签: python python-3.x web-scraping python-imaging-library python-tesseract


【解决方案1】:

关键是将图像转换与tesseract 能力相匹配。您的主要问题是字体不是通常的字体。你只需要

from PIL import Image, ImageEnhance, ImageFilter

response = requests.get('http://facweb.cs.depaul.edu/sgrais/images/Type/Tools.jpg')
img = Image.open(io.BytesIO(response.content))

# remove texture
enhancer = ImageEnhance.Color(img)
img = enhancer.enhance(0)   # decolorize
img = img.point(lambda x: 0 if x < 250 else 255) # set threshold
img = img.resize([300, 100], Image.LANCZOS) # resize to remove noise
img = img.point(lambda x: 0 if x < 250 else 255) # get rid of remains of noise
# adjust font weight
img = img.filter(ImageFilter.MaxFilter(11)) # lighten the font ;)
imagetext = pytesseract.image_to_string(img)
print(imagetext)

瞧,

TOOLS

被识别。

【讨论】:

  • 看起来img = img.filter(ImageFilter.MaxFilter(11)) 是关键:)
  • 你能详细说明img.convert('L')ImageEnhance.Color(img).enhance(0)之间的区别吗?在指令排序方面是否有任何最佳实践?
  • 1) MaxFilter 所做的基本上是形态侵蚀。 2)差异主要是概念上的。 .convert('L') 将颜色转换为灰度,Color(img).enhance(0) 去除色调。 3) 指令顺序遵循处理逻辑,即去除字母图案,转换成黑白图像,调整字体粗细,发送至tesseract。如果背景不是白色,我会使用颜色通道并尝试其他方法,可能检测长边。由于它是一个单一的图像,我只是添加了一些可以完成工作并且在某种程度上很强大的东西。
【解决方案2】:

您的实施的关键问题在于:

img = img.resize([100,100], Image.ANTIALIAS)
img = img.point(lambda x: 0 if x < 170 else 255)

您可以尝试不同的尺寸和不同的阈值:

import requests, io, pytesseract
from PIL import Image
from PIL import ImageFilter

response = requests.get('http://facweb.cs.depaul.edu/sgrais/images/Type/Tools.jpg')
img = Image.open(io.BytesIO(response.content))
filters = [
    # ('nearest', Image.NEAREST),
    ('box', Image.BOX),
    # ('bilinear', Image.BILINEAR),
    # ('hamming', Image.HAMMING),
    # ('bicubic', Image.BICUBIC),
    ('lanczos', Image.LANCZOS),
]

subtle_filters = [
    # 'BLUR',
    # 'CONTOUR',
    'DETAIL',
    'EDGE_ENHANCE',
    'EDGE_ENHANCE_MORE',
    # 'EMBOSS',
    'FIND_EDGES',
    'SHARPEN',
    'SMOOTH',
    'SMOOTH_MORE',
]

for name, filt in filters:
    for subtle_filter_name in subtle_filters:
        for s in range(220, 250, 10):
            for threshold in range(250, 253, 1):
                img_temp = img.copy()
                img_temp.thumbnail([s,s], filt)
                img_temp = img_temp.convert('L')
                img_temp = img_temp.point(lambda x: 0 if x < threshold else 255)
                img_temp = img_temp.filter(getattr(ImageFilter, subtle_filter_name))
                imagetext = pytesseract.image_to_string(img_temp)
                print(s, threshold, name, subtle_filter_name, imagetext)
                with open('thumb%s_%s_%s_%s.jpg' % (s, threshold, name, subtle_filter_name), 'wb') as g:
                    img_temp.save(g)

看看什么适合你。

我建议您在保持原始比例的同时调整图像大小。你也可以尝试一些替代img_temp.convert('L')

迄今为止最好的:TWlsT0018

您可以尝试手动操作图像,看看是否可以找到一些可以提供更好输出的编辑(例如http://gimpchat.com/viewtopic.php?f=8&t=1193

通过提前了解字体,您可能也可以获得更好的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 2017-05-14
    • 2018-09-05
    • 2021-09-19
    • 1970-01-01
    相关资源
    最近更新 更多