在这一章里,重点介绍机器视觉的一个分支:文字识别,介绍如何用一些 Python 库来识别和使用在线图片中的文字。
当你不想让自己的文字被网络机器人采集时,把文字做成图片放在网页上是常用的办法。
利用这种人类用户可以正常读取但是大多数机器人都没法读取的图片,验证码 (CAPTCHA) 就出现了。
将图像翻译成文字一般被称为光学文字识别(Optical Character Recognition,OCR)。可以实现 OCR 的底层库并不多,目前很多库都是使用共同的几个底层 OCR 库,或者是在上面进行定制。
11.1 OCR 库概述
在读取和处理图像、图像相关的机器学习以及创建图像等任务中,Python 一直都是非常出 色的语言。虽然有很多库可以进行图像处理,但在这里我们只重点介绍两个库: Pillow 和 Tesseract。
每个库都可以从它们的网站上下载并安装,或者用第三方管理器(像 pip)通过 “pillow” 和
“pytesseract”进行安装 。
11.1.1 Pillow
Pillow 可以轻松地导入代码,并通过大量的过滤、修饰甚至像素级的变换操作处理图片。
我们可以用 Pillow 完成图片的预处理,让机器可以更方便地读取图片。除了这些简单的
事情之外,Pillow 还可以完成许多复杂的图像处理工作。更多的信息,请查看 Pillow 文档。
11.1.2 Tesseract
Tesseract 是一个 OCR 库,目前由 Google 赞助。Tesseract 是目前公认最优秀、最精确的开源 OCR 系统。 除了极高的精确度,Tesseract 也具有很高的灵活性。它可以通过训练识别出任何字体(只要这些字体的风格保持不变就可以),也可以识别出任何 Unicode 字符。
Tesseract 是一个 Python 的命令行工具,不是通过 import 语句导入的库。安装之后,要用 tesseract 命令在 Python 的外面运行。
11.1.3 NumPy
NumPy 是一个非常强大的库,具有大量线性代数以及大规模科学计算的方法。因为 NumPy 可以用数学方法把图片表示成巨大的像素数组, 所以它可以流畅地配合 Tesseract 完成任务。
11.2 处理格式规范的文字
通常,格式规范的文字具有以下特点:
• 使用一个标准字体(不包含手写体、草书,或者十分“花哨的”字体)
• 虽然被复印或拍照,字体还是很清晰,没有多余的痕迹或污点
• 排列整齐,没有歪歪斜斜的字
• 没有超出图片范围,也没有残缺不全,或紧紧贴在图片的边缘
文字的一些格式问题在图片预处理时可以进行解决。例如,可以把图片转换成灰度图,调 整亮度和对比度,还可以根据需要进行裁剪和旋转。
11.3 读取验证码与训练 Tesseract
Google 的 reCAPTCHA 难得令人发指,作为目前最具有安全意识的流行网站,Google 拦截了多达 25% 的准备访问网站的正常人类用户。
大多数其他的验证码都是比较简单的。例如,流行的 PHP 内容管理系统 Drupal 有一个著名的验证码模块,可以生成不同难度的验证码。
训练 Tesseract
要训练 Tesseract 识别一种文字,无论是晦涩难懂的字体还是验证码,你都需要向 Tesseract 提供每个字符不同形式的样本。
提示:建议使用验证码的真实结果给每个样本文件命名。这样可以帮你一次性对大量的文件进行快速检查——你可以先把图片调成缩略图模式,然后通过文件名对比不同的图片。这样在后面的步骤中进行训练效果的检查也会很方便。
准确地告诉 Tesseract 一张图片中的每个字符是什么,以及每个字符的具体位置。
在线工具 Tesseract OCR Chopper,因为它不需要安装,也没有其他依赖,只要有浏览器就可以运行,而且用法很简单:上传图片,如果要增加新矩形就单击“add”按钮,还可以根据需要调整矩形的尺寸,最后把新生成的矩形定位文件复制到一个新文件里就可以了。
如果你对 Tesseract 的其他训练方法感兴趣,甚至打算建立自己的验证码训练文件库,或者想和全世界的 Tesseract 爱好者分享自己对一种新字体的识别成果,那么我推荐你仔细阅读 Tesseract 的文档。
11.4 获取验证码提交答案
大多数网站生成的验证码图片都具有以下属性。
• 它们是服务器端的程序动态生成的图片。验证码图片的 src 属性可能和普通图片不太一 样,比如 <img src="WebForm.aspx?id=8AP85CQKE9TJ">,但是可以和其他图片一样进行下载和处理。
• 图片的答案存储在服务器端的数据库里。
• 很多验证码都有时间限制,如果你太长时间没解决就会失效。
常用的处理方法就是,首先把验证码图片下载到硬盘里,清理干净,然后用 Tesseract 处理 图片,最后返回符合网站要求的识别结果。