news 2026/9/1 16:41:26

基于YOLOv5的中文车牌识别方案:覆盖12种车牌与双层车牌处理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于YOLOv5的中文车牌识别方案:覆盖12种车牌与双层车牌处理

简介:本资源是一套基于YOLOv5实现的中文车牌端到端检测与识别完整方案,面向计算机视觉初学者、智能交通系统开发者及高校课程实践者,解决真实场景下多类型中文车牌(含普通蓝牌、新能源绿牌、警车、军车、使馆车等12类)及双层车牌的精准定位与字符识别难题。压缩包共146个文件,涵盖45个Python源码(含训练/推理/预处理脚本)、20个YAML配置文件(模型结构与超参定义)、15张JPG/PNG实测图像(如police.jpg、single_green.jpg等典型样本)、7个Shell部署脚本及5份Markdown使用文档,辅以Dockerfile、.pt模型权重与字体资源,整体大小24.91MB。已有166人学习下载,提供从环境配置、数据准备、模型训练到单图/视频推理的全流程可运行代码与详细说明,特别适配中文字符复杂结构与双层遮挡场景,开箱即用且便于二次开发与迁移学习。 车牌识别这个方向,做过的人都知道,真正落地的时候坑远比你想象的多。尤其是中文车牌,字符集里有汉字、字母、数字,还得面对蓝牌、绿牌、黄牌、白牌、黑牌,再加上大型货车挂车常见的双层车牌,一套模型要全部吃下来,不是简单拿个开源检测模型就能搞定的。

我最近在整理一套基于YOLOv5的车牌检测与中文车牌识别方案,整套源码加模型加使用文档都打包好了,标题里写得很清楚:支持12种中文车牌,双层车牌也能处理。这篇文章我就把整个方案的思路、核心细节、部署步骤、训练调优,以及我实际踩过的坑,完整拆开讲一遍。如果你正准备做停车场道闸、卡口监控、高速收费这种场景下的车牌识别,或者你只是想把这套流程跑通作为毕设、项目演示,这篇东西应该能帮你少走不少弯路。

1. 项目概述与整体设计方案

1.1 项目定位:检测+识别两条线分别处理

这套项目在最开始设计的时候,我就定了一个原则:检测是检测,识别是识别,两个环节彻底分开。为什么这么干?因为这两个任务的目标完全不同。

检测模型要回答的是"车牌在哪",它需要在整张图里找目标,哪怕是远距离、小目标、光线昏暗,也得尽量把位置框准。而识别模型要回答的是"车牌是什么",它只需要拿到一块裁剪好的车牌图像,把里面的字符逐个读出来。一个是全局任务,一个是局部任务,混在一起反而互相干扰。

常见的端到端方案,比如直接把OCR大模型套在车牌上,效果不是不行,但在实际部署时你会发现太重了,推理速度、显存占用、成本都压不住。而用YOLOv5做检测,再单独接一个轻量的车牌识别网络,两阶段各管各的,精度和速度都更容易调到理想状态。这套项目就是采用了两阶段设计:YOLOv5负责检测,背后再接一个专门为中文车牌字符集设计的识别模型。

1.2 为什么选YOLOv5而不是YOLOv8或更重的模型

很多人问我,现在YOLOv8、YOLOv9都出来了,你干嘛还用YOLOv5?

说实话,YOLOv5确实是"老"了一点,但它有两个优势是很多新模型比不了的:一是生态成熟,网上的资料、预训练权重、部署案例极多,遇到问题基本一搜就有解法;二是它对硬件的要求比较友好,从GPU到CPU,从PyTorch到ONNX再到TensorRT,整个转换链路我都跑过很多遍,非常稳。

另外,车牌检测本质上是一个单类别检测任务,背景相对单一,目标纹理特征明显,YOLOv5s这个体量完全够用。我在这套项目里默认用的是YOLOv5s作为检测模型,如果你想在嵌入式设备上跑,换成YOLOv5n,帧率还能再往上走。没必要一上来就上大模型,算力是要花钱的。

1.3 识别端为什么不能直接用通用OCR

