YOLOv5车牌识别实战:从环境搭建到训练部署全流程指南

发布时间:2026/10/11 9:12:52

YOLOv5车牌识别实战:从环境搭建到训练部署全流程指南 简介基于YOLOv5的车牌识别项目面向具备一定Python基础、希望掌握目标检测与字符识别完整实战流程的开发者。支持对指定图像完成车牌定位并输出文字结果适用于停车场管理、交通监控、车辆出入登记等场景。压缩包共85个文件包体约475.22MB主要包含25个py源码模型结构、训练与预测脚本、7个yaml网络配置、5个xml标注文件、5个txt说明、3个pth/pt预训练权重、11张jpg测试图以及依赖清单、中文字体、模型下载脚本等配套文件目录按核心代码、权重、数据与工程配置分层组织结构直观易于检索。项目集成LPRNet车牌识别模块与YOLOv5/YOLOv4检测网络配合可直接加载权重推理也支持使用自带样张与权重进行二次训练帮助理解从检测到字符识别的完整链路。已有2310人学习下载特别适合AI竞赛、毕业设计或企业级车牌识别系统的工程实践。1. 车牌识别用 YOLOv5为什么这个组合最容易被复现车牌识别这个需求从停车场道闸到园区安防都有看起来简单真上手才知道坑都在细节上。用 Python 做 YOLOv5 车牌识别是目前最容易被复现的一条路YOLOv5 的训练和推理管线足够成熟社区资料多遇到问题搜得到车牌这种目标形状规整、类别少用默认的 COCO 预训练权重做迁移学习几十张车牌图就能把 mAP 拉起来。这份资源的核心就是一条链路用 YOLOv5 对指定图像做车牌检测输出带框的可视化结果和结构化标签。适合正在做毕设、接小项目或者想快速落地车牌检测的开发者。接下来我会把环境配置、推理参数、数据集格式、训练调优和常见翻车点按实际操作的顺序过一遍。2. 先看懂模型与数据集网络结构、超参数与标注格式2.1 YOLOv5 网络结构从 CSPDarknet 到 Detect 头YOLOv5 的主干网络是 CSPDarknet53它把基础残差块改成了 C3 结构也就是在残差连接两侧各加一个 1x1 卷积做通道压缩。这样做的直接收益是梯度回传路径更丰富同时计算量比普通残差块低。颈部网络用的是 PANet自顶向下和自底向上两条路径都有特征融合小目标和大目标都能兼顾。检测头是三个不同尺度的输出分别对应 80x80、40x40、20x20 的特征图分别负责小、中、大目标。车牌在图像里通常占的面积不大尤其是远距离拍摄时所以决定检测上限的往往是 80x80 那个分支的浅层特征。训练时如果发现小目标漏检优先怀疑的不是网络结构而是输入分辨率--img和训练数据里小目标的占比。锚框这部分容易被忽略。YOLOv5 在训练前会自动基于你的数据集重新计算锚框尺寸具体在train.py里调用check_anchors完成不需要手动指定。但推理时权重文件里已经固化了锚框所以换数据集训练后必须用新的权重文件去做推理拿旧的yolov5s.pt直接替换数据集的检测框尺寸会不贴合。2.2 车牌数据集的标注与目录组织做车牌检测有两个层级检测车牌区域本身以及识别车牌上的字符。资源标题说的是「识别车牌」我通常理解为先框出车牌区域如果要做字符级识别需要在检测框基础上再叠加字符分类模型。绝大多数项目场景比如道闸和安防第一步先把车牌框准准确率就能到九成。数据集目录组织是固定的套路YOLOv5 训练脚本默认按这个结构读取dataset/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/每个图像对应一个同名.txt标签文件文件里每行代表一个目标格式是五个数字类别索引、归一化后的中心点 x、中心点 y、宽度 w、高度 h。比如一张 1920x1080 的图某个车牌的像素坐标是左上角 (1200, 500)、宽 300、高 90那对应的标签行就是0 0.703125 0.504630 0.156250 0.083333这里的 0 是类别号如果你是单类车牌检测所有行都是 0如果你把车牌字符分成省份汉字、字母、数字共 65 类那类别号就从 0 到 64。算归一化坐标时用(x_center / width)和(y_center / height)宽度同理注意一定是中心点坐标而不是左上角坐标这是新手最容易标错的地方。标注工具用 labelImg 或者 labelme 都行labelImg 导出 YOLO 格式最省事。标注时框稍微贴近车牌边缘留一点边距就行框太大把车标或保险杠包进去会引入噪声。2.3 超参数文件想改训练效果先改这里YOLOv5 的超参数集中在data/hyps/hyp.scratch-low.yaml这类文件里训练时用--hyp指定。资源里如果用默认配置训练大概率能出结果但效果上限取决于这几个参数参数默认值作用车牌场景建议lr00.01初始学习率数据量小时降到 0.005mosaic1.0马赛克增强启用概率数据少时保持 1.0 提泛化hsv_h/hsv_s/hsv_v0.015/0.7/0.4颜色增强幅度车牌颜色敏感s 降到 0.4fliplr0.5水平翻转概率汉字会翻转降到 0.0degrees0.0旋转增强角度可设 5.0模拟视角偏差这里有个细节车牌是强颜色特征的目标蓝底白字、绿底黑字、黄底黑字颜色本身是判别信息。HSV 增强调太高会把蓝色车牌增强成紫色反而干扰特征学习。我一般把hsv_s从 0.7 降到 0.4保留一点颜色抖动用来应对不同曝光但不至于让色相漂移。水平翻转对车牌识别是双刃剑。如果只做车牌区域检测翻转没问题如果做字符识别翻转后 京A12345 变成 54321A京字符顺序语义全乱了。所以做字符级识别时fliplr直接设 0。3. 环境搭建到首次推理从 python 环境变量到 detect.py 跑通3.1 Python 环境与依赖安装先把 Python 环境弄干净。Windows 上装 Python 时记得勾选 Add Python to PATH不然后面pip命令全是不是内部或外部命令。装完后在命令行验证python --version pip --version如果python能执行但pip报错常见原因是 Scripts 目录没进环境变量手动把C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\Scripts加到 PATH 里就行。Linux 上则注意系统自带的 Python 版本Ubuntu 20.04 默认是 Python 3.8直接装依赖通常没问题但如果是 Ubuntu 22.04 的 Python 3.10个别旧版本 YOLOv5 会有兼容问题。推荐用虚拟环境隔离项目避免把系统 Python 搞乱python -m venv venv source venv/bin/activate # Windows 上执行 venv\Scripts\activate pip install -r requirements.txtYOLOv5 的requirements.txt里核心依赖是 torch、torchvision、opencv-python、numpy、pandas 和 matplotlib。CPU 环境跑推理没问题训练建议先确认有没有 NVIDIA GPU。用nvidia-smi看驱动再装对应版本的 PyTorch。我踩过最大的坑就是 torch 和 CUDA 版本对不上训练时直接报CUDA error: no kernel image is available这个后面避坑章细说。3.2 下载模型权重与首次推理权重文件建议从官方仓库的 release 页面下载资源里如果没有附带训练好的权重先用yolov5s.pt做基线测试。下载后放在项目根目录然后准备一张包含车牌的图片作为测试输入。推理命令最简版是这样python detect.py --weights yolov5s.pt --source test.jpg --conf-thres 0.25跑完后在runs/detect/exp目录下会生成标注了检测框的test.jpg和对应的test.txt标签文件。第一次跑通就算链路通了。这个命令做了四件事读取权重文件构建网络、加载test.jpg、前向推理得到候选框、过滤后把结果画到图上。--source支持单张图、目录、视频流和摄像头 ID比如传--source 0就是用默认摄像头实时检测。3.3 推理参数详解conf-thres、iou-thres、device--conf-thres是置信度阈值默认 0.25。意思是一个检测框的概率低于 0.25 就丢弃。车牌检测场景建议从 0.5 起步调试。阈值设太低背景区域会被误判成车牌尤其是深色车身上的反光区域设太高模糊的远距离车牌就会被滤掉。这个参数没有标准答案取决于你的图像来源入口道闸近景可以拉到 0.6监控杆远景 0.3 可能才不漏检。--iou-thres是 NMS 的 IoU 阈值默认 0.45。它决定两个重叠框是否合并。车牌目标不会密集堆叠这个值保持默认就行除非你在一张图里同时检测多块重叠的临时车牌。--device选择推理设备--device cpu指定 CPU--device 0指定第一块 GPU。CPU 推理一张 640x640 的图大约 200 到 400 毫秒GPU 能到 20 到 40 毫秒。部署到 RK3568 这类边缘板子上时因为硬件指令集差异一般要先做 ONNX 导出再量化成 int8直接跑 .pt 文件性能很差。推理时还有一个值得改的参数是--img默认 640。你的测试图如果是 1920x1080按 640 输入推理等效于把原图缩到 640远处小尺寸车牌可能丢细节。把--img 1280加上去小目标召回会明显改善但推理时间也会涨约两倍。4. 训练自己的车牌模型数据准备、标签修正与训练命令4.1 数据集划分与 yaml 配置用资源自带的数据集或者自己标的数据第一步是划分训练集和验证集。划分不是随便拆要避免同一辆车出现在两边。真实场景里同一辆车的车牌在训练集和验证集各出现一次验证集的 mAP 会被虚高因为模型记住了这辆车的特征而不是车牌特征。最简单的方式是按拍摄时段或按图片所在目录划分。划分完数据集写一个data.yamltrain: dataset/images/train val: dataset/images/val nc: 1 names: [license_plate]nc是类别数这里是单类names列表里的名称要跟训练时的类别索引一一对应。如果你要做 65 类字符识别names就是 31 个省份简称加 10 个数字加 24 个字母的完整列表顺序一旦定下来不能再改改了对不上标签就全乱。标签文件本身也要抽查。我每次训练前必跑一段校验脚本看标签坐标是否越界、是否有负值import os label_dir dataset/labels/train for f in os.listdir(label_dir): with open(os.path.join(label_dir, f)) as fp: for line in fp: parts line.strip().split() cls, x_c, y_c, w, h int(parts[0]), float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) if w 0 or h 0: print(f{f}: 非法宽高) if x_c 0 or x_c 1 or y_c 0 or y_c 1: print(f{f}: 中心点越界) if x_c w / 2 1 or x_c - w / 2 0: print(f{f}: 边界溢出)坐标系归一化后中心点坐标和宽高都必须落在 0 到 1 区间。边界溢出表现在检测框会往图外延伸训练时损失函数照常计算但推理结果会在图像边缘出现半截框。4.2 训练命令与超参数调整训练命令最常用的是python train.py --data data.yaml --weights yolov5s.pt --epochs 100 --batch-size 16 --img 640 --hyp data/hyps/hyp.scratch-low.yaml--weights yolov5s.pt是迁移学习的起点。COCO 预训练权重里已经有通用的特征提取能力车牌这种目标虽然 COCO 里没有但底层的边缘、纹理、颜色特征是可迁移的这比从头训练收敛快得多。如果你的数据集很小比如只有几百张图强烈建议保留--weights参数从头训练几百张图基本过拟合。--batch-size受显存限制。16G 显存跑 640 分辨率、yolov5s 模型batch 16 没问题8G 显存就降到 8。显存不够时会报CUDA out of memory这时候不是调代码能解决的老老实实降 batch 或者换yolov5n这种更小的模型。训练日志里每轮结束会保存权重到runs/train/exp/weights/last.pt是最后一轮的best.pt是验证集 mAP 最高的。断点续训用--resume runs/train/exp这个参数很关键训练到一半断电或者崩了不需要从头再来。4.3 训练结果解读从 result.png 判断欠拟合还是过拟合训练结束后runs/train/exp/目录下有一张results.png里面有训练过程的损失曲线和验证集指标曲线。这是判断训练状态的核心依据不要只看最终 mAP 数字。看这张图有三个重点。第一看train/box_loss和val/box_loss两条曲线如果训练损失持续下降但验证损失在第 40 轮左右拐头上升典型过拟合对策是增加数据增强强度、加 dropout 或者缩小模型。第二看metrics/mAP_0.5曲线是否还处于上升趋势如果训练到 100 轮还在涨说明没训满加大--epochs继续训。第三看metrics/precision和metrics/recall的相对关系precision 高 recall 低说明模型保守框出来的基本都对但漏检多反过来则是误检多。还有一个黑匣子一样的问题训练损失曲线震荡幅度大。这通常是 batch size 太小或者学习率偏高把lr0从 0.01 降到 0.002 再训一轮曲线会平滑很多。车牌检测的收敛速度比通用目标检测更快类别少、目标尺度集中一般 50 到 80 轮就能稳定。5. 避坑车牌识别里最容易翻车的五个问题现象一训练正常但推理时蓝牌全检出来了绿牌一个不漏地漏检。原因数据集中蓝牌样本占比超过九成模型把「蓝色区域」当成了最强特征新能源绿牌的颜色特征没有被充分学习。解决按颜色类别重新平衡数据集蓝牌和绿牌比例控制在 3:1 以内或者用数据增强把绿色车牌的样本多复制几份注意是复制并做轻微仿射变换不是简单重复。我在一个停车场项目里就是这么翻车的甲方给的图片九成是蓝牌绿牌检出率只有 20%。现象二同一张图--img 640检测不到车牌--img 1280能检测到。原因输入分辨率过低车牌在缩放过程中丢失了细节特征。远距离监控画面里车牌可能只有 20x6 像素缩到 640 分辨率下连 6 个像素都不到特征图上的响应极弱。解决推理时固定用--img 1280但训练时也要用匹配的分辨率。训练用 640、推理用 1280 会引入尺度偏移mAP 会有损失最好训练时就设成--img 1280。现象三推理结果里一个车牌出了两个框。原因--iou-thres阈值设置不当NMS 没有把重叠框合并干净。常见做法是排查是不是同一个目标的两个高置信度框如果是把--iou-thres从 0.45 降到 0.3 试试。另外还有一种可能是数据集标注里同一样本出现了重复框模型学会了同时输出两个框这种只能在数据层面清理。现象四训练没几个 epoch 就报NaN loss。原因学习率过大导致梯度爆炸或者数据里有异常的标签值比如归一化坐标出现 1e5 这样的野值。先检查标签文件再降学习率。YOLOv5 默认带 warmup 机制前三轮学习率是线性上升的如果lr0设置过高warmup 结束后直接爆炸。遇到 NaN 先看hyp文件里lr0从 0.01 降到 0.001 能解决大部分情况。现象五RK3568 等边缘设备上部署后帧率只有个位数。原因直接拿 PyTorch 的 .pt 权重在端侧跑设备不支持 CUDA算子也做了很多动态分支推理效率极低。解决先导出 ONNX再量化为 int8。YOLOv5 官方仓库里export.py支持--include onnx导出后再用 RKNN Toolkit 做转换。量化后 mAP 会有 1% 到 3% 的下降但推理速度能提升一个数量级。另外需要注意的是量化前用验证集做 int8 校准校准数据集最好是你真实场景的图拿 COCO 图校准车牌模型会掉点严重。6. 进阶批量识别与错误样本复盘6.1 写一个批量识别脚本单张图测试通过后真实使用场景一定是批量处理。YOLOv5 的detect.py本身支持--source传目录但如果你想在批量处理时做一些额外操作比如把车牌区域裁剪出来存档那就需要自己写脚本调用模型接口import cv2 import torch import os model torch.hub.load(ultralytics/yolov5, custom, pathbest.pt, force_reloadTrue) model.conf 0.5 model.iou 0.45 model.img_size 1280 input_dir test_images output_dir output_crops os.makedirs(output_dir, exist_okTrue) for img_name in os.listdir(input_dir): img cv2.imread(os.path.join(input_dir, img_name)) results model(img) boxes results.xyxy[0].cpu().numpy() for i, (x1, y1, x2, y2, conf, cls) in enumerate(boxes): crop img[int(y1):int(y2), int(x1):int(x2)] cv2.imwrite(os.path.join(output_dir, f{img_name}_plate_{i}.jpg), crop)torch.hub.load加载本地权重时path参数直接指向你的best.ptmodel.conf和model.iou对应于命令行里的--conf-thres和--iou-thres。results.xyxy[0]返回的是检测框的左上角右下角坐标、置信度和类别索引用切片把它转成 NumPy 数组是为了方便直接索引坐标值。6.2 用错误样本反推阈值调整批量识别完不要急着收工把漏检和误检的图单独拉出来看一遍。我的习惯是建一个bad_cases/目录每次跑完批量识别把所有conf低于 0.2 或者明显框错的图丢进去。看一段时间就能发现规律如果漏检集中在远距离小目标优先调--img如果误检集中在车灯、保险杠等圆形区域优先把conf阈值往上提如果蓝牌绿牌识别率失衡回到数据集层面做平衡。从那以后我每次训练完都会强制走一遍这套流程先单图验证、再批量跑测试集、最后人工复盘错误样本。阈值参数不能靠猜每一版模型的置信度分布都不一样换一次数据集就要重新看一遍分布曲线再定阈值。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/11 9:12:52

