在学习过目标检测和字符识别后想用yolov5、crnn+ctc做一个车牌识别项目,本意是参考大佬们的项目,怎奈钱包不允许。网上有关车牌检测的基本都是引流贴,甚至有的连用到的公共数据集都不放链接,索性我也不找了,直接找原始数据集,从头开始搞。本文是一篇实战过程记录,仅记录我在车牌识别项目中的工作,不会牵涉过多理论知识。而且本次实战由于收集的数据集不太合适,导致效果较差,因此不建议读者直接搬用我收集的数据集。
功能:车牌识别分为车牌检测、识别两个部分,即先检测到车牌再识别检测到的车牌。不过我想在车牌检测、识别的基础上再加上车辆的检测,让项目变得更有意思一些。思路一:找一个带有车辆、车牌标注的数据集,使用yolov5训练-->使用crnn+ctc网络训练车牌识别-->推理时将检测与识别组合在一起,以达到预期的功能。可行性:没有找到合适的数据集,因此只能换一个思路了。思路二:将车辆检测、车牌检测的训练分开,分别收集数据集,使用yolov5训练-->使用crnn+ctc网络训练车牌识别-->推理时将检测与识别组合在一起,以达到预期的功能。可行性:数据集的收集较为容易,但是推理阶段的组合变得困难了。
数据集名称:BITVehicle_data数据集简介:北京理工大学实验室放出来的数据集,该数据集包含6个类别:公共汽车、微型巴士、小型货车、轿车、SUV和卡车,共9850张图片。数据集中不同时间和地点的两个相机捕获了大小为 16001200和 19201080的图像。图像包含照明条件、比例、车辆表面颜色和视点的变化。由于捕获延迟和车辆的大小,某些车辆的顶部或底部不包括在图像中。不过该数据集的标注是以.mat形式保存的,因此需要先转为适合yolov5的格式。数据集预处理:将标注转为**.txt**格式;将源数据集分为训练数据集和评估数据集,train:val=6000:3850
备注:角度单一,只有俯拍角度;场景简单,每张图中只有几辆车,因此应再找一些其他角度的数据集,以提高模型的鲁棒性。
数据集预处理:由于该数据集很大,我挑选了部分用于项目;从图片名字中将车牌检测的标注转为.txt格式。以下是提取ccpd车牌边界框标注的代码。
数据集名称:CCPD2019_data数据集预处理:从CCPD2019_data裁剪出车牌图像;从图片名字中将车牌提取车牌标签(车牌信息)。
备注:由于主要是在合肥采集,因此“皖”牌照居多,导致对其他省份的简称识别较差。
在字符识别中还需要将文字标签数字化,即我们用数字来表示每一个文字。比如“我”字对应的id是1,“l”对应的id是1000,“?”对应的id是90,如此类推,这种编解码工作使用字典数据结构存储即可,训练时先把标签编码(encode),预测时就将网络输出结果解码(decode)成文字输出。在开始编码、解码前,我们需要先明确字母表,它就是一个字符串。
下面让我们来看一下该字母表对应的编码、解码函数。
下面我们来crnn+ctc网络的训练,训练过程和普通的cnn网络没有多大的区别。唯一需要注意的是ctc损失函数的构建,这里我建议读者在进行这部分代码阅读前一定要仔细阅读pytorch官方文档的ctc损失函数部分。下面是训练的核心代码:
由于在检测部分使用的是yolov5,而yolov5拥有一套完整的代码,因此我们可以在yolov5的.detect基础上调整得到需要的推理代码。下面是推理的核心代码:
由于1)收集的数据集较为单一,如车辆检测仅有俯瞰正视角度、车牌检测无双层牌照图片、车牌识别80%以上是安徽牌照;2)场景不够丰富,如车辆检测中最多也才有三四辆车、天气、地理环境等单一;3)数据集体量小。以上原因导致模型的鲁棒性较差,只有在监控视角、车辆较少、且车辆是正视角度才能达到理想效果,其他场景下较为拉跨。本次项目由于数据集的原因导致成果十分不理想,建议读者重新寻找合适的数据集进行实战!以上是本次车牌识别实战的简单记录,如果本项目对您能有所启发,不要忘了点赞哦!