【Lecture 5.2】The (Py)Tesseract Library

2023-05-16

文章目录

    • Lecture: The (Py)Tesseract Library
      • 对文本图像的处理
        • 改变图片大小
        • greyscale - 灰度图
        • binarization 二值图
    • Tesseract and Photographs 对图像的OCR识别
    • Jupyter Widgets (Optional)

Lecture: The (Py)Tesseract Library

让我们首先使用 import PIL 库并展示 text图像

from PIL import Image

image = Image.open('readonly/text.png')
display(image)

image-20200604221358198

让我们import pytesseract 库,并使用 dir() 函数看看这个库的一些函数

import pytesseract
dir(pytesseract)
---
['Output',
 'TesseractError',
 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__path__',
 '__spec__',
 'get_tesseract_version',
 'image_to_boxes',
 'image_to_data',
 'image_to_osd',
 'image_to_pdf_or_hocr',
 'image_to_string',
 'pytesseract']

只有少量的函数,我觉得image_to_string 是合适的,我们使用 help() 查看一下

help(pytesseract.image_to_string)
---
Help on function image_to_string in module pytesseract.pytesseract:

image_to_string(image, lang=None, config='', nice=0, output_type='string')
    Returns the result of a Tesseract OCR run on the provided image to string

可见这个函数第一个输入参数是 an image, 剩下的是一些可选参数,返回的是OCR的结果。

这是因为pytesseract库下面正在调用C++库,该库完成了所有艰苦的工作,而作者只是将所有调用传递给了底层tesseract可执行文件。 在使用python库时,这是一个常见问题,这意味着我们需要执行一些 Web 搜索,以便了解如何与tesseract进行交互。

还有一个问题是没有说明输入参数 image 具体是什么,Is it a string to an image file? A PILLOW image?Something else? 我们通过查看源码了解到是一个 PILLOW image。因此输入一个 PIL image是可以作为这个函数的参数的。

为这个函数撰写说明文档

Hint: The doc line we needed was :param image: A PIL Image.Image file or an ndarray of bytes

Ok, lets try and run tesseract on this image

from PIL import Image

image = Image.open('readonly/text.png')  # 代开文件为PILLOW image
display(image)

text = pytesseract.image_to_string(image)
print(text)
# 输出结果
Behold, the magic of OCR! Using
pytesseract, we’ll be able to read the
contents of this image and convert it to
text

More Tesseract - 更复杂的情况

前面我们使用的是清晰的 unambiguous 图片。现在我们试试混淆的图片

from PIL import Image
img = Image.open('readonly/Nosiy_OCR.PNG')
display(img)

image-20200604221323732

现在我们尝试使用 tsseract -OCR 函数

import pytesseract
text = pytesseract.image_to_string(Image.open('readonly/Noisy_OCR.PNG'))
print(text)
# 输出结果
e magic of OCR! Using pytesseract,
le to read the contents of this

 

d convert it to text

识别的不是很好,我们现在采用一种方法:change the size of the image

对文本图像的处理

改变图片大小

import PIL
# 设置图片的 basewidth
basewidth = 600

img = Image.open('readonly/Noisy_OCR.PNG')
# 对图片的比例 ratio 保持不变,我们使用basewidth除以实际的width
wpercent = (basewidth / float(image.size[0]))
# 则设置后的图片高度等于 实际高度乘以这个比例
hsize = int(float(img.size[1]) * float(wpercent))
# 最后,让我们调整图像大小。 抗锯齿 antialiasing是一种调整线条大小以使其平滑的特定方法
img = img.resize((basewidth, hsize), PIL.Image.ANTIALIAS)

# 另存为,展示
img.save('resized_noise.png')
display(img)
# and run OCR
text = pytesseract.image_to_string(Image.open('resized_nois.png')) 
print(text)
e magic of OCR! Using pytesseract,
le to read the contents of this
d convert it to text

通过 resize 图片大小OCR的效果没有提升,下面我们把图像转为灰度图。

greyscale - 灰度图

我们看 PILLOW documention可以发现一种最简单的转换成灰度图的方法是使用 convert() 函数。