有朋友图省事,想直接拿PaddleOCR或者Tesseract来识别车牌。我只能说,通用OCR在车牌场景下不太聪明。通用OCR训练数据里车牌图像占比极少,它擅长的是印刷体文本,面对车牌这种特殊字体、特殊背景、特殊字符排列,识别率会掉得很厉害。

车牌识别必须走专用模型。中文车牌的字符集是固定的:省份简称汉字、大写字母、数字,字符数量有限且完全封闭。所以识别端的模型设计更适合用轻量的CNN+RNN+CTC结构,字符表就写死在代码里,模型只需要在这几十个类别里做分类,准确率自然要高得多。这套项目里识别端就是按照这个思路做的,训练完成后单张车牌识别耗时在毫秒级。

2. 核心技术细节拆解:12种车牌与双层牌处理

2.1 12种中文车牌类型都是哪来的

"支持12种中文车牌"不是营销话术,这是国内路面上常见的车牌类型的合集。我在这套项目里按底牌颜色和车辆属性分别统计过,主要的车牌类型包括以下几类:

车牌类型底色字符颜色适用范围
小型汽车蓝牌普通燃油小型车
大型汽车黄牌大型客车、货车
新能源小型车绿牌绿黑/白纯电、混动小车
新能源大型车绿牌绿黑/白纯电、混动大车
教练车黄牌驾校教练车
警用汽车白牌公安、司法警车
军用汽车白牌黑/红军车
驻华使馆黑牌使馆车辆
涉外外企黑牌外资企业车辆
港澳入出内地车牌粤Z港/澳
挂车黄牌半挂车
农机/其它专用牌绿/黄农用、专项作业

不同车牌的底牌颜色差异很大,这对检测模型来说是个天然的挑战。YOLOv5在训练时如果用了足够的颜色增强和曝光增强,模型会慢慢学会"不看颜色看结构",因为车牌本身的字符排版、边框比例、反光特征是有共性的。

2.2 双层车牌为什么那么多项目翻车

双层车牌主要集中在大型货车、挂车上,常见形式是上面一行是省份简称和发牌机关代码,下面一行是号码,整体高度比普通车牌高一倍左右,宽高比例和普通蓝牌完全不一样。

很多开源项目翻车,不是模型能力不够,而是数据处理阶段就没考虑双层牌的情况。如果把双层车牌和单层车牌混在一起做检测,YOLOv5默认的anchor对长条形目标不友好,很容易出现漏检或者框不完整的情况。而且识别模型如果不单独针对双行字符做训练,直接把整块双层车牌压成一张小图送进识别网络,字符挤在一起,CTC解码效果会非常差。

这套项目里我做了两个关键处理。检测端,我在anchor设置里加入了一组长宽比比较大的先验框,专门适配双层车牌;同时在训练数据增强步骤中,对双层车牌做了单独的尺寸扰动,避免模型只见过一种尺度。识别端,我实现了一个双行判断逻辑:当前面检测输出的目标框高宽比超过阈值时,自动将车牌图像按中间线切分成上下两部分,分别送进识别网络,再把结果拼成最终字符串。这样双层车牌从"一张图硬识别"变成了"两行分别读",识别率一下就提上来了。

2.3 字符集设计:不只31个省份简称

识别端默认支持的字符集大概是这么个构成:全国31个省级行政区简称汉字、24个大写英文字母(I和O容易和数字混淆,通常剔除或做特殊处理)、10个数字,再加上少量特殊字符比如挂车用的"挂"字、警车用的"警"字、使馆用的"领"字,整体字符表大约在65个上下。

设计字符集的时候有一个细节很多人会忽略:汉字部分必须跟实际业务场景匹配。比如你做的是某个省的本地项目,理论上可以只保留部分省份简称来减小分类难度,但如果你做的是通用闸机、全国道路监控,字符表就不能砍,必须全量保留。这套项目默认是全量字符表,但代码里预留好了配置接口,你可以在字符表文件里自由增删。

2.4 识别模型结构:CNN+RNN+CTC三板斧

