不需要分层的双层车牌识别新方案

序言

车牌识别目前算是比较常见的OCR应用,各大停车场的门口均能看见,国内的车牌分为多种,有单层、有双层,有黄牌、蓝牌、绿牌等等,目前基本上都是基于检测加识别的方案进行,检测通常是一阶段的检测器:YOLO、SSD等等,这类型的检测器特点是速度快、性能好优化,便于嵌入边缘设备;而识别则是CRNN居多,CRNN也是目前用的最多的中文文本识别算法,但是CRNN无法直接识别双行的文字,而在车牌中恰好有一种车牌比较特殊,那就是双层车牌,基于CRNN的车牌识别通常是不能直接对双层车牌进行识别的,需要将上下层文字分割后再分别送入识别网络中,但是这么多又显得稍微繁琐了一点,那么能不能直接将双层车牌直接送入CRNN中进行识别呢?之前在一些技术群中关于这个问题有过讨论,答案是可以的,并且有大佬已经实践过了,表示方案可行。趁着最近有时间,我也验证一下这个结论。

双层车牌示例,目前的识别方案较多是先将上、下层文字分割开来,分别进行识别,然后再组合起来:
在这里插入图片描述

一、可行性分析

基于传统的CRNN识别方案,因为识别的都是单行文字输入,所以通常来说输入的图片是高(H=32),宽W是可变长的尺寸,举个简单的例子,如果一张图片为H=32,W=224的图片(1x3x32x224)输入CRNN网络中,经过卷积层的下采样后,可以得到1 x Cout x 1 x 56的特征图,该特征图再经过reshape后输入LSTM中,即下采样的倍数为W下采样4倍,H下采样32倍。如图
不需要分层的双层车牌识别新方案_第1张图片
那么双层的传统方案是将两层文字分开,分别识别两行文字;
不需要分层的双层车牌识别新方案_第2张图片
那么我们能不能不分层,直接将原图送入网络识别呢?或者换个思路,让网络自己去分层。为了验证这个想法,我尝试了将输入的高H变成了64,W还是自适应变化,即一张双层的车牌的输入变成了1 x 3 x 64 x W(这里取W=224,可自己调整),那么正常输入CRNN后,经过下采样得到了1 x Cout x 2 x 56,画一张图来说明:
不需要分层的双层车牌识别新方案_第3张图片
怎么样,有没有看出什么猫腻?这么一来网络不是自己帮我们分好层了嘛,我们只需要将下面一层的特征衔接到上面一层的后面,不就还是变成了单序列问题了嘛!!!看到这里是不是恍然大悟?这都可以!!
不需要分层的双层车牌识别新方案_第4张图片
那么问题来了,我们看到上面的车牌,上面层的文字高明显比下层的要短一点,这样一来会不会影响识别的效果呢?理论上来说,因为感受野的概念,网络收敛是因为没有问题的,但是不知道精度如何,所以我们需要实践验证一下,光有空想没有实验也不行。

二、数据生成

要训练一个网络,数据必不可少,因为只是验证一下方案的可行性,并不打算去收集真实的车牌,采用数据合成即可,要注意的是,所以我使用了这个文章开源的代码仓库中国车牌模拟生成器,合成了一批双层车牌的数据,大约10w张,合成示例如下:
不需要分层的双层车牌识别新方案_第5张图片
可以看到都是规规整整的数据,这类数据如果不根据真实的车牌数据做任何数据增强或者贴近合成的话,是无法用于生产环境的,因为数据分布不同的原因,在这类数据基础上训练出来的网络用到实际场景中效果会奇差,而我这里也仅仅是用于实验,验证只需要单步即可识别双层文字的问题,不考虑使用,所以就没必要再折腾真实数据。

最终生成10w张数据,数据集随机划分为train_data:98000张,test_data:2000张。

三、网络选择

基于常规的CRNN网络做的改进,去掉了RNN层,因为对于这类型的任务,并不太依赖语义信息,所以去掉RNN层在性能上效果反而会更好,最后网络只剩下:CNN+CTC构成;说到这里可能有的人就在想,网络这么简单,这怎么能识别呢?我对CNN部分做了改进,改用了我最近非常喜欢用的RepVGG网络,即RepVGG+CTC训练。

但是我这里遇到了一个问题,两种不同的打标签方式,训练的结果差距非常的大,一种是在上层文字和下层文字之间加了空格符号,另一种不加,不加的话第一层的字母基本上全是错的,也就是网络基本上在瞎猜,但是其他位置的字母识别的非常准确,如图所示:
不需要分层的双层车牌识别新方案_第6张图片
不需要分层的双层车牌识别新方案_第7张图片

但是加的话,训练的效果缺非常的好,基本上都预测正确了,所以我最后采用了加空格的方式训练,训练结果如下:
不需要分层的双层车牌识别新方案_第8张图片
不需要分层的双层车牌识别新方案_第9张图片

基本上才走完一轮就达到了很好的精度,当然其中一个原因还是我用来训练的数据分布太简单的,这种数据是无法用于实际场景的,再次声明。好了,实验的结果表明,这个想法是行得通的,唯一的困难也许就是数据难搞一些,需要大量的数据来训练,这个看自己的造数据的能力了。

四、最后

很开心这个实验能够成功,思路相对来说很简单,但是看问题的角度却很新颖,其实神经网络的用法有很多,并不局限于某个任务,对于我们CV算法工程师而言,在做项目的时候思路应该要开阔、活跃,不能局限于某个算法只能用于某个任务,思维的到处碰撞没准能碰出个突破行规的idea出来,当时看到群里的大佬们讨论的时候迟迟想不通,最后还是自己走一遍才明白,所以也很开心将这个思路分享给大家。互相学习,相互进步。

你可能感兴趣的:(OCR,深度学习,pytorch,机器学习)