zoukankan      html  css  js  c++  java
  • [转]一个简单的基于Tesseract的数字识别程序

    一个简单的基于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操作了,这个过程中的图像处理参照了 EasyPR 和 Building a Pokedex in Python 这两个项目的思路。

    OpenCV的手册整理的还是蛮赞的,C/C++/Python的接口都罗列出来了,所以看着EasyPR然后用Python实现也是极为轻松的事情。

    3.1 实现步骤如下:

    (1) 图像归一化尺寸,因为后面很多的操作是基于大小的,如果这些参数如果输入图像差异过大,参数就会不适用;

    (2) 灰度化图像,然后高斯模糊,计算水平方向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

    参考文献

  • 相关阅读:
    数仓备机DN重建:快速修复你的数仓DN单点故障
    深度学习分类任务常用评估指标
    云小课 | MRS基础入门之HDFS组件介绍
    华为云数据库GaussDB(for Cassandra)揭秘第二期:内存异常增长的排查经历
    为什么vacuum后表还是继续膨胀?
    Go 自定义日志库
    Go time包
    Go 文件操作
    Go 包相关
    【程序人生】跟小伙伴们聊聊我有趣的大学生活和我那两个好基友!
  • 原文地址:https://www.cnblogs.com/Crysaty/p/6283303.html
Copyright © 2011-2022 走看看