识别端的核心网络结构,我用了类似LPRNet和CRNN结合的一套轻量方案。输入是一张固定尺寸的车牌图像,比如宽94高24或者宽168高48,先经过几个卷积层提取特征,再经过两到三层双向LSTM建模序列上下文,最后接CTC损失函数完成字符序列对齐。

CTC这个损失函数是整个识别链路里最关键的一环。车牌字符间距不固定,不需要像传统OCR那样先做字符分割,CTC允许模型为每个位置输出一个字符概率分布,然后通过动态规划寻找到最可能的字符序列。这就省去了字符分割这个最大的误差源。我试过先分割字符再逐个识别的方案,遇到字符粘连、铆钉遮挡、边框干扰的时候直接崩,换了CTC之后稳了很多。

3. 环境部署与快速上手

3.1 环境依赖与版本匹配

拿到压缩包解压之后,第一步是把环境搭起来。这套项目基于PyTorch,Python版本建议3.8以上,PyTorch建议1.8到2.x之间都行,CUDA版本看你手里的显卡驱动来定。

装依赖的时候有个坑:YOLOv5的requirements.txt里torch版本如果跟你的CUDA不匹配,import的时候就会报错。我建议先单独装好PyTorch,再装其它依赖。如果你只是推理,不打算重新训练,CPU版本也完全可以跑,只是速度会慢一些。整个依赖清单大概包括:torch、torchvision、numpy、opencv-python、matplotlib、pandas、pyyaml、tqdm、seaborn,如果要用到模型导出,还需要onnx和onnxruntime。

3.2 源码目录结构解读

解压后你会看到这样一个目录结构:

plate_project/ ├── detect.py # 检测入口,YOLOv5风格的推理脚本 ├── train.py # 训练入口,支持训练检测模型 ├── recognize.py # 识别入口,加载识别模型输出车牌字符串 ├── run_pipeline.py # 检测+识别串联脚本 ├── models/ # YOLOv5网络定义 │ ├── yolov5s.yaml │ ├── yolo.py │ ├── common.py │ ├── plate_rec.py # 车牌识别网络定义 ├── weights/ │ ├── plate_detect.pt # 检测模型权重 │ └── plate_rec.pth # 识别模型权重 ├── configs/ │ ├── plate.yaml # 检测数据集配置 │ └── rec_chars.txt # 识别字符表 ├── datasets/ # 训练数据路径 ├── utils/ │ ├── anchors.py # anchor计算工具 │ └── plate_utils.py # 双层车牌判断与切分工具 ├── docs/ │ └── 使用文档.pdf └── requirements.txt

这个结构其实已经把YOLOv5官方仓库的工程习惯继承下来了。detect.py和train.py的调用方式跟官方非常像,你如果跑过YOLOv5,上手几乎零成本。识别网络的代码单独放在plate_rec.py里,和检测部分解耦,方便你替换成自己的网络结构。

3.3 用自带权重串起整个流程

跑通整个项目非常简单。先用预训练检测权重跑YOLOv5的推理脚本,输入一张测试图片:

python detect.py --weights weights/plate_detect.pt --source test.jpg --conf 0.5 --img 640

这个命令会输出检测到的车牌位置,生成标注好的图片。如果你只想看检测框效果,这一步就够了。但要输出车牌字符串,还得接着跑识别:

python recognize.py --det-weights weights/plate_detect.pt --rec-weights weights/plate_rec.pth --source test.jpg

如果你嫌两步麻烦,直接跑串联脚本:

python run_pipeline.py --source test.jpg

它会自动完成"全图检测 -> 切出车牌 -> 判断单双层 -> 识别字符 -> 输出结果"这一整条链路,最终在终端打印出类似"粤B12345"这样的字符串。

3.4 模型文件必须注意的加载细节

模型文件这块有几点经验要分享。第一,检测权重是.pt格式,它就是PyTorch的checkpoint,里面除了模型状态字典之外,还保存了训练时的超参数、类别名称、anchor配置等元信息,所以用YOLOv5的官方工具加载非常方便。第二,识别权重是.pth格式,它只存了模型参数,你需要保证网络定义里的字符表顺序和训练时完全一致,否则识别结果就是乱的。