S7-200 PLC与组态王的锅炉水位控制组态设计与调试

从标题就能看出,这是一个典型的“老牌自动化组合”项目:西门子S7-200 PLC加组态王,控制对象是40#预热锅炉的水位。我在现场调试过的类似系统不下十套,虽然现在S7-1200/1500和博途已经是主流,但国内仍有大量在役设备用的…

2026/10/11 9:07:52

单调栈解接雨水:从边界思维到完整代码实现

1. 这个"trap"到底在装什么水1.1 题目速览:接雨水到底在算什么接雨水(Trapping Rain Water)是 LeetCode 第 42 题,也是单调栈这个数据结构最经典的出场场景之一。题目本身很短:给你一个非负整数数组height&a…

2026/10/11 9:07:52

Python 安装

Python 安装 1. Linux 系统 1.1 使用系统自带 Python(推荐) 大多数 Linux 发行版预装了 Python 3,只需让 python 命令指向 python3: sudo apt update sudo apt install python-is-python3 -y验证安装: python --v…

2026/10/11 11:13:01

海康MVS V4.4.0工业相机调试实战指南:从黑屏到稳定取流

简介:本资源是海康机器人官方发布的工业相机客户端MVS V4.4.0用户手册(2024年8月版),面向自动化产线工程师、机器视觉开发人员及工业图像采集系统集成技术人员,解决工业相机选型配置、环境部署、参数调试与故障排查等核…

2026/10/11 11:13:01

Show HN项目评估指南:从快速部署到API调用与性能排查

“Show HN”不是一个具体的模型,也不是某个能双击启动的开源工具。它是 Hacker News 上一种特殊的项目发布方式:作者把自己刚做完、还在早期阶段的独立作品用 Show HN 作为标题前缀发布出来,通常后面跟一句话说清楚“这个东西是什么、我为什…

2026/10/11 11:13:01

2026年哔哩哔哩职级与薪资体系,附AI测试开发面试题

哔哩哔哩(Bilibili,简称B站)的业务覆盖视频、直播、游戏、广告、会员等领域。对于考虑进入B站的技术人员,最先想了解的往往是三件事:职级怎么分、年薪大概多少、面试需要准备什么。 先看B站职级、年薪和绩效机制&#…

2026/10/11 11:08:01

ESP32冰箱状态监测系统:温度、门磁与告警推送实战

1. 从一个被忽略的生活痛点说起:冰箱到底出了什么问题冰箱大概是家里最"沉默"的家电。它不像空调有遥控器可以随时调温,不像洗衣机有面板显示剩余时间,更不像路由器有指示灯告诉你它是不是在干活。你唯一能感知到它存在的方式&…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/11 0:02:13

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