上一篇文章中我们学习了用于光学字符识别的 Tesseract。本文将探讨如何在Python脚本中调用Tesseract库。
然后我们应用Tesseract程序在一个非常小的示例图像集上对OCR的性能进行测试和评估。
当前景文本与背景有非常清晰的分割时,Tesseract效果最好。在实践中,保证这些类型的分割可能极具挑战性。因此,我们倾向于训练特定领域的图像分类器和检测器。
然而,当我们需要将OCR应用于我们自己的项目时,需要知道如何通过Python语言访问Tesseract OCR(前提是我们可以对图像进行很好的分割)。
涉及光学字符识别的示例项目可能包括 构建一个文档扫描器,该项目需要从扫描仪中提取文本信息,或者您正在运行一个扫描纸质病历的程序,并且您希望将这些信息放入符合HIPA标准的数据库中。
在这篇博文中我们将学习如何在Python程序中调用Tesseract。在本教程结束时,您将能够把图像中的文本转换为Python字符串数据类型。
这篇博客文章分为三个部分。
需要使用 pip
安装 pytesseract,也要安装 Pillow 用于加载磁盘中的图像。
$ pip install pillow
$ pip install pytesseract
先创建一个文件 ocr.py
:
from PIL import Image
import pytesseract
import argparse
import cv2
import os
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
help="path to input image to be OCR'd")
ap.add_argument("-p", "--preprocess", type=str, default="thresh",
help="type of preprocessing to be done")
args = vars(ap.parse_args())
上面主要是命令行参数解析的相关程序,有两个参数: - --image:要传入OCR系统的图片路径 - --preprocess:预处理方法,可以接受两个值,thresh
或者 blur
。
接下来,我们将加载图像,将其二值化,并写入磁盘。
# load the example image and convert it to grayscale
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# check to see if we should apply thresholding to preprocess the
# image
if args["preprocess"] == "thresh":
gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# make a check to see if median blurring should be done to remove
# noise
elif args["preprocess"] == "blur":
gray = cv2.medianBlur(gray, 3)
# write the grayscale image to disk as a temporary file so we can
# apply OCR to it
filename = "{}.png".format(os.getpid())
cv2.imwrite(filename, gray)
先加载图像,然后将图像转换为灰度图。接下来,根据命令行参数指定的预处理方法,对图像进行阈值化或滤波处理。在这里可以添加更高级的预处理方法(取决于你的光学字符识别的具体应用)。
thresh
:阈值化处理便于从背景中分割出前景。点击这里可以查看阈值化处理的详细信息。
我们将在后面的结果部分看到,这种阈值方法对于识别覆盖在灰色斑点上的深色文本非常有用。
blur
:也可以应用滤波处理。应用中值滤波
有助于减少椒盐噪声,使Tesseract更容易正确识别图像。
对图像进行预处理后,使用 os.getpid
根据Python脚本的进程 id 得到一个临时图片文件名。把预处理后的图像(灰度图)写入磁盘,用得到的文件名进行保存。
使用pytesseract对图像应用光学字符识别:
# load the image as a PIL/Pillow image, apply OCR, and then delete
# the temporary file
text = pytesseract.image_to_string(Image.open(filename))
os.remove(filename)
print(text)
# show the output images
cv2.imshow("Image", image)
cv2.imshow("Output", gray)
cv2.waitKey(0)
使用 pytesseract.image_to_string
将图片上的文字内容转化为文本字符串,我们传入的是磁盘上的临时图像文件。
然后使用 os.remove
将临时图像文件删除。
可以对得到的文本字符串做一些额外的处理,例如拼写检查OCR的错误或自然语言处理,在本教程中只是简单地将其打印到控制台。
最后,在单独的窗口中显示原始图像和处理后的图像。cv2.waitKey(0)
表示需要等到键盘上的某个键被按下后才能退出脚本。
现在可以应用 Python 和 Tesseract 对一些输入图像执行光学字符识别了。
我们会分别对三张图片执行如下三步:
Tesseract
命令行对原始图像进行识别。ocr.py
(在传入Tesseract之前进行了预处理)对每个图像进行识别。下面是第一个示例图片,这张图片包含了我们想要的前景黑色文本,背景中一部分是白色,一部分是人工生成的圆形斑点。斑点对我们的算法来说是“干扰物”。
使用上一篇文章 用于光学字符识别的 Tesseract 介绍的 Tesseract
命令对未处理的原始图像应用OCR。
$ tesseract images/example_01.png stdout
Noisy image
to test
Tesseract OCR
结果完全正确,然后用 ocr.py 脚本,得到的结果也是正确的。
$ python ocr.py --image images/example_01.png
Noisy image
to test
Tesseract OCR
正如你在这张截图中看到的,阈值图像非常清晰,背景已经被移除。我们的脚本将图像中的文本内容正确打印到控制台上。
接下来,在背景中带有椒盐噪声的图像上测试Tesseract和ocr.py:
可以看到 tesseract 命令的输出如下:
$ tesseract images/example_02.png stdout
Detected 32 diacritics
" Tesséra‘c't Will
Fail With Noisy
Backgrounds
不幸的是,Tesseract没有成功地对图像中的文本进行识别。但是在 ocr.py 中使用 blur
预处理方法,我们可以获得更好的识别结果:
$ python ocr.py --image images/example_02.png --preprocess blur
Tesseract Will
Fail With Noisy
Backgrounds
成功!我们的 blur 预处理使Tesseract能够正确识别和输出我们想要的文本。
最后,让我们尝试另一个图像,这个有更多文本的图像:
$ tesseract images/example_03.png stdout
PREREQUISITES
In order In make the rnosi of this, you will need (a have
a little bit of pregrarrmung experience. All examples in this
book are in the Python programming language. Familiarity
with Pyihon or other scriphng languages is suggesied, but
mm required.
You'll also need (a know some basic mathematics. This
book is handson and example driven: leis of examples and
lots of code, so even if your math skills are noi up to par.
do noi worry! The examples are very damned and heavily
documented (a help yuu follaw along.
然后用 ocr.py 测试图像:
请注意两个输出结果中的拼写错误,包括但不限于,"In"、"of"、"required"、"programming" 和 "follow"。
两者的输出不匹配;然而,预处理版本只有8个错误,而未预处理的图像有17个错误(两倍以上的错误数量)。即使在干净的背景下,我们的预处理也会有所帮助!
Python + Tesseract 在OCR这方面表现不错,但是要想直接使用的话,仍然存在一些局限性。
我们在Tesseract的光学字符识别系统中可能会获得比较好的结果,但是要获得最高的准确率,还是需要对出现在真实场景图像中的特定字体进行自定义的字符分类器的训练。
没有真正的“现成”OCR能给你完美的结果(肯定会有一些错误)。
注意: 如果您的文本是旋转的,您可能希望进行额外的预处理,可以参考文章 纠正文本倾斜。否则,如果你想建立一个文档扫描器,可以把在本文学到的光学字符识别系统集成到其中。
在这篇博文中我们学到了如何在python程序中应用Tesseract OCR算法,该算法最大的缺点是Tesseract自身的局限性。当前景文本与背景有非常清晰的分割时,Tesseract效果最好。
此外,这些分割需要尽可能高的分辨率,并且输入图像中的字符在分割后不能出现“像素化”。如果字符表现出像素化,那么Tesseract很难正确识别文本——我们甚至在应用理想条件下拍摄的图像时也发现了这一点(一个PDF截图)。
光学字符识别虽然不再是一项新技术,但仍然是计算机视觉一个活跃的研究领域,尤其是在将光学字符识别应用于真实场景的无约束图像时。深度学习和卷积神经网络(CNNs)无疑使我们能够获得更高的准确性,但我们离“近乎完美”的光学字符识别还有很长的路要走。
当把光学字符识别应用到自己的项目中时,我给读者的建议主要是首先尝试Tesseract,如果结果不理想,就可以使用谷歌视觉API。
如果Tesseract和谷歌视觉API都没有获得合理的准确性,您可能需要重新评估您的数据集,并决定是否值得训练您自己的自定义字符分类器—特别是当如果数据集有噪声或者包含您希望检测和识别的非常特定的字体时。特定字体的例子比如信用卡上的数字、支票底部的账户和号码,或者图形设计中使用的风格化文本。
pytesseract 是 命令行工具 tesseract 的封装,传入的参数可以通过 config
指定,用法如下:
config = ('-l eng --oem 1 --psm 3')
text = pytesseract.image_to_string(Image.open(filename), config=config)
默认只有英文字体(eng.traineddata),如果要应用于中文文本,需要先下载中文字体包并放到指定的位置(我的Ubuntu上存放字体文件的路径为 /usr/share/tesseract-ocr/4.00/tessdata
)。
点击 这里 查看并下载更多支持的语言。
源码链接:
Using Tesseract OCR with Python - PyImageSearchwww.pyimagesearch.com zxdefying/OpenCV_projectgithub.com