我见过最多的错误就是有人自己改了rec_chars.txt里的字符顺序,但没重新训练模型,结果模型还是按原来的顺序输出,对不上。所以记住一句话:改字符表不重训,等于白改。

4. 训练自己的数据集与模型优化

4.1 数据采集与标注规范

如果你需要适配特定的场景,比如某个停车场出入口角度特别刁钻,或者想提升夜间识别率,就得准备自己的数据去微调。数据采集时,我建议一个场景至少拍3000到5000张,覆盖不同时间段、不同天气、不同距离、不同角度。

标注工具我用的是LabelImg,标注输出格式选YOLO格式,也就是每张图片对应一个同名txt文件,文件里每行是"类别序号 中心点x坐标 中心点y坐标 框宽 框高"。这套项目里检测类别就一个,所以类别序号永远是0。标注的时候要特别注意,框要贴着车牌边缘,不要留太多背景,也不要切掉字符。框的质量直接决定检测精度,这一点我在实战中反复验证过。

4.2 数据集目录组织与配置文件

YOLOv5的约定是images和labels两个权重目录分别存放图片和标注文件,train和val拆开。目录结构大概是这样的:

datasets/plate/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/

然后在configs/plate.yaml里写上:

train: datasets/plate/images/train val: datasets/plate/images/val nc: 1 names: ['plate']

这里nc是类别数量,因为车牌检测只有一个类别,所以是1。names里给一个名字就行。如果你把检测任务自己扩展成"车头+车尾+车牌"多类别,再在这里加名字。

4.3 训练参数设置与迁移学习

一切就绪后,用预训练权重做迁移学习:

python train.py --img 640 --batch 16 --epochs 200 --data configs/plate.yaml --weights yolov5s.pt --device 0

几个关键参数说一下。img是训练分辨率,我默认用640,如果你的场景里车牌普遍很小,可以提到768或960,但显存占用会涨。batch在16G显存上跑yolov5s最多16到32,建议16。epochs如果你是微调,100个epoch就够,如果是从头训练,至少300。weights这里可以指向YOLOv5官方在COCO上预训练好的yolov5s.pt,它已经学会了通用的视觉特征,能显著加速收敛,比随机初始化好太多。

训练过程中,YOLOv5会自动生成训练曲线图,重点关注mAP@0.5这个指标。如果检测场景不复杂,mAP@0.5一般能到98%以上。到不了的话,大概率是数据问题而不是模型问题。

4.4 数据增强与双层车牌专项优化

YOLOv5内置了很多数据增强策略,其中Mosaic增强是把四张图拼成一张训练,对小目标检测尤其友好。车牌检测场景里,小目标特别多,如果是远距离卡口抓拍,车牌可能只占整张图几十个像素,没有Mosaic增强,模型很难学到这种特征。

针对双层车牌,我在plate_utils.py里加了一个专门的增强逻辑:训练阶段会把双层车牌的样本以一定概率随同单层车牌进行混合缩放,保证模型见过的双层车牌尺寸分布足够多样。另外,对双层车牌样本我额外增加了水平翻转和轻微旋转变换,因为大车挂的双层车牌往往带有一定倾斜角,特别是行驶状态下拍摄时,只做垂直矫正是不够的。

4.5 模型导出:从PyTorch到ONNX再到TensorRT

训练好检测模型之后,部署一般不会直接拿.pt跑,尤其是生产环境。常规做法是先导出ONNX,再转换成TensorRT的engine文件,或者用OpenVINO跑CPU推理。

导出ONNX可以用官方脚本:

python export.py --weights weights/plate_detect.pt --include onnx --img 640

导出的时候要注意opset版本和动态维度设置。用TensorRT部署时,建议把batch固定为1,关闭动态shape,这样能拿到最大的优化空间。识别模型也可以导出成ONNX,整个流程跑下来速度提升非常明显。我的实测数据是:同样的显卡上,PyTorch直接推理单张图像全程大约12毫秒,TensorRT优化后大约5毫秒,差别还是很大的。

5. 常见问题与排查技巧实录

