这张照片很容易辨认。笔迹呢?手写识别一直是OCR一直在努力攻克的难点,但时至今日,感觉这个难点并没有被突破,很多学者和公司还在研究。为什么手写识别这么难识别?因为人的笔迹往往有个人特点,所以每个人的书写风格基本都不一样。虽然人类能读懂你的文字,但很难缺少机器。那为什么机器可以读取印刷品呢?因为印刷是机器做的,机器当然能读懂自己的字体。哈哈~其实就像上面说的,印刷一般都是有规律的,基本有几十种字体。机器学习这几十种字体并不难,但是手写,如果每个人都有一种字体,机器要学习多少种字体?这就是难点。
如果按照识别的内容分类,也就是按照识别的语言分类,那么要识别的内容将是所有人类语言(汉语、英语、德语、法语等。).如果仅仅根据我国人民的需要,识别的内容包括:汉字、英文字母、阿拉伯数字和常用标点符号。识别的难度根据要识别的内容而不同。简单来说,识别数字是最容易的。毕竟要识别的字符只有0~9个,而英文字母识别要识别的字符有26个(大小写都算的话有52个),而中文识别要识别的字符有上千个(共6763个二级汉字)!由于汉字的字形不同,结构复杂(比如有偏旁部首的汉字),要准确识别所有这些字符是相当具有挑战性的。然而,并不是所有的应用都需要识别如此庞大的汉字集,比如车牌识别。我们的识别对象只是中国几十个省、直辖市的缩写,难度大大降低。当然,在一些自动文档识别应用中,需要识别整个汉字集,所以要保证识别的整体识别还是很困难的。
如果输入到系统中的图像是一页文字,那么在识别中首先要做的就是判断文字在页面上的方向,因为我们得到的文档往往并不完美,很可能是倾斜的或者有污点的,所以我们首先要做的就是对图像进行预处理,校正角度,去噪。然后我们需要对文档版面进行分析,把每一行分成若干行,把每一行的文字剪下来,最后把每一行分成若干列,把每一个字符剪下来,把字符送到训练好的OCR识别模型进行字符识别,得到结果。然而,模型识别的结果往往是不准确的,我们需要对识别结果进行修正和优化。比如我们可以设计一个语法检测器来检测字符的组合逻辑是否合理。比如考虑单词Because,我们设计的识别模型把它识别为8ecause,那么我们可以用语法检测器纠正这个拼写错误,用B代替8,完成识别和纠正。这样,整个OCR过程就完成了。从一个大的模块来总结,一组OCR过程可以分为:
版面分析-预处理-行列切割-字符识别-后处理识别和校正从上面的流程图可以看出,字符识别不是单一的OCR模块可以实现的(如果OCR模块比较简单,识别率相当低),必须将所有模块组合起来才能保证较高的识别率。以上过程大致划分,每个模块下还有很多更细致的操作,每个操作都关系到最终识别结果的准确性。做过OCR的童鞋都知道,送到OCR模块的图像越清晰(也就是预处理越好),识别效果越好。现在对这个过程中最重要的字符识别技术做一个总结。
利用Google开源的OCR引擎Tesseract,利用大公司(如百度)的OCR开放平台,利用他们传统的字符识别API的方法提取字符的特征,输入到分类器中,就可以得到OCR模型暴力的杀手锏:基于深度学习的CN。
N字符识别上面提到的OCR方法都有其有点和缺点,也正如此,他们也有各自特别适合的应用场景。
首先说开源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的研究还得不断地进行下去。
下一篇:梦见翻车什么意思呢