img = Image.open('readonly/Noisy_OCR.png')
img = img.convert('L')
---
# Now lets save that image
img.save('greyscale_noise.jpg')
# And run OCR on the greyscale image
text = pytesseract.image_to_string(Image.open('greyscale_noise.jpg')) 
print(text)
# 输出结果
Behold, the magic of OCR! Using pytesseract,
we'll be able to read the contents of this
image and convert it to text

运行效果非常好。

binarization 二值图

这意味着要分为两个不同的部分-在这种情况下为黑色和白色。 二值化通过称为阈值threshold的过程进行。 如果像素值大于阈值,它将被转换为黑色像素; 如果它低于阈值,它将被转换为白色像素。

在 PILLOW 里调用函数:

img = Image.open('readonly/Noisy_OCR.PNG').convert('1')
img.save('black_white_noise.jpg')
display(img)

image-20200604222044753

不过你也可以自己写二值化图像的函数:

def binarize(image_to_transform, threshold):
    # 先转换成单通道的灰度图
 	output_image=image_to_transform.convert("L")
 
 	for x in range(output_image.width):
     	for y in range(output_image.height):
         	# 比较每一个像素
         	if output_image.getpixel((x,y))< threshold: #注意这个函数的参数是一个元组(坐标)
             	output_image.putpixel( (x,y), 0 )
         	else:
             	output_image.putpixel( (x,y), 255 )
 	#now we just return the new image
    return output_image

让我们在不同阈值范围内测试此功能。 请记住,您可以使用 range() 函数生成不同步长的数字列表。 使用开始,停止和步长调用 range()。 因此,让我们尝试 range(0,257,64),它应该生成5个不同阈值的图像

for thresh in range(0,257,64):
    print("Trying with threshold " + str(thresh))
 	# Lets display the binarized image inline
 	display(binarize(Image.open('readonly/Noisy_OCR.PNG'), thresh))
 	# And lets use tesseract on it. It's inefficient to binarize it twice but this is just for
 	# a demo
 	print(pytesseract.image_to_string(binarize(Image.open('readonly/Noisy_OCR.PNG'), thresh)))

Tesseract and Photographs 对图像的OCR识别

让我们尝试一下其它的图片OCR识别,例如一个门头:

from PIL import Image
import pytesseract

image = Image.open('readonly/storefront.jpg')
display(image)
# ocr
pytesseract.image_tostring(image) # 这个方法的对象是 PIL image

image-20200604222759084

''

OCR识别返回空的字符串,说明 Tesseract不能识别这幅图。我们在上一节学习过 裁剪图片的方法,crop the images;我们在这里尝试对原图进行裁剪。

# First, lets set the bounding box. In this image the store name is in a box
# bounded by (315, 170, 700, 270)
bounding_box = (315, 170, 700, 270)
# 对image进行裁剪
title_image=image.crop(bounding_box)

# 展示裁剪后的图片并对其进行OCR识别
display(titlr_image)
pytesseract.image_to_string(title_image)

image-20200612145308979

'FOSSIL'

太好了,我们看到了如何通过减少一些问题来使该工作得以实现。 因此,现在我们已经能够拍摄图像,对其进行预处理(灰度图,二值化,裁剪),以至于希望看到文本,然后将其转换为python可以理解的字符串。

观察图片可以发现墙上也有 商店的名字的标志。我们现在试试能不能识别它。

# 首先我们 determine a bounding box来裁切这个小的标志
bounding_box = (900, 420, 940, 445)
little_sign = image.crop((990, 420, 940, 445))
display(little_sign)

image-20200604223005142

这是一个很小的图片,我们首先对它 resize

# 放大十倍
new_size = (little_sign.width*10, little_sign.height*10)
# Now lets check the docs for resize()
help(little_sign.resize)
---
Help on method resize in module PIL.Image:

resize(size, resample=0, box=None) method of PIL.Image.Image instance
    Returns a resized copy of this image.
    
    :param size: The requested size in pixels, as a 2-tuple:
       (width, height).
    :param resample: An optional resampling filter.  This can be
       one of :py:attr:`PIL.Image.NEAREST`, :py:attr:`PIL.Image.BOX`,
       :py:attr:`PIL.Image.BILINEAR`, :py:attr:`PIL.Image.HAMMING`,
       :py:attr:`PIL.Image.BICUBIC` or :py:attr:`PIL.Image.LANCZOS`.
       If omitted, or if the image has mode "1" or "P", it is
       set :py:attr:`PIL.Image.NEAREST`.
       See: :ref:`concept-filters`.
    :param box: An optional 4-tuple of floats giving the region
       of the source image which should be scaled.
       The values should be within (0, 0, width, height) rectangle.
       If omitted or None, the entire source is used.
    :returns: An :py:class:`~PIL.Image.Image` object.
# 我们可以看到在 resize 的时候可以选用不同的 filters 对图像进行处理,我们选用 Image.NEAREST 试试看
display(little_sign.resize(new_size, Image.NEAREST))
image-20200604223225279

上面是对图像进行resize操作时默认的 filter,让我们看看所有的filter 的效果

options=[Image.NEAREST, Image.BOX, Image.BILINEAR, Image.HAMMING, Image.BICUBIC, Image.LANCZOS]
for option in options:
    # lets print the option name
    print(option)
    # lets display what this option looks like on our little sign
    display(little_sign.resize(new_size, option))

在这种情况下,Image.LANCZOS和Image.BICUBIC筛选器可以很好地完成工作。 让我们看看我们是否能够从调整后的图像中识别出文字

new_size = (little_sign.width*10, little_sign.height*10)
bigger_sign = little_sign.resize(new_size, Image.BICUBIC)
# ocr输出
pytesseract.image_to_string(bigger_sign)
''

并没有识别,

我们再对它尝试二值化 binarize,我么前面编写的二值化程序:

def binarize(image_to_transform, threshold):
    output_image=image_to_transform.convert("L")
    for x in range(output_image.width):
        for y in range(output_image.height):
            if output_image.getpixel((x,y))< threshold:
                output_image.putpixel( (x,y), 0 )
            else:
                output_image.putpixel( (x,y), 255 )
    return output_image

# Now, lets apply binarizations with, say, a threshold of 190, and try and display that
# as well as do the OCR work
binarized_bigger_sign = binarize(bigger_sign, 190)
dispay(binarized_bigger_sign)
pytesseract.image_to_string(binarized_bigger_sign)

image-20200604223537291

'Lae'

好的,该文本几乎没有用。我们应该如何选择最佳的二值化方法来使用? 好的,让我们尝试一些非常简单的方法, 我们正在尝试检测一个英文单词“ FOSSIL”。 如果我们尝试从0到255的所有二值化,并查看列表中是否有英文单词,这可能是一种方法。 因此,让我们看看是否可以编写例程来执行此操作。

# 首先加载英语字符的list 26个英语字母,存放在事先准备的地址
eng_dict=[]
with open ("readonly/words_alpha.txt", "r") as f:
    data=f.read()
    # now we want to split this into a list based on the new line characters
    eng_dict = data.split("\n")  # 将字符串分成一个列表

# 现在,让其遍历所有可能的阈值并寻找英文单词,如果存在则将其打印出来
for i in range(150,170):
    # 让我们将其二值化并将其转换为string值 命名为 strng
    strng = pytesseract.image_to_string(binarize(bigger_sign,i))
    # 我们要从文本中删除非字母字符,例如([%$]),这是首先执行的一种简短方法,让我们仅将字符串转换为小写
    strng=strng.lower()
    # then lets import the string package - it has a nice list of lower case letters
    import string
    # 现在让我们遍历字符串,逐个字符地查看它,并将其放入比较text中
    comparison=''
    for character in strng:
        if character in string.ascii_lowercase: # 是符串类型的话
            comparison = comparison + character
    # 最后,让我们在字典文件中搜索比较
    if comparison in eng_dict:
        # and print it if we find it
        print(comparison)
fossil
si
fossil
fossil
gas
gas
sl
sl
sil