5.1 高频问题速查表

我把这套项目在实际运行中最高频的问题整理成了一个表格,都是真实踩过的坑,照着排查能省不少时间。

现象可能原因解决方案
检测不到远处的小车牌输入分辨率太低,anchor尺寸过大推理时提高img分辨率到960以上,或对anchor做重聚类
检测框比车牌大一圈标注框不贴边,数据不干净清理标注数据,重新标注
蓝牌识别成黄牌数据不均衡,蓝牌样本占比过高增加黄牌、绿牌样本数量,或用类别平衡采样
双层车牌识别成乱码识别端没有走双行切分逻辑检查plate_utils.py中双行判断阈值是否匹配实际数据
绿牌前两位字母反复错新能源车牌字符间距与蓝牌不同单独对绿牌样本做字符间距归一化增强
夜间图片完全识别不出训练数据缺少夜间样本采集夜间数据,或在增强中增加随机亮度和对比度扰动
推理速度只有几帧在CPU上跑大模型换yolov5n检测权重,识别端也换成轻量配置
输出字符串多了一个字CTC解码参数设置有误检查识别代码里beam search或greedy decode的参数

5.2 检测框不准的排查顺序

很多人一上来就调模型参数,其实方向错了。检测框不准,首先检查的是标注文件。我从数据里随机抽几张图,把标注框画出来看,经常发现标注框要么偏大要么偏小。标注质量决定了模型能力的上限,模型再怎么调参也突破不了数据本身的天花板。标注修一遍,效果立竿见影。

如果标注没问题,再看anchor。YOLOv5官方在COCO数据集上聚类得到的anchor是通用物体尺寸,比如人要站直、车是长方体,跟车牌这种扁平目标的尺寸差异很大。用官方anchor不用重新训练,但如果你想榨干精度,可以用工具在训练集上重新聚类anchor,这一项通常能提升1到2个点的召回率。

5.3 双层车牌识别乱码的详细处理

双层车牌识别乱码,90%的原因是没有正确触发双行切分逻辑。我的实现里,判断依据是检测框的高宽比,经验阈值是高度除以宽度大于0.35就认为是双层车牌。不同相机分辨率下,这个阈值可能需要微调。

切分的时候要注意,上下两行不是简单从中间一刀切。大型货车的双层车牌经常上少下多,比如上面是"粤B",下面"12345挂",中间分隔线不一定落在正中。我的解法是先对车牌图像做水平投影,统计每一行的字符像素密度,然后根据投影谷底找到两行的分界线。这样比固定切分稳健很多。

切分完成之后,把上下两行各自送进识别网络,如果某一行太窄,需要先做等比例放大,统一缩放到训练时使用的输入尺寸。最后拼接字符串时,注意"挂"字的位置,挂车车牌通常在第二行的末尾。

5.4 数据不平衡怎么解决

车牌识别项目里数据不平衡几乎是必然的。蓝牌最多,绿牌其次,白牌、黑牌本来就少,双层大车车牌更是稀缺样本。如果不做处理,模型会对少数类别欠拟合,识别率上不去。

我用过比较有效的手段是复制粘贴增广:把少数类别的车牌图像,通过缩放、旋转、透视变换之后,粘贴到真实道路背景图上,生成大量合成训练样本。这种方法的收益比单纯重复采样高很多,因为模型不仅能见到更多目标实例,还能见到不同的环境上下文。

另外,训练时也可以用类别加权采样,让batch里少数类别的出现概率提高。YOLOv5官方训练脚本里没有直接提供这个功能,但我在自定义dataset里简单扩展了一下,效果不错。

5.5 多角度、透视畸变下的识别技巧

车牌识别最怕的不是模糊,而是透视畸变。车辆从侧面驶过,相机斜着拍,车牌在图像里是梯形甚至更扭曲的形状,直接送进识别网络的时候字符都歪了。

我的标准做法是检测出车牌后,先做透视校正,也就是常说的四点对齐。用车牌检测框投影到原图的四个角点,再利用OpenCV的getPerspectiveTransform和warpPerspective,把车牌区域矫正成规则的矩形。这一步对识别率提升非常明显。我在测试集上做过比对,不做校正的识别率大概88%,做了之后能到95%以上。

