基于Tesseract的数字识别程序

一、前言

  这算是一个临时空降的任务,项目背景就懒描述了,先期目的就是从电表的照片中,自动识别出电表的读数出来。如果透过现象看本质,这显然就是一个OCR的任务,而OCR无非就是先期的图片预处理,以及后期的实际OCR识别任务两个阶段。
  说到OCR,就不得不提到大名鼎鼎的Google Tesseract了(虽然这个项目最初是由惠普开发,后面交由Google维护),几乎绝大多数的开源OCR项目,都是用它作为识别引擎的。Tesseract是开源的,而且本身就包含了很多种语言模型的训练结果,如果不是有特别的需求(比如手写的不规则字体),几乎就是开箱就用的效果。我们这里电表的读数都是8段LCD的字体,作为一类最常见的标准字体,我想自己训练也不见得模型有所提升,把精力花在第一步图像的处理方面,会得到更加显著的效果。
  当然,这暂时也不是我的兴趣所在,也没有什么深入研究和体会,只是借助上面的项目搭建了个可以工作的模型,所以干货是没有的干活~

二、EasyPR开源车牌

  对于OCR,经过Google之后,我不得不推荐一个项目EasyPR,其原因不仅仅在于它是开源的,而是作者十分的用心,将整个项目流程的原理、思路和实现细节介绍的十分详细,可以说是手把手教你做车牌识别的,而这无论对于准备入坑的工程师,还是在校学生灌水发论文或者毕业设计,都具有很好的指导入门作用。现在这个项目已经更新到v1.5版本了,引入了MSER等算法用于目标定位等操作,如果想跟着上面作者教程的思路,建议切换到v1.3分支查看。
  参阅作者的教程,总结下来实现流程是这样的:

2.1 图像预处理过程

  这个过程可以总结为抠图过程——就是在一副图像中,提取出车牌号的那一块出来,这纯粹就是个图像处理的过程;对于抠出来的图片,还通过SVM判断器分析是否是车牌图像,可以在减少后续OCR操作的同时,也增加了识别的准确率。
(1) 高斯模糊化,可以平滑滤除小的变化细节,保留车牌边沿这些大的细节;
(2) 图片灰度化;
(3) 对图像X轴方向做Sobel计算(等于是个求导操作),求取图像变化特征,至于为何只求水平方向而不求垂直方向,作者用实验的方法表明,水平方向Sobel足以获得足够的特征用于后续求取轮廓,而垂直Sobel计算往往对最终结果有害无益;
(4) OTSU法自适应对图像进行二值化(一看就是日本名字,经典啊);
(5) 进行形态学的膨胀腐蚀操作,滤除小的噪声点,同时获取相应的连通区域;
(6) 求取Contours轮廓,同时对轮廓进行粗筛选(比如角度、大小、长宽比等);
(7) SVM判别器分析图像块是否为含车牌图像;

2.2 OCR过程

  OCR作者是使用的MLP神经网络实现的,而神经网络/深度学习对于手写数字的识别率达到98%以上,这个领域可谓神经网络的应用之典范,所以作者选此也不足为奇。
  此外,OpenCV本身集成了MLP库,所以这边集成使用起来也更为的方便。

三、电表和身份证识别过程

  整个工程是用Python实现的,主要是得益于OpenCV和Tesseract都有Python接口的封装,借助numpy做一些简单的科学变换,可以快速的搭建模型适配参数,至于后面工程实现可以直接用目标语言予以改写,这也是之前做NLP时候的思路。实现的思路和EasyPR类似,先提取出待识别目标区域,然后就直接调用Tesseract进行OCR操作了,这个过程中的图像处理参照了EasyPRBuilding a Pokedex in Python这两个项目的思路。
  OpenCV的手册整理的还是蛮赞的,C/C++/Python的接口都罗列出来了,所以看着EasyPR然后用Python实现也是极为轻松的事情。

3.1 实现步骤如下:

  (1) 图像归一化尺寸,因为后面很多的操作是基于大小的,如果这些参数如果输入图像差异过大,参数就会不适用;
  (2) 灰度化图像,然后高斯模糊,计算水平方向Sobel特征子,用OTSU方法提取出二值化图像;
下面的图像右边是提取的Sobel特征子,而左边是使用OTSU得到的二值化图像。
Sobel OTSU
  (3) 图像膨胀腐蚀操作,然后提取Contours连通区域;
  (4) 对连通区域进行选择,比如依据形状、长宽度、长宽比等参数;
候选连通区域
  (5) 对每一个基本满足条件的连通区域,尝试使用Tesseract进行OCR识别,得出电表读数;
  这里是跟EasyPR项目差异比较大的地方(当然我是简化了处理,所以最终效果还不好):EasyPR使用SVM对待识别的图像片进行了判断,看是否是车牌图像,这是比较好的优化方式,节省计算量是小,主要是可以提高识别的准确度,一个乱七八糟的图像也可能识别出字符出来再判别就困难了,我是为了省事儿就没做;本文对原始图像进行了一个Transform,归一化成标准长宽矩形的待识别图像供Tesseract识别;图像二值化本文用了自适应OSTU方法,具体可以参照参考文献。另外,对小的图像块再优化操作也是比较容易的哦。
处理后待识别的图像

3.2 其它问题

  (1) 图像处理技术
  之前说过,这个项目的最大难点在于使用OpenCV进行图片处理,图像处理的好,Tesseract的识别率还是挺高的,如果不是需要手写体等特殊字体,感觉完全可以直接用Tesseract自带的模型数据,比如How we tuned Tesseract to perform as well as a commercial OCR package就说,通过图像优化可以让Tesseract达到商用级别的效果。
残缺的区域
  (2) 稍加修改一下,就可以做成一个识别身份证的工具了。
  自己手机拍的图像识别还可以,当然我不会上传自己的身份证给你测试,网上用别人的身份证照又不好,就用了个恶搞的美国总统图,感兴趣的话参数自己调去吧!
身份证识别

项目地址:opencv_tesseract

参考文献