好吧,这并不完美,但是我们看到 fossil 在字典中还有其他值。 这不是清除OCR数据的好方法。 在实践中使用语言或领域特定的词典可能很有用,尤其是在生成针对特定语言(例如医学知识库或位置)的搜索引擎时。

至此,您已经了解了如何处理图像并将其转换为文本。 在本课程的下一个模块中,我们将更深入地研究计算机视觉库,该库可让我们检测其他事物。 然后,继续进行最终的项目!

Jupyter Widgets (Optional)

在这个简短的演讲中,我想向您介绍Jupyter笔记本开发环境中称为小部件Widgets 的更高级功能之一。 有时您想与已创建的函数进行交互,并使用不同的参数多次调用它。 例如,如果我们想在图像的一部分周围绘制一个红色框,以尝试微调裁剪位置。 小部件是在浏览器中快速完成此操作的一种方法,而无需学习如何编写大型桌面应用程序。

让我们来看看。 首先,我们要从PILLOW包中导入Image和ImageDraw类

from PIL import Image, ImageDraw

# 然后导入 interact class from the widgts package
from ipywidgets import interact
# 我们将使用交互来注释函数

image = Image.open('readonly/storefront.jpg')

好的,我们的设置完成了。 现在,我们将使用交互装饰器interact decorator来表示要包装wrap的python函数。 我们使用 @ 符号进行此操作。

这将使用一组与要调用的函数相同的参数。 然后Jupyter将在屏幕上绘制一些滑块,让我们操纵这些值。

Decorators, which is what the @ sign is describing, are standard python statements and just a short hand for functions which wrap other functions. @ 符号描述的装饰器是标准的python语句,只是包装其他函数的函数的简写形式。 不过,它们有点先进,因此我们在本课程中没有讨论它们.

@interact(left=100, top=100, right=200, bottom=200)

def draw_border(left, top, right, bottom):
    img = img.copy()
    drawing_object = ImageDraw.Draw(img)
    drawing_object.rectangle((left, top, right, bottom), fill=None, outline='red')
    display(img)

image-20200604224147701