如果你用的是这套项目的run_pipeline.py,里面已经把透视校正作为默认选项开启了。但如果你打算串到自己的代码里,一定不要漏掉这一步。

6. 一些诚实的总结与扩展建议

这套项目跑下来,我个人最大的体会是:车牌识别难的不是某个单一模型,而是整套链路里每个环节的配合。检测要稳,切图要准,透视矫正不能省,识别模型要贴字符集,双行判断要灵活。任何一个环节掉链子,最终的用户感知都是"识别不对",但你永远不知道是哪一环出了问题。所以做这类项目时,我强烈建议你把每个模块独立测试一遍,再串起来整体测试,这是排查问题最省时间的方式。

如果你想在这个基础上继续扩展,我建议关注两个方向。一个方向是把检测模型替换成更轻量的版本,比如用YOLOv5n微调,配合TensorRT部署到Jetson NX或者RK3588这类嵌入式设备上,实现一个纯边缘端的车牌识别盒子。另一个方向是增加一个车辆跟踪模块,用ByteTrack或者DeepSORT把视频流里同一辆车的不同帧关联起来,多帧投票决定最终的车牌字符,这样能大幅降低单帧误识别对结果的影响。这两个方向都是我实测过有效果的,遇到具体问题可以再单独聊。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 16:39:22

Python 中获取环境变量的全面指南

中获取环境变量的全面指南身处开发进程里, 环境变量属于一种相当关键的配置途径, 它能让我们于不改动代码的情形下, 依据不一样的运行环境(像是开发环境、测试环境、生产环境)去动态调节程序的表现, 提供了简便且强大的办法来获取环境变量, 本文会详细阐…

作者头像 李华
网站建设 2026/9/1 16:37:39

2023携程春招技术岗笔试复盘:考点剖析与备战指南

刚参加完2023年携程春招技术通用岗第二批笔试,趁记忆还热乎,赶紧把题目类型、考点分布、做题节奏这些整理一遍。这批笔试整体给我的感觉是:不像某些大厂上来就搞 hard 级算法题压场,携程更看重基础扎实度、工程思维和快速编码能力…

作者头像 李华
网站建设 2026/9/1 16:37:34

计算机毕业设计之基于Java 的汽车维修保养管理系统的设计与实现

随着新世纪无纸化办公方式的普及,自动化信息处理和基于网络的信息交互方式已被广泛应用。现在很多行业基本上都是交由计算机进行管理和测试,网络与计算机已成为整个线上管理体系中的重要组成部分。虽然信息技术广泛应用和数据存取更加方便,但…

作者头像 李华
网站建设 2026/9/1 16:37:13

Zephyr RTOS深度解析:从环境搭建到与FreeRTOS的2026选型对比

这次我们看的不是又一个套壳工具,而是一个真正对标 Linux、却跑在微控制器上的实时操作系统:Zephyr。Zephyr 的定位很特殊,它不是 FreeRTOS 那种“小而美”的任务调度器,也不是 RT-Thread 那种“国产全功能物联网 OS”&#xff0c…

作者头像 李华
网站建设 2026/9/1 16:36:27

Maya风格化场景建模实战:从布线逻辑到日系烤肉店全流程解析

1. 先搞清楚“风格化场景”到底要解决什么问题如果你刚开始接触 Maya 场景建模,看到“日系风格化烤肉店”这种标题,可能会觉得这是一个炫技的复杂项目。但实际做下来,你会发现它的核心价值不在于做出多么写实的模型,而在于通过一个…

作者头像 李华
网站建设 2026/9/1 16:34:37

pdf转ppt的几种方法,亲测有效的6种方案

技术背景与需求分析 PDF与PPT虽然都在演示场景中频繁出现,但两者的底层结构完全不同。PDF以“页面描述”为核心,每个元素都有固定坐标和层级关系;PPT则以“幻灯片”为组织单元,文字、形状、图表各自独立可编辑。因此,…

作者头像 李华