最近入坑研究OCR,看了比较多关于OCR的资料,对OCR的前世此生也有了一个比较清晰的了解。因此想写一篇关于OCR技术的综述,对OCR相关的知识点都好好总结一遍,以加深我的理解。html
OCR英文全称是Optical Character Recognition,中文叫作光学字符识别。它是利用光学技术和计算机技术把印在或写在纸上的文字读取出来,并转换成一种计算机可以接受、人又能够理解的格式。文字识别是计算机视觉研究领域的分支之一,并且这个课题已是比较成熟了,而且在商业中已经有不少落地项目了。好比汉王OCR,百度OCR,阿里OCR等等,不少企业都有能力都是拿OCR技术开始挣钱了。其实咱们本身也能感觉到,OCR技术确实也在改变着咱们的生活:好比一个手机APP就能帮忙扫描名片、身份证,并识别出里面的信息;汽车进入停车场、收费站都不须要人工登记了,都是用车牌识别技术;咱们看书时看到不懂的题,拿个手机一扫,APP就能在网上帮你找到这题的答案。太多太多的应用了,OCR的应用在当今时代确实是百花齐放啊。python
若是要给OCR进行分类,我以为能够分为两类:手写体识别和印刷体识别。这两个能够认为是OCR领域两个大主题了,固然印刷体识别较手写体识别要简单得多,咱们也能从直观上理解,印刷体大多都是规则的字体,由于这些字体都是计算机本身生成再经过打印技术印刷到纸上。在印刷体的识别上有其独特的干扰:在印刷过程当中字体极可能变得断裂或者墨水粘连,使得OCR识别异常困难。固然这些均可以经过一些图像处理的技术帮他尽量的还原,进而提升识别率。总的来讲,单纯的印刷体识别在业界已经能作到很不错了,但说100%识别是确定不可能的,可是说识别得不错那是没毛病。网络
印刷体已经识别得不错了,那么手写体呢?手写体识别一直是OCR界一直想攻克的难关,可是时至今天,感受这个难关还没攻破,还有不少学者和公司在研究。为何手写体识别这么难识别?由于人类手写的字每每带有我的特点,每一个人写字的风格基本不同,虽然人类能够读懂你写的文字,可是机器缺很难。那为何机器能读懂印刷体?由于印刷体是机器造出来的啊,那机器固然能读懂本身造的字体啦哈哈~其实上面也提到了,印刷体通常都比较规则,字体都基本就那几十种,机器学习这几十种字体并非一件难事,可是手写体,每一个人都有一种字体的话,那机器该学习多少字体啊?这就是难度所在。机器学习
若是按识别的内容来分类,也就是按照识别的语言的分类的话,那么要识别的内容将是人类的全部语言(汉语、英语、德语、法语等)。若是仅按照咱们国人的需求,那识别的内容就包括:汉字、英文字母、阿拉伯数字、经常使用标点符号。根据要识别的内容不一样,识别的难度也各不相同。简单而言,识别数字是最简单了,毕竟要识别的字符只有0~9,而英文字母识别要识别的字符有26个(若是算上大小写的话那就52个),而中文识别,要识别的字符高达数千个(二级汉字一共6763个)!由于汉字的字形各不相同,结构很是复杂(好比带偏旁的汉字)若是要将这些字符都比较准确地识别出来,是一件至关具备挑战性的事情。可是,并非全部应用都须要识别如此庞大的汉字集,好比车牌识别,咱们的识别目标仅仅是数十个中国各省和直辖市的简称,难度就大大减小了。固然,在一些文档自动识别的应用是须要识别整个汉字集的,因此要保证识别的总体的识别仍是很困难的。学习
如今就来整理一下常见的OCR流程,为了方便描述,那就举文档中的字符识别为例子来展开说明吧。字体
假如输入系统的图像是一页文本,那么识别时的第一件事情是判断页面上的文本朝向,由于咱们获得的这页文档每每都不是很完美的,极可能带有倾斜或者污渍,那么咱们要作的第一件事就是进行图像预处理,作角度矫正和去噪。而后咱们要对文档版面进行分析,进每一行进行行分割,把每一行的文字切割下来,最后再对每一行文本进行列分割,切割出每一个字符,将该字符送入训练好的OCR识别模型进行字符识别,获得结果。可是模型识别结果每每是不太准确的,咱们须要对其进行识别结果的矫正和优化,好比咱们能够设计一个语法检测器,去检测字符的组合逻辑是否合理。好比,考虑单词Because,咱们设计的识别模型把它识别为8ecause,那么咱们就能够用语法检测器去纠正这种拼写错误,并用B代替8并完成识别矫正。这样子,整个OCR流程就走完了。从大的模块总结而言,一套OCR流程能够分为:优化
版面分析 -> 预处理-> 行列切割 -> 字符识别 -> 后处理识别矫正
从上面的流程图能够看出,要作字符识别并非单纯一个OCR模块就能实现的(若是单纯的OCR模块,识别率至关低),都要各个模块的组合来保证较高的识别率。上面的流程分的比较粗,每一个模块下仍是有不少更细节的操做,每一个操做都关系着最终识别结果的准确性。作过OCR的童鞋都知道,送入OCR模块的图像越清晰(即预处理作的越好),识别效果每每就越好。那如今对这流程中最为重要的字符识别技术作一个总结。设计
如今咱们只想单纯地想对字符进行识别,那方法会有哪些呢?我列了一下能够采起的策略:3d
上面提到的OCR方法都有其有点和缺点,也正如此,他们也有各自特别适合的应用场景。code
首先说开源OCR引擎Tesseract。搞字符识别的童鞋应该都据说过Tesseract这个东西,这是谷歌维护的一个OCR引擎,它已经有一段至关悠久的历史了。Tesseract如今的版本已经支持识别不少种语言了,固然也包括汉字的识别。毕竟Tesseract是外国人搞得一个东西,因此在汉字识别的精度上仍是不能摆上台面,不过仍是本身去改善。可是Tesseract在阿拉伯数字和英文字母上的识别仍是能够的,若是你要作的应用是要识别英文或者数字,不妨考虑一下使用Tesseract,毕竟拿来就能获得不错的结果。固然啦,要作到你想要的识别率,后期微调或者优化确定要多下功夫的。
接下来讲一下借用OCR开放平台作文字识别。如今不少大公司都开放了OCR的API供开发者调用,固然啦,小量调用是不收费的,可是大量调用就要收费了。最近我也在百度开放平台上调用OCR的API作一些识别的工做,说实话,在汉字的识别上,咱们中国公司的技术仍是顶尖的,在汉字识别的准确率上已经让人很满意了。好比我要识别一些文本,本身写个python脚本,调用开放平台的服务,返回的就是识别结果了。这种模式有啥很差的地方吗?首先是须要钱(固然天天小批量识别一下是不用钱的),第二是本身的控制程度不足,咱们想要提高识别精度,咱们不能够从OCR识别上作改进(毕竟别人的东西,咱们改不了),能作只是预处理和后期矫正,能作的仍是比较有限的。可是,若是本身不想花大量时间作OCR模型而且手上有钱的话,这种识别方法仍是OK的。
上面提到的都是用的是别人的东西,那咱们想从头本身作,咋办?
那就本身作吧!先谈一谈字符模板那匹配法。暴力的字符模板匹配法看起来很蠢,可是在一些应用上可能却很凑效。好比在对电表数字进行识别时,考虑到电表上的字体较少(可能就只有阿拉伯数字),并且字体很统一,清晰度也很高,因此识别难度不高。针对这种简单的识别场景,咱们首先考虑的识别策略固然是最为简单和暴力的模板匹配法。咱们首先定义出数字模板(0~9),而后用该模板滑动匹配电表上的字符,这种策略虽然简单可是至关有效。咱们不须要冥思苦想去建模,训练模型,只须要识别前作好模板库就能够了。
模板匹配法只限于一些很简单的场景,但对于稍微复杂的场景,那就不太实用了。那此时咱们能够采起OCR的通常方法,即特征设计、特征提取、分类得出结果的计算机视觉通用的技巧。在深度学习大放异彩以前,OCR的方法基本都是这种方法,其效果嘛,并不算特别好。在这里简单说一下这里常见的方法。第一步是特征设计和提取,特征设计是一件很烦人的事情,作过模式识别相关项目的童鞋也深有体会,咱们如今识别的目标是字符,因此咱们要为字符设计它独有的的特征,来为后面的特征分类作好准备。字符有啥特征呢?有结构特征,即字符的端点、交叉点、圈的个数、横线竖线条数等等,都是能够利用的字符特征。好比“品”字,它的特征就是它有3个圈,6条横线,6条竖线。除告终构特征,还有大量人工专门设计的字符特征,听说都能获得不错的效果。最后再将这些特征送入分类器(SVM)作分类,得出识别结果。这种方式最大的缺点就是,人们须要花费大量时间作特征的设计,这是一件至关费工夫的事情。经过人工设计的特征(例如HOG)来训练字符识别模型,此类单一的特征在字体变化,模糊或背景干扰时泛化能力迅速降低。并且过分依赖字符切分的结果,在字符扭曲、粘连、噪声干扰的状况下,切分的错误传播尤为突出。针对传统OCR解决方案的不足,学界业界纷纷拥抱基于深度学习的OCR。
这些年深度学习的出现,让OCR技术焕发第二春。如今OCR基本都用卷积神经网络来作了,并且识别率也是惊人的好,人们也再也不须要花大量时间去设计字符特征了。在OCR系统中,人工神经网络主要充当特征提取器和分类器的功能,输入是字符图像,输出是识别结果,一鼓作气。这里就再也不展开说明卷积神经网络了,想要知道的细节的能够看我之前写过的一篇博客《卷积神经网络CNN总结》。固然用深度学习作OCR并非在每一个方面都很优秀,由于神经网络的训练须要大量的训练数据,那么若是咱们没有办法获得大量训练数据时,这种方法极可能就不奏效了。其次,神经网络的训练须要花费大量的时间,而且须要用到的硬件资源通常都比较多,这几个都是须要考虑的问题。
在接下来的博客中,我将在工程上一一实现以上说到的几种OCR的识别方法~~
在一些简单环境下OCR的准确度已经比较高了(好比电子文档),可是在一些复杂环境下的字符识别,在当今尚未人敢说本身能作的很好。如今你们都不多会把目光还放在如何对电子文档的文字识别该怎么进一步提升准确率了,由于他们把目光放在更有挑战性的领域。OCR传统方法在应对复杂图文场景的文字识别显得力不从心,愈来愈多人把精力都放在研究如何把文字在复杂场景读出来,而且读得准确做为研究课题,用学界术语来讲,就是场景文本识别(文字检测+文字识别)。
从上图能够看出,天然场景下的文字识别比简单场景的文字识别实在困难太多了,如今虽然出了不少成果,可是离理想结果仍是差很远。
固然啦,除上面的场景文字识别外,历史悠久的手写体的识别到如今仍是一件具备挑战的课题,在深度学习的浪潮下,手写体的识别已经前进了一大步,可是尚且没达到印刷体识别那种能够商用的地步,因此啊,OCR的研究还得不断地进行下去。