Jupyter小部件无疑是高级领域,但是如果您想探索更多内容,则可以阅读此处的信息:https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Lecture 5.2】The (Py)Tesseract Library 的相关文章

  • 如何使用 OCR 检测图像中的下标数字?

    我在用tesseract对于 OCR 通过pytesseract绑定 不幸的是 当我尝试提取包含下标样式数字的文本时遇到困难 下标数字被解释为字母 例如 在基本图像中 我想将文本提取为 CH3 即我不关心知道该数字3是图像中的下标 我对此的
  • 如何设置和运行适用于 PHP 的 Tesseract OCR(开源)?

    我已经根据GitHUb上提供的文档通过MacPorts安装了Tesseract OCR 并且安装成功 并且 但是 我正在尝试使用 Tesseract OCR for PHP https github com thiagoalessio te
  • 使用 Android NDK 构建 Tesseract

    我正在跟进this http kurup87 blogspot ca 2012 03 android ocr tutorial image to text html编译教程this https github com rmtheis tess
  • “language_model_penalty_non_dict_word”在 tesseract 3.01 中没有效果

    我正在设置language model penalty non dict word通过 Tesseract 3 01 的配置文件 但其值没有任何效果 我尝试过使用多个图像及其多个值 但每个图像的输出始终相同 另一位用户也注意到了同样的情况在
  • 如何使用 Tesseract OCR 从图像中读取表格数据?

    有谁知道如何从图像中读取和解析任何表格数据 我正在使用 asp net 应用程序 并且已使用 Tesseract OCR API 成功读取数据 但无法从图像读取表格 请用c 代码给出解决方案 None
  • Tesseract OCR 无法检测数字

    我正在尝试用 python 中的 tesseract 检测一些数字 下面您将看到我的起始图像以及我可以将其简化为的内容 这是我用来获取它的代码 import pytesseract import cv2 import numpy as np
  • Tesseract OCR:解析表格单元格

    我正在使用 cmd 中的 Tesseract OCR v4 0 0 alpha 从如下所示的表格的 png 中提取文本 我希望 Tesseract OCR 能够解析一个单元格中的内容 然后再转到下一个单元格 我不想继续 行 中的下一个单词
  • OCR 处理前的图像预处理

    我当前的项目涉及将 pdf 中的文本转录为文本文件 我首先尝试将图像文件直接放入 OCR 程序 tesseract 中 但效果不佳 原始图像文件基本上是旧报纸 并且有一些背景噪音 我确信 tesseract 存在问题 因此 我尝试在将图像输
  • 目录:资产/tessdata

    我从 github 下载了 OCR 文本识别器 我的问题是 我想在不在线的情况下启动我的应用程序 但每次我在手机上安装 apk 时 它都会开始下载英语和 tesseract OCR 引擎 我找到了一个在线指南 其中说我必须在资产文件夹中创建
  • 从图像中提取线条以输入 OCR - Tesseract

    我在 pycon 上看这个演讲http youtu be B1d9dpqBDVA t 15m34s http youtu be B1d9dpqBDVA t 15m34s15 33 左右 演讲者谈到从图像 收据 中提取线条 然后将其输入 OC
  • Android 中最好的 OCR(光学字符识别)示例 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想要一个在android中运行OCR的例子 我做了一些研究并找到了一个在android中实现OCR的例子 https github co
  • 使用Python从具有两列或三列数据的图像中使用OCR读取图像中的文本

    在示例图像中 仅作为参考 我的图像将具有相同的图案 一个页面具有完整的水平文本 其他页面具有两个水平文本列 如何在python中自动检测文档的模式并逐一读取另一列数据 我将 Tesseract OCR 与 Psm 6 一起使用 它是水平读取
  • 如何从收据中提取相关信息

    我正在尝试结合使用 Opencv Tesseract 和 Keras 从一系列不同的收据中提取信息 该项目的最终结果是 我应该能够使用手机拍摄收据照片 并从该照片中获取商店名称 支付类型 卡或现金 支付金额和找零 到目前为止 我已经使用 O
  • Tess-2 OCR 不工作

    我试图在 Android 上使用 tess two 从图像中获取文本 但这给了我一个非常糟糕的结果 01 16 12 00 25 339 I Tesseract native 29038 Initialized Tesseract API
  • 使用 OpenCV 对 Tesseract OCR 进行图像预处理

    我正在尝试开发一个应用程序 它使用 Tesseract 来识别手机摄像头拍摄的文档中的文本 我使用 OpenCV 来预处理图像以实现更好的识别 应用高斯模糊和阈值方法进行二值化 但结果非常糟糕 Here https s6 postimg c
  • 无法在 Mac 上安装 Tesseract-OCR

    我正在尝试使用 pytesseract 在 python 2 7 14 中制作 OCR 程序 当我运行我的代码时 from PIL import Image import pytesseract print pytesseract imag
  • 如何将 Tesseract 导入 Angular2 (TypeScript)

    我正在尝试将 Tesseract 导入 Angular2 TypeScript 我可以看到它保存到 node modules 文件夹中 但是在使用时 import Tesseract from types tesseract js it s
  • 在tesseract中添加任何traineddata文件并在IOS中使用

    我能够编译英语版本 该版本已经在 tesseract 的示例中 但无法添加其他语言 例如 ara traineddata 我正在做这样的事 Tesseract tesseract Tesseract alloc initWithDataPa
  • Tesseract 是否会忽略扫描文档中的任何非文本区域?

    我正在使用 Tesseract 但我不知道它是否忽略任何非文本区域并仅针对文本 我是否必须删除任何非文本区域作为预处理步骤以获得更好的输出 Tesseract 有一个非常好的算法来检测文本 但它最终会给出误报匹配 理想情况下 您应该在将图像
  • Tess4j - Pdf 到 Tiff 到 tesseract - “警告:分辨率 0 dpi 无效。使用 70 代替。”

    我正在使用 tess4j net sourceforge tess4j tess4j 4 4 0 并尝试对 pdf 文件进行 OCR 因此 据我了解 我必须首先将 pdf 转换为 tiff 或 png 其中有任何建议吗 我这样做是这样的 t

随机推荐