ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

基于YOLOv5的深度学习车牌识别系统实战全记录

基于YOLOv5的深度学习车牌识别系统实战全记录 简介本资源是一套基于YOLOv5实现的端到端车牌识别系统面向深度学习初学者与计算机视觉实践者解决真实场景下车牌定位、颜色分类与字符识别三大核心问题适用于智能交通、停车场管理、违章抓拍等AI落地场景。压缩包共675个文件含618张标注车牌图像jpg、20个核心Python脚本含数据预处理、模型训练、OCR识别与推理部署、7个YOLOv5配置文件yaml、3个预训练权重pth/pt及配套标签xml/txt整体体积575.9MB结构清晰模块解耦明确。已有4023人学习下载资源提供完整可运行流程从YOLOv5车牌检测模型训练、颜色分支扩展到CRNN类OCR对裁剪车牌图的字符识别附带.gitignore、.iml等工程配置与shell部署脚本便于快速复现与二次开发。 做深度学习车牌识别这个项目说实话最开始是应一个停车管理项目的需求要在摄像头抓拍画面里把车牌位置找出来、认出车牌颜色、再把车牌号读出来。当时调研了一圈传统图像处理方案对光照和角度变化太敏感最后还是选了YOLOv5作为检测主力配合分类网络做颜色识别字符部分用切分分类的思路。这篇就完整记录一下这个系统从设计到落地的全过程包括我踩过的坑和实测后的调整给准备做车牌识别的朋友一个参考。1. 项目整体设计与思路拆解1.1 这个系统到底要解决什么问题车牌识别系统的核心任务可以拆成三个子任务车牌定位在画面中找到车牌、车牌颜色识别判断是蓝牌、黄牌、绿牌还是其他、车牌字符识别把车牌号读出来。这三个任务看似独立但实际工程里它们之间是有依赖关系的。比如颜色识别结果可以用来校正字符识别的逻辑绿色新能源车牌和蓝色普通车牌的字符分布规则就不同。我选择YOLOv5作为检测主框架是因为它在小目标检测和实时性之间平衡得比较好。车牌在监控画面里占比通常很小可能只有几十个像素宽而且经常伴随运动模糊、夜间低照度、反光等问题。YOLOv5在COCO数据集上的表现虽然不算最顶尖但在自建数据集微调后对车牌这种纹理规则的目标能取得很不错的检测精度同时推理速度能跑到实时。这个系统的适用场景很明确停车场入口、小区门禁、高速收费站的辅助识别、交通监控视频的离线分析。适合具备一定深度学习基础、想快速落地车牌识别功能的开发者参考。1.2 为什么不用传统图像处理方案很多人会问车牌是矩形、字符是规则的为什么不用边缘检测轮廓查找模板匹配这类传统方案我刚开始也试过。传统方案在单一固定场景、光照稳定的条件下确实能跑通比如地下室停车场入口的固定机位。但一旦遇到晴天强反光、夜间车灯直射、雨天水渍干扰、车牌边框变形等情况边缘检测的稳定性会急剧下降车牌定位框会漂移字符分割也会出错。传统方案的另一个问题是没有学习能力。不同省份的车牌字体虽然有国标但实际印刷有细微差异模板匹配需要为每一种字体维护模板库维护成本很高。深度学习方案通过数据驱动只要标注足够多、足够多样的样本模型自己能学到鲁棒的特征对光照、角度、模糊的容忍度明显更高。我当时的结论是传统方案可以作为兜底策略但主力必须上深度学习YOLOv5是当前投入产出比最高的选择。1.3 整体技术架构与流程这个系统的处理流程分四步输入图像或视频帧送入YOLOv5检测模型输出车牌检测框坐标和置信度。根据检测框裁剪出车牌区域做透视矫正和图像增强为后续识别准备。对矫正后的车牌区域做颜色识别用HSV颜色空间阈值加小型分类网络结合的方式判断颜色类别。车牌区域送人字符识别模块完成字符切分和单个字符分类最终拼接成完整的车牌号码。这个流程看起来简单但每一步都有细节需要处理。比如YOLOv5检测的是整个车牌区域里面包含了边框和铆钉如果直接送进字符识别模块铆钉会被误切分为字符。所以第二步的预处理很关键后面会详细讲。2. 车牌检测与颜色识别YOLOv5的落地细节2.1 YOLOv5模型选型与参数配置YOLOv5有n/s/m/l/x五个版本参数量和推理速度逐级递增。车牌识别场景里我建议优先考虑YOLOv5s或YOLOv5m。YOLOv5n虽然最快但小目标检测能力弱车牌这种小目标容易漏检YOLOv5l和x适合离线批量处理实时视频流推理帧率上不去。我自己实测在1080p分辨率下YOLOv5s的推理速度在GTX 1660上大约能到60-70 FPSbatch1YOLOv5m大约40 FPS左右。对于停车场入口这种场景摄像头抓拍通常一秒两帧到三帧就够了YOLOv5s完全够用。如果你有NVIDIA Jetson这类边缘设备可以尝试TensorRT加速后面有一节专门讲。训练配置上有几个超参数值得关注img size训练分辨率建议640x640这和YOLOv5的默认anchor设计匹配。batch size根据自己的显存定16或32都可以。epochs车牌检测不是什么复杂任务300轮足够收敛再多容易过拟合。hyp/scractch.yaml里的mosaic默认1.0数据增强力度够强对小目标检测有好处。我踩过的一个坑是直接用YOLOv5默认的COCO预训练权重作为起点然后微调。这样做的基础是COCO数据集里有车牌类别吗其实没有但预训练权重已经学到了通用的边缘、纹理、形状特征微调时只需要让模型把这些特征重新组合成车牌的概念。我实验下来用COCO预训练权重微调比从零训练收敛快很多mAP也更高。2.2 车牌颜色识别的实现方式车牌颜色识别有两种主流做法我两个都试过。第一种是把颜色作为检测类别直接在YOLOv5的检测层里输出blue_plate green_plate yellow_plate这些类别。这样做的好处是端到端检测的同时就输出了颜色推理流程更短。但坏处是检测类别增多会让模型略微膨胀而且颜色特征在低照度下不稳定容易把蓝色车牌识别成绿色因为夜间蓝和绿的区分度会下降。还有一种情况是新能源绿色车牌和普通蓝色车牌在白平衡失调的画面里确实容易被混淆。第二种是检测到车牌后把车牌区域裁剪出来用单独的模块做颜色分类。我最终采用的是这种方案并且用了两层策略先用HSV颜色空间的像素统计做初步过滤再送入一个小型CNN分类网络做二次确认。这样做的好处是效率高HSV过滤只需几十毫秒CNN网络也很轻量整体延迟可接受。HSV的判断逻辑是这样的蓝色车牌H通道大约在100-130之间S饱和度较高。绿色车牌新能源H通道大约在35-85之间。黄色车牌H通道大约在15-35之间。白色车牌警车、应急救援S接近0且V很高。具体实现时先把车牌区域从BGR转到HSV统计满足各颜色阈值的像素占比占比最高且超过一定阈值就初步判定为对应颜色。然后把这个区域resize到64x64送进CNN分类网络输出蓝、绿、黄、白、黑五个类别的概率取概率最高的类别作为最终结果。这套策略实测准确率能达到95%以上主要误差集中在夜间光照不足导致HSV颜色偏移的场景CNN分类网络能挽回大部分误判。2.3 检测与颜色模型的训练关键点训练YOLOv5检测模型数据标注是第一大事。我标注了大概6000张车牌图片标注框紧贴车牌边缘包含边框但尽量不把车灯、保险杠等相邻区域框进来。类别就一个license_plate。颜色识别模型的数据不需要单独采集可以直接从检测模型预测结果中裁剪车牌区域然后按颜色类别归档。这一步自动化程度可以很高我用检测模型跑了2万张图片自动裁剪出车牌再人工筛选出约5000张清晰样本按颜色分类。这样省去了大量的人工标注工作。训练时要注意类别不均衡问题。蓝牌数量远多于黄牌和黑牌如果不做处理模型会偏向预测蓝牌。我采用的方法是加权采样每个类别在每轮训练中的采样权重与类别数量成反比让模型见到各颜色车牌的概率接近均匀。这个方法在小型数据集中特别有效。3. 车牌号识别字符切分与OCR方案3.1 端到端OCR还是字符切分车牌字符识别的主流方案有两条路线端到端OCR和字符切分分类。端到端OCR方案典型代表是LPRNet或CRNNCTC。这类方案直接输入车牌整图输出字符序列不需要显式的切分。优点是流程简洁不需要处理切分边界问题CTCLoss能自动对齐字符位置与序列标签。缺点是模型调优相对复杂CTC解码参数需要仔细调整而且对透视畸变和字符粘连比较敏感。我最终选择的是字符切分分类路线原因是这个方案更可控每个环节都能独立排查问题。切分错了可以针对性调整预处里分类错了可以单独加数据。对中小规模项目来说可解释性更重要。字符切分的流程是先对车牌子图做灰度化、二值化然后通过连通域分析或垂直投影找到每个字符的左右边界。国内车牌字符分布有规则第一位是省份简称汉字第二位是发牌机关代号字母后五位是序号字母和数字混合。字符间距相对均匀但也有特殊情况比如京A12345和京A·12345中间有点状分隔符需要特殊处理。3.2 车牌图像预处理预处理是字符切分成败的关键一环。我的预处理流程如下第一步是做透视矫正。YOLOv5检测框是水平矩形但实际车牌在画面中可能有倾斜比如车头略偏左或略偏右。直接用水平框裁剪出来的车牌子图会有透视变形。我用检测框四个角点作为参考配合车牌固定的宽高比440x140计算出透视变换矩阵把车牌子图矫正成正视角度的矩形。第二步是去噪和增强。车牌图像通常有椒盐噪声我用中值滤波处理。光照不均的区域可以用直方图均衡化做增强。第二步做得不好后续二值化阈值很难选。第三步是二值化。这里我踩过不少坑。直接用全局Otsu阈值在某些光照条件下会失败原因在于车牌底色和字符颜色对比度不足时Otsu会把底色误判为前景。我改用自适应阈值ADAPTIVE_THRESH_GAUSSIAN_C配合适当的blockSize和C值效果稳定很多。针对蓝底白字车牌还有一个技巧是先通过颜色通道分离提取蓝色区域作为掩膜把车牌背景和字符分离出来再做二值化这样准确率更高。3.3 字符识别与后处理字符切分完成后每个字符图像送入分类模型。分类模型用的是一个小型CNN结构类似LeNet输入尺寸32x32输出类别数6531个省份简称汉字24个字母10个数字其中字母I和O在车牌号中不使用。训练字符分类模型时要注意字体干扰问题。实际车牌字符可能与标准字体有细微差别比如0和O字形接近、1和I字形接近、8和B字形接近。训练时要确保数据集覆盖这些容易混淆的样本并在后处理逻辑中增加规则约束。比如车牌第二位必须是字母、序号中第一位是字母或数字等这些规则可以消除明显不符合车牌规范的输错。后处理还有一个关键点是拼接时机的把控。有些字符被铆钉遮挡连通域分析可能漏掉有些字符间距过近可能被分割成一段。我采用的方法是先做垂直投影粗切分再对疑似粘连的区域用固定宽度窗口细切分最后用分类模型置信度筛选置信度低于阈值的字符重新走细切分流程。4. 实操过程从数据准备到模型部署4.1 数据准备与标注规范整个项目最耗时的是数据准备。我前前后后花了两周时间收集和标注数据。数据来源主要有两个渠道一是停车场的实际监控录像二是网上开源的车牌数据集比如CCPD两者混合使用。CCPD数据集有几十万张带标注的车牌图片虽然标注格式和YOLOv5的格式不同但可以通过脚本转换成YOLOv5需要的txt标签格式。转格式时要注意坐标准换和类别编号。CCPD的标注是四点坐标需要转换成xywh中心点坐标类别编号要和训练配置里的类别顺序一致。如果只训练一个车牌类别类别编号就是0。如果要把颜色类别也加进去我建议分开训练不要让检测模型承担颜色分类的任务这样每个模型的负担都小准确率也更高。标注工具我用的是LabelImg它能直接导出YOLO格式的txt文件支持画矩形框自动编号保存对新手很友好。标注时注意框的紧致度框应该刚好框住车牌外边缘稍微留一点余地可以接受但不要框到周围背景。我见过很多人标注不严谨导致训练出来的检测框偏移严重对后续的字符识别影响很大。4.2 训练过程与验证训练环境我是在Ubuntu 20.04上用GPU跑的显卡是RTX 3080显存10GBbatch size设32没有压力。训练命令用的是YOLOv5官方仓库的train.py关键参数如下python train.py --data plate.yaml --weights yolov5s.pt --img 640 --batch 32 --epochs 300 --device 0这里plate.yaml文件里指定训练和验证数据的路径、类别数量和类别名称。训练过程我会用TensorBoard监控mAP0.5和mAP0.5:0.95的变化。车牌检测是一个单类目标场景相对单一一般来说mAP0.5能到98%以上mAP0.5:0.95能到85%以上就算不错了。验证阶段我额外制作了一个难例集专门挑那些夜间低照度、强反光、大角度倾斜、部分遮挡的车牌图片。难例集不参与训练只用来评估模型的实际泛化能力。模型可能在常规测试集上表现很好但在难例集上漏检率很高这时候就需要做难例挖掘把漏检的图片加入训练集继续微调。4.3 模型导出与部署优化训练完成后模型推理有几种方式。最简单的直接加载PyTorch权重推理适合原型验证。但实际部署我建议导出成ONNX再用TensorRT加速推理速度能提升2-3倍。导出命令大致如下python export.py --weights best.pt --include onnx --img 640然后用TensorRT的trtexec工具转engine文件或者用Python API动态构建engine。转完后推理速度在我的3080上YOLOv5s模型能从约4ms提升到约2ms在边缘设备上提升更明显。部署架构上我用的是FastAPI封装了检测服务接收图片base64编码返回检测框和识别结果。这样可以和业务系统解耦前端上传图片后端返回结构化JSON方便停车场系统调用。需要提醒的是视频流场景中不要对每一帧都做检测识别会出现大量重复结果而且计算开销大。我通常的做法是设置一个检测间隔比如每10帧检测一次或者用相邻帧检测框的IoU做去重如果检测框几乎没有位移就认为还是同一辆车。5. 常见问题与排查技巧实录5.1 检测漏检与误检怎么办漏检是车牌识别中最头疼的问题。常见原因有三个第一是车牌在画面中占比太小。如果摄像头角度太高或者车辆距离太远车牌可能只有十几像素宽YOLOv5的anchor根本匹配不上。解决办法是调整摄像头安装位置或者在推理时把输入分辨率从640提高到960甚至1280。提高分辨率会明显增加计算量但在边缘设备上通常还能接受。第二是强光反光导致车牌区域信息丢失。车牌表面有反光涂层在白天太阳光直射时车牌字符会白成一片人眼都看不清楚模型更难检测。这种情况的缓解手段是做数据增强时模拟高光让模型见过这种形态。另外在推理前对图像做MSRCR增强能在一定程度上恢复反光区域的纹理。第三是样本分布不均衡。如果训练数据里大量是正对车头的车牌模型对斜侧角的检测能力会变弱。解决方法是数据增强时加大随机旋转、随机透视变换的力度让模型见过足够多的角度变化。误检的情况相对少主要出现在车尾广告牌、车身贴纸、车灯造型等看起来像矩形的区域。误检的处理办法是过滤置信度阈值一般0.5以上才认为检测成功同时可以结合车牌的颜色特征做二次校验检测框区域的颜色分布不符合任何已知车牌颜色时直接丢弃。5.2 字符识别错误如何排查字符识别错误分为两类切分错误和分类错误排查时要区分。切分错误的表现是识别结果字符个数不对或字符宽度怪异。常见原因是二值化阈值选得不好导致字符粘连或断裂。我的排查经验是先把车牌子图可视化出来和二值化结果一起看。如果二值化后字符粘连成一片说明阈值过低或背景干扰太多可以调高自适应阈值的blockSize或者C值如果字符断裂成碎块说明阈值过高或图像噪声大需要先做中值滤波。分类错误是字符被正确切分但识别成错误的字符。最常见的混淆对是0/O 1/I 8/B 2/Z等。处理办法有两个层面数据层面多收集混淆样本模型层面在后处理中增加车牌规则约束。比如车牌第二位一定是字母所以如果第二位的分类结果里有数字概率高就要强制改为最可能的字母。另外一个容易被忽视的问题是铆钉干扰。车牌上固定车牌的铆钉位置在字符附近二值化后铆钉会变成一个圆点如果恰好和字符边缘相连就会被误认为一个字符。解决方法是先通过形态学开运算去除小连通域再根据车牌的几何先验字符高度占比、间距范围过滤掉不符合字符尺寸的连通域。5.3 性能瓶颈与环境配置问题性能问题主要出现在部署阶段。YOLOv5在GPU上性能没问题但很多实际项目跑在CPU的NVR或嵌入式设备上比如RK3568这样的平台。纯CPU推理YOLOv5s在1080p输入下可能只有几帧到十几帧的速度这时候需要结合模型剪枝和量化来加速。我实测过把YOLOv5s的模型用TensorRT的FP16量化在RK3568上推理时间能控制在100ms以内基本满足实时需求。如果还是不够可以考虑用YOLOv5n或进一步做模型蒸馏但精度会有一定损失需要测试。这时候可以参考rv1106搭建yolov5模型这类嵌入式搭建经验核心是把模型导出为RKNN格式在NPU上跑。环境配置方面新手最容易卡在PyTorch和CUDA版本匹配上。我的建议是直接用官方推荐的组合PyTorch 1.13或2.0配CUDA 11.7或12.1。安装时用conda创建独立环境避免污染系统Python。如果你在装Ubuntu 22.04或24.04时遇到驱动安装了没反应的问题大概率是显卡驱动和内核版本不匹配需要先卸载重装驱动再装CUDA Toolkit最后再装PyTorch这个顺序不能乱。6. 后续可扩展的方向系统做完后我发现还有几个可以继续完善的方向。一个是对多车牌场景的支持现在的模型只能检测单张图片中的多个车牌但还没有对同一辆车在不同抓拍时刻的车牌识别结果做关联和融合如果车辆跨摄像头移动需要加入车牌跟踪和去重逻辑。另一个是夜间红外图像的车牌识别目前很多停车场是24小时运行夜间依靠补光灯拍摄的是近红外图像车牌的成像特性和白天可见光差异很大需要单独训练一个红外域模型或者做域适应。还有一个小细节值得提就是车牌识别结果的置信度评估。在实际业务中我们不能只看模型输出的字符串还要给这个结果一个可信度分数。比如字符分类的置信度平均分、检测框的稳定性、字符切分的完整度把这些因素综合成一个置信度评分业务系统可以根据评分决定是自动放行还是转入人工审核。这个设计在停车场场景尤为重要可以减少错误扣费带来的客诉。我自己的体会是车牌识别系统看起来是一个标准任务但真正做完一遍才发现脏活累活全在细节里。模型训练反而是最顺手的一步数据清洗、难例挖掘、后处理逻辑这些看不见的工作才是决定项目成败的关键。如果你正在做类似的项目希望这篇记录能帮你少走一些弯路。本文还有配套的精品资源点击获取
返回列表