OCR处理技术之模板化处理技术
一、背景
随着深度学习的发展,在CNN的帮助下,找到了一种通过仅仅需要堆参数来提高模型泛化能力的方法。在这种策略的帮助下,以前工业界或者学术界很难完成的任务,在今天深度学习的帮助下通过这种办法都得到了不小的提升,很多图像类分类任务甚至超过了人类,如人脸识别,ImageNet图像分类等等。NLP在一些机器理解,机器阅读的竞赛上甚至也超越了人类的水平
当然OCR也是不例外的,OCR技术的发展在这几年也取得了非常好的效果,主要体现在以下三个地方:
1. 检测的提升
传统的文字检测算法和传统的目标检测算法以前是一个不是特别相关的问题,因为文字的有比较显著的特征便于人工来选取,但是广义的目标检测算法并没有。所以在此之前文字检测算法一般是通过一些人工特征来选取,之前一个比较代表性特征工作是MSER,他的全称叫最大稳定极值区域,他通过类似于分水岭填充算法的方式来找到图像中变化相对稳定的区域,这个工作就算在深度学习检测算法被占据的今天,MSER仍应用在特定工业场景,而且仍可用于文字图像区域的的质量检测。另外还有一些基于类似filter方式的人工设计的特征提取方式;如Stroke filter,它能够滤除图像中那些文字特征不明显的部分,而保留那些文字较明显的部分。但是在深度学习出来之后,在CNN巨大参数面前,这些“手动学习”,“手动设计”设计的特征就变得效果不是那么好了。以深度学习目标检测为代表的一些工作碾压性的战胜的一些传统算法。
2. 文本识别
因为文字识别本质上是个分类问题,以前传统算法自然是打不过深度学习的。另外传统的OCR一般在检测之后需要切分字符来识别,HMM,RNN等类似语音识别中的方法来做对整个图像序列的识别,这种方法虽然可以学到一些语义信息,但是由于序列中每个位置都需要人工标注,工作量巨大,所以效果不是那么好。深度学习的出现之后,直接利用其强大的感受野甚至可以不需要人工标注,直接识别序列信息。在CTC LOSS这个工作出来之后,把序列的自动对齐变成了一种可微表达,可以通过CTC LOSS直接端到端的识别。但是另外的,由于CNN太大的感受野,一些上下文的context信息往往容易被学到,这个有时候我们收集的样本非常不均衡的情况下是不期望发生的,比如在车牌识别的时候,一些偏远地区(如西藏 ,新疆)等车牌并不是那么容易被收集到,另外例如苏A,苏B容易被收集,但是苏F 苏G等车牌可能在一个地方不是那么的常见,使用这种端到端的方法去训练,往往会造成对训练数据中高频的样本表现比较好,单低频的样本表现的很差,在车牌识别这个任务中我们是期望各个省份的表现效果都是一致的。另外由于CNN需要大量的数据,在某些工业场景下,字符样本获取并不是那么容易,工业设备算力不允许,所以一些传统的字符识别算法在如今还是有一定优势的。
3. 后处理
后处理是OCR的重要组成部分,因为受环境噪声,或者同形字的很象文字识别的错误是非常常见的,我们往往期望通过上下文来纠错,例如,一段图像文本中,出现”上海市“,由于字迹不清等不可控因素,文字识别将他识别成“土海市”,我们根据语料和上下文信息,可以很容易的进行纠错。后处理是NLP的一部分,我们在做OCR的过程中往往在不同场景,不同字段,需要使用不同的后处理策略,例如当识别到地址文本字段的时候,使用地址库的语料信息进行做错。近年来,深度学习在NLP上的进展也非常的好,出现了像BERT,GPT-2等这样的巨大模型,这些模型具有序列到序列的生成能力,甚至可以用来写诗,编造新闻小说,在OCR的应用上相比传统算法具有更好的效益。
OCR 是一个相对很广义的问题,这类问题,在不同的特定场景的要求和标准、容错率也不一样。一般情况下OCR的流程一般分为以下几个步骤 文本检测,文本识别,后处理。但是很多情况下我们的OCR业务目标往往都是基于模板的需要输出特定结构化信息,如身份证识别,名片识别,驾驶证识别,医院化验单,以及一些财务资料的录入。这类结构化的识别的任务在学术界相对比较少见,研究的人也比较少,但在工业界,日常生活中,这类结构化的OCR任务却非常常见。而且处理结构化信息的OCR的相关研究和文献也是非常少,这类任务往往都比较杂。在深度学习占据OCR的今天,其OCR的Pipeline和早期传统算法已经有很多不同。本文就此给出几种结合传统方法简单实用处理结构化OCR文本信息的方法。
二、方法介绍
首先我们拿简单的几种情况开始举例:假设我们要识别的材料是一个刚性物体,并且其没有较大旋转角度,这类刚性物体一般为硬质卡片,如身份证,驾照等不会发生弯折和形变。就拿身份证识别来举例
我们注意到在身份证,驾照这类证件识别的问题上,通常有几个相对固定的字段,如“姓名”,“性别”,“民族”。我们可以利用这些字段位置的相对不变性,找到证件平面的透视变换矩阵。由此来恢复证件。这些特殊不变的字段我们可以尝试用很多方法来提取他们的位置,就拿身份证识别问题而言,这些字段往往都显示为淡蓝色。我们通过一些简单的处理甚至不用文本检测方法都能找出这些字段的proposal,例如我们可以通过一个简单的非线性变换加强蓝色区域:
接着我们将其灰度,并使用找到一个适当的阈值进行二值化(例如分块的大津法即可):
我们可以利用OpenCV做几个简单的形态学变换来找到这些区域的团块,找到这些轮廓的包围框
我们发现,身份证上的字段几乎有着相同比例的高度,我们可以通过对这些包围框的高,进行简单的聚类找出高度的分布。尽可能的减少候选框。
这样一来,写着包围框的基本都包括了,我们大部分的特征字段的文字。接着我们对把这些特征字段送入分类器识别,由于在识别的时候有一些是字段,有一些是单字。但是很多时候光凭单字,是不太好表征这个模板的特征的。因此我们需要把单字的相近一些字段根据语义合并。合并的方法也是相对比较简单,我们可以按照语义的序列进行遍历,例如“姓名”,我遍历到“姓字”的时候,我们遍历整个bdbox列表,找到最近为“名”的bdbox。然后将两个bdbox合并,下面是合并之后的结果。
有了这些字段之后,我们可以确定这个刚性物体刚性物体的透视变换矩阵,可以将其对齐到我们的模板上,然后可以根据选择我们想要识别的区域进行识别。