本教程翻译自PyImageSearch英文原文
上周的博客内容,我们学习了如何安装Tesseract去做OCR识别。
然后我们通过一些小图片示例去应用Tesseract测试和评估这个OCR引擎的性能。
我们的结论显示,Tesseract在前景文本和背景色区分的非常清晰的图片上工作非常好。实际上,保证这些类型的分割可能极具挑战性。因此,我们倾向于训练特定领域的图像分类器和检测器。
然而,在我们需要将OCR应用于我们自己的项目的情况下,我们了解如何通过Python编程语言访问Tesseract OCR非常重要(前提是我们可以获得Tesseract所需的漂亮,干净的分段)。
涉及OCR的示例项目可能包括[构建移动文档扫描程序](https://www.pyimagesearch.com/2014/09/01/build-kick-ass-mobile-document-scanner-just-5-minutes/)您希望从中提取文本信息,或者您正在运行扫描纸质医疗记录的服务,并且您希望将信息放入符合HIPA的数据库中。
在本章的其余部分,我们将学习如何安装Tesseract OCR + Python“绑定”,然后编写一个简单的Python脚本来调用这些绑定。在本教程结束时,您将能够将图像中的文本转换为Python字符串数据类型。
通过Python使用Tesseract OCR
本博客分为三部分。
首先,我们将学会如何安装pytesseract package 以便我们可以通过Python编程语言应用Tesseract。
然后,我们将开发一个简单的Python脚本来加载图片,二值化图片并且将图片传给Tesseract OCR 系统。
最后,我们将在一些示例图像上测试我们的OCR管道并查看结果。
在Python中绑定Tesseract
让我们从安装pytesseract开始吧。我们将利用pip来安装pytesseract 。
如果你使用的是虚拟环境(我强烈推荐这样,以便您可以隔离不同的项目),使用workon命令为你的环境配置合适的名称。在这个例子中,我们的虚拟环境叫做cv。
$ workon cv
接下来我们来安装 Pillow,一个跟友好的pytesseract依赖的PIL端口。
$ pip install pillow
$ pip install pytesseract
注意:pytesseract 并不是提供 一个真正的Python绑定。而是简单的提供tesseract库的接口。如果你看它在GitHub的项目你将发现该库将图像写入磁盘上的临时文件,然后在文件上调用tesseract二进制文件并捕获结果输出。这绝对有些取巧,但它为我们完成了工作。
让我们继续,查看一些将前景文本从背景中分割出来的代码,然后使用我们新安装的pytesseract。
使用Tesseract和Python应用OCR
让我们首先创建一个名字叫ocr.py 的新文件:
1. # import the necessary packages
2. from PIL import Image
3. import pytesseract
4. import argparse
5. import cv2
6. import os
7.
8. # construct the argument parse and parse the arguments
9. ap = argparse.ArgumentParser()
10. ap.add_argument("-i", "--image", required=True,
help="path to input image to be OCR'd")
11. ap.add_argument("-p", "--preprocess", type=str, default="thresh",
help="type of preprocessing to be done")
12. args = vars(ap.parse_args())
2-6行是处理引用库。我们从硬盘加载图片需要使用Image类,当使用pytesseract时需要引入pytesseract库。
9-14行是处理输入的命令参数,我们有2个入参:
--image: 传入给OCR系统的图片路径。
--preprocess:处理的方法。这个是可选的开关,目前这个参数只接受2个值:thresh(阈值)或者blur。下面我们将要加载图片,对图片进行二值化并且将结果写入硬盘。
16. # load the example image and convert it to grayscale
17. image = cv2.imread(args["image"])
18. gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
19.
20. # check to see if we should apply thresholding to preprocess the
21. # image
22. if args["preprocess"] == "thresh":
23. gray = cv2.threshold(gray, 0, 255,
24. cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
25.
26. # make a check to see if median blurring should be done to remove
27. # noise
28. elif args["preprocess"] == "blur":
29. gray = cv2.medianBlur(gray, 3)
30.
31. # write the grayscale image to disk as a temporary file so we can
32. # apply OCR to it
33. ilename = "{}.png".format(os.getpid())
34. cv2.imwrite(filename, gray)
首先,我们将--image参数的图片从硬盘加载到内存中(第17行),接着对它进行灰度处理。(第18行)
接下来,根据传入的预处理参数,我们选择threshold或者blur来处理图片。这里我们可能需要添加更多的预处理方法处理超出本章范围的情况。
第22-24行执行threshold方法分离图片的前景和背景。我们通过使用 cv2.THRESH_BINARY 和 cv2.THRESH_OTSU标志处理。更多细节,请看在 official OpenCV documentation中查看*“Otsu’s Binarization”。
稍后我们将在结果部分中看到,这种阈值处理方法可用于读取叠加在灰色形状上的暗文本。
或者,可以应用模糊方法。 当--preprocess标志设置为blur时,第28-29行执行中值模糊。应用中值模糊可以帮助减少盐和胡椒的噪音,再次使Tesseract更容易正确地OCR图像。
在预处理图片之后,我们使用os.getpid根据Python脚本的进程ID派生临时图片文件名称(33行)。
使用pytesseract进行OCR之前的最后一步是将预处理后的图像灰色写入磁盘,并使用上面的文件名保存它(第34行)。
我们最终可以使用Tesseract Python“绑定”将OCR应用于我们的图像:
36. # load the image as a PIL/Pillow image, apply OCR, and then delete
37. # the temporary file
38. text = pytesseract.image_to_string(Image.open(filename))
39. os.remove(filename)
40. print(text)
41.
42. # show the output images
43. cv2.imshow("Image", image)
44. cv2.imshow("Output", gray)
45. cv2.waitKey(0)
第38行,我们使用pytesseract.image_to_string方法将图片内容转化为文本字符串。需要注意的是,我们传的是对图片的临时引用。
第39行,我们清除了临时文件。
我们在40行打印出识别的文本到控制台上。在你自己的应用中,你可能会想在这本上要做一些额外的处理。例如:拼写错误检查或者自然语言处理代替在控制台输出文本,这些内容我们将要在本章后面讲解。
最后,第43和44行分别展示原始图片和预处理后的图片。43行的cv2.waitKey(0) 等待指令,等待从键盘输入任意字符后退出程序。
下面让我们开始动手写代码。
Python Tesseract OCR识别和结果
现在创建一个ocr.py的文件,是时候让我们使用Python + Tesseract 针对一些示例图片进行OCR识别了。
在这个章节中我们将使用如下步骤尝试OCR识别三个示例图片:
首先,我们将按照Tesseract库原样运行每个图片。
然后,我们将运行ocr.py脚本通过Tesseract实现预处理文件来处理每个图片。
最后,我们将比较这两种方法的结果并记录任何错误。
我们第一个例子是一个“噪点”图片。此图像包括我们期望的前景色是黑色的文本,背景色是部分白色和部分人工生成的灰色的圆点。灰色的污点充当我们算法的“干扰者”。
我们可以使用Tesseract识别原始的、未处理的图片。就像我们上一章的内容。
1. $ tesseract images/example_01.png stdout
2. Noisy image
3. to test
4. Tesseract OCR
Tesseract表现的非常好,在这个例子中没有任何错误。
现在让我们确认下我们新的脚本,ocr.py ,同样运行良好:
1. $ python ocr.py --image images/example_01.png
2. Noisy image
3. to test
4. Tesseract OCR
正如您在此屏幕截图中看到的那样,阈值图像非常清晰,背景已被删除。我们的脚本正确地将图像的内容打印到控制台。
接下来,让我们在背景中的“盐和胡椒”噪声图像上测试Tesseract和我们的预处理脚本:
我们可以在下面看到tesseract的输出结果:
1. $ tesseract images/example_02.png stdout
2. Detected 32 diacritics
3. " Tesséra‘c't Will
4. Fail With Noisy
5. Backgrounds
不幸的是,Tesseract没有成功地对图像中的文本进行OCR识别。
但是,通过在ocr.py中使用模糊预处理方法,我们可以获得更好的结果:
1. $ python ocr.py --image images/example_02.png --preprocess blur
2. Tesseract Will
3. Fail With Noisy
4. Backgrounds
成功了!通过模糊预处理步骤使Tesseract正确的识别和输出我们期望的文本。
最后,让我们尝试另外一个图片,这个图片有更多的文本:
以上图片是我的书Practical Python and OpenCV 中的*“Prerequisites” *章节截图。让我们来看看Tesseract如何处理这个图片:
1. $ tesseract images/example_03.png stdout
2. PREREQUISITES
3.
4. In order In make the rnosi of this, you will need (a have
5. a little bit of pregrarrmung experience. All examples in this
6. book are in the Python programming language. Familiarity
7. with Pyihon or other scriphng languages is suggesied, but
8. mm required.
9.
10. You'll also need (a know some basic mathematics. This
11. book is handson and example driven: leis of examples and
12. lots of code, so even if your math skills are noi up to par.
13. do noi worry! The examples are very damned and heavily
14. documented (a help yuu follaw along.
然后使用ocr.py测试图像:
1. $ python ocr.py --image images/example_03.png
2. PREREQUISITES
3.
4. Lu order to make the most ol this, you will need to have
5. a little bit ol programming experience. All examples in this
6. book are in the Python programming language. Familiarity
7. with Python or other scripting languages is suggested, but
8. not requixed.
9.
10. You’ll also need to know some basic mathematics. This
11. book is handson and example driven: lots of examples and
12. lots ol code, so even ii your math skills are not up to par,
13. do not worry! The examples are very detailed and heavily
14. documented to help you tollow along.
注意两个输出中的拼写错误,包括但不限于“In”,“of”,“required”,“programming”,“follow”。
两者的输出都不匹配;然而,有趣的是,预处理版本只有8个字错误,而非预处理图像有17个字错误(错误数量超过两倍)。 我们的预处理可以帮助非干净的背景条件下识别文字!
Python + Tesseract在这里做了一个合理的工作,但我们再一次证明了库作为现成的分类器的局限性。
我们可以使用Tesseract for OCR获得良好或可接受的结果,但最佳准确度将来自在实际真实世界图像中出现的特定字体集上的自定义字符分类器上的训练。
不要让Tesseract OCR的结果让您失望 - 只需管理您的期望并对Tesseract的表现保持现实。没有真正的“现成”OCR系统可以为您提供完美的结果(肯定会有一些错误)。
注意:如果您的文字被轮换,您可能希望进行额外的预处理,如之前关于纠正文本偏斜的博客文章中所执行的那样。否则,如果您对构建[移动文档扫描程序](https://www.pyimagesearch.com/2014/09/01/build-kick-ass-mobile-document-scanner-just-5-minutes/ )感兴趣,你现在有一个相当不错的OCR系统可以集成到它中。
摘要
在今天的博客文章中,我们学习了如何将Tesseract OCR引擎应用于Python编程语言。这使我们能够在我们的Python脚本中应用来自within的OCR算法。
最大的缺点是Tesseract本身的局限性。当前景文本中有极 干净分割时,Tesseract效果最佳。
此外,这些分割需要尽可能高的分辨率(DPI)和输入图像中的字符在分割后不会出现“像素化”。如果字符确实出现像素化,那么Tesseract将难以正确识别文本 - 即使应用在理想条件下捕获的图像(PDF截图),我们也发现了这一点。
OCR虽然不再是一项新技术,但仍然是计算机视觉文献研究的一个活跃领域*尤其是在将OCR应用于真实世界的无约束图像时。深度学习和卷积神经网络(CNN)无疑使我们能够获得更高的准确度,但我们距离看到“接近完美”的OCR系统还有很长的路要走。此外,由于OCR在许多域中具有许多应用程序,因此用于OCR的一些最佳算法是商业性的,并且需要许可才能在您自己的项目中使用。
在将OCR应用于自己的项目时,我向读者提出的主要建议是首先尝试使用Tesseract,如果结果不合适,请转到Google Vision API。
如果* Tesseract 和 Google Vision API 都没有获得合理的准确度,您可能需要重新评估数据集并确定是否值得培训自己的自定义字符分类器 - 这尤其是如果*为真您的数据集有噪音和/或包含您希望检测和识别的特定字体。特定字体的示例包括信用卡上的数字,在支票底部找到的帐户和路由号码,或图形设计中使用的程式化文本。
我希望你能在Python和OpenCV上享受关于光学字符识别(OCR)的一系列博客文章!