简介:本资源为面向YOLO系列目标检测学习者的车牌检测数据集,适合需要快速开展车牌识别训练与验证的开发者、学生及算法工程师使用。数据集已按训练与测试需求划分完毕,并附带data.yaml配置文件,可直接接入yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等主流框架,省去自行整理与划分数据的繁琐步骤。压缩包共2000个文件,包含1019个xml标注、980个txt标注和1个yaml配置,整体约47.28MB;其中txt为YOLO格式标注,记录类别索引与归一化后的中心点、宽高比例,xml为VOC格式标注,两种格式分别存放于独立文件夹,便于按需选用。目前已有153人学习下载,可作为车牌检测任务的练手与验证素材,帮助读者快速跑通训练流程、对比不同YOLO版本的检测效果,并在此基础上进行模型调优与迁移实验。
1. 车牌检测数据集怎么选:1019 张带标签的 YOLO 实战包值不值得下
做车牌检测的项目,最耗时的环节往往不是调模型,而是搞数据。自己拍图、标注、划分训练验证集,一套流程走下来少说两三天,标完还得检查坐标有没有越界、类别有没有写错。这份 1019 张图像带标签的车牌检测数据集,解决的就是这个前置痛点——它已经把图像、YOLO 格式标签、VOC 格式标签、data.yaml 配置文件全部整理好,目录结构直接对齐 YOLOv5 到 YOLO11 的训练入口。适合两类人:一是想快速跑通车牌检测 baseline 的算法工程师,二是拿它做课程设计或验证自己训练脚本的从业者。数据集规模不算大,但胜在格式规范、双标签格式齐全,拿来验证训练链路是否通畅非常合适。
2. 数据集结构与标签格式:先看清目录再动手
2.1 目录组织与文件命名规律
拿到压缩包解压后,第一件事不是急着跑训练,而是把目录结构摸清楚。从项目正文给出的文件名来看,图像和标签采用同名配对的方式,比如img_0201_2.txt对应img_0201_2.jpg,img_0567_409.txt对应img_0567_409.jpg。这种命名方式的好处是配对关系一目了然,写脚本检查漏标、多标时直接按文件名比对即可。
常见的目录组织方式是这样:
plate_dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ ├── annotations/ # VOC 格式 xml │ ├── train/ │ └── val/ └── data.yamlimages下放图像,labels下放 YOLO 格式 txt,annotations下放 VOC 格式 xml。两个标签文件夹是同一批图的不同标注格式,不是两份独立数据。这一点新手容易搞混,以为有两千多张图,实际就是 1019 张图配两套标签。
2.2 YOLO 格式标签的坐标含义
YOLO 格式每行代表一个目标框,格式为:
<class> <x_center> <y_center> <width> <height>五个字段全部是归一化后的值。<class>是类别索引,从 0 开始;<x_center>和<y_center>是框中心点相对图像宽高的比例,范围 0 到 1;<width>和<height>是框宽高相对图像宽高的比例,同样在 0 到 1 之间。车牌检测通常只有一个类别,所以<class>基本都是 0。
这里有个血泪经验:归一化坐标一旦算错,训练时 loss 会异常震荡,但模型不一定报错,只是 mAP 死活上不去。验证方法很简单,写个脚本把坐标反算回像素值,看框有没有超出图像边界。
import os from PIL import Image def check_yolo_labels(img_dir, label_dir): """检查 YOLO 标签坐标是否越界""" issues = [] for txt_file in os.listdir(label_dir): if not txt_file.endswith('.txt'): continue img_name = txt_file.replace('.txt', '.jpg') img_path = os.path.join(img_dir, img_name) if not os.path.exists(img_path): issues.append(f"缺图: {img_name}") continue w, h = Image.open(img_path).size with open(os.path.join(label_dir, txt_file)) as f: for line_no, line in enumerate(f, 1): parts = line.strip().split() if len(parts) != 5: issues.append(f"{txt_file}:{line_no} 字段数不对") continue cls, xc, yc, bw, bh = map(float, parts) # 反算像素坐标 x1 = (xc - bw / 2) * w y1 = (yc - bh / 2) * h x2 = (xc + bw / 2) * w y2 = (yc + bh / 2) * h if x1 < 0 or y1 < 0 or x2 > w or y2 > h: issues.append(f"{txt_file}:{line_no} 框越界") return issues issues = check_yolo_labels('plate_dataset/images/train', 'plate_dataset/labels/train') print(f"发现 {len(issues)} 个问题") for i in issues[:10]: print(i)这段脚本做三件事:按文件名配对图像和标签、反算归一化坐标到像素坐标、检查框是否越界。参数上img_dir和label_dir分别指向图像和标签目录,运行后如果输出问题数为 0,说明标签质量过关,可以进入训练环节。如果有越界框,需要回到标注工具里修正,或者用脚本裁剪到边界内。
2.3 VOC 格式与 YOLO 格式的转换关系
VOC 格式用 xml 存储,每个目标一个<object>节点,包含<name>类别名和<bndbox>下的xmin、ymin、xmax、ymax四个像素坐标。和 YOLO 格式的换算关系是:
x_center = (xmin + xmax) / 2 / img_width y_center = (ymin + ymax) / 2 / img_height width = (xmax - xmin) / img_width height = (ymax - ymin) / img_height数据集同时提供两种格式,好处是既能直接喂给 YOLO 系列,也能用于需要 VOC 格式的评估脚本或转换到 COCO 格式。常见做法是训练用 YOLO 格式,验证时用 VOC 格式的 xml 做可视化对比,两边交叉检查标注一致性。
3. data.yaml 配置与训练入口:把数据集接进 YOLOv8/v11
3.1 data.yaml 的关键字段
data.yaml是 YOLO 系列训练时读取数据集信息的配置文件,核心字段有四个:
path: ./plate_dataset train: images/train val: images/val nc: 1 names: ['plate']path是数据集根目录,train和val是相对path的训练集和验证集图像路径,nc是类别数,names是类别名列表。车牌检测只有一类,所以nc: 1,names里写plate或license_plate都行,但要和标签里的类别索引对应——索引 0 对应names列表第一个元素。
注意:
path建议用绝对路径或相对于训练脚本的路径,用相对路径时容易因为工作目录不同而找不到数据。我一般会先os.path.abspath打印一下确认。
3.2 YOLOv8 训练命令与参数说明
YOLOv8 的训练入口是yolo detect train,最小可用命令:
yolo detect train \ data=plate_dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ project=runs/plate \ name=exp1逐项说明:data指向 data.yaml;model用预训练权重,yolov8n.pt是最小的 nano 版本,适合快速验证;epochs训练轮数,1019 张图的数据集 100 轮通常够收敛;imgsz输入尺寸,640 是默认值,车牌目标较小可以试 960;batch批大小,显存不够就降到 8 或 4;project和name控制输出目录。
训练过程中重点看三个指标:box_loss是否稳定下降、mAP50是否上升、precision和recall是否平衡。如果box_loss震荡剧烈,先检查标签坐标;如果mAP50卡在低位,可能是学习率太大或数据量不足。
3.3 YOLOv5 与 YOLO11 的差异
YOLOv5 用train.py脚本,参数写法类似但入口不同:
python train.py \ --data plate_dataset/data.yaml \ --weights yolov5n.pt \ --epochs 100 \ --img 640 \ --batch-size 16YOLO11 则沿用 YOLOv8 的 CLI 风格,把model换成yolo11n.pt即可。三个版本对 data.yaml 的字段要求基本一致,所以同一份配置可以跨版本复用。差异主要在预训练权重和部分超参默认值上,迁移时注意版本对应的权重文件名。
3.4 训练前用脚本做一次数据自检
在正式训练前,跑一个自检脚本能省下大量排查时间:
import yaml from pathlib import Path def validate_dataset(yaml_path): with open(yaml_path) as f: cfg = yaml.safe_load(f) root = Path(cfg['path']) for split in ['train', 'val']: img_dir = root / cfg[split] label_dir = root / 'labels' / split imgs = {p.stem for p in img_dir.glob('*.jpg')} labels = {p.stem for p in label_dir.glob('*.txt')} print(f"{split}: 图像 {len(imgs)} 张, 标签 {len(labels)} 个") print(f" 缺标签: {len(imgs - labels)}") print(f" 多标签: {len(labels - imgs)}") print(f"类别数: {cfg['nc']}, 类别名: {cfg['names']}") validate_dataset('plate_dataset/data.yaml')这个脚本检查训练集和验证集的图像与标签是否一一对应,输出缺标签和多标签的数量。正常情况下两个数字都应该是 0。如果缺标签数量不为 0,说明有图没标;多标签则说明有标签文件找不到对应图像,可能是文件名后缀不一致(比如.jpeg和.jpg)。
4. 从零跑通训练与验证:完整流程与参数调优
4.1 环境准备与依赖安装
训练前先把环境搭好。YOLOv8 和 YOLO11 用 ultralytics 包:
pip install ultralyticsYOLOv5 需要克隆仓库装依赖:
git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt显卡驱动和 CUDA 版本要匹配,torch.cuda.is_available()返回 True 才算 GPU 可用。如果只有 CPU,把batch降到 4 以下,imgsz降到 416,否则训练会慢到怀疑人生。
4.2 训练过程监控与日志解读
训练启动后,控制台会逐轮输出指标。重点关注:
| 指标 | 含义 | 正常表现 |
|---|---|---|
| box_loss | 边界框回归损失 | 逐轮下降,后期趋于平稳 |
| cls_loss | 分类损失 | 逐轮下降 |
| mAP50 | IoU=0.5 时的平均精度 | 逐轮上升,最终 0.9 以上 |
| mAP50-95 | 多 IoU 阈值平均精度 | 逐轮上升,最终 0.6 以上 |
| precision | 查准率 | 与 recall 平衡 |
| recall | 查全率 | 与 precision 平衡 |
如果mAP50在 0.5 附近就上不去了,常见原因是学习率太大、数据量太少或标签有噪声。可以先把lr0从默认的 0.01 降到 0.001 试一轮,或者用cos_lr开启余弦退火。
4.3 验证与推理:用训练好的权重跑测试
训练完成后,权重保存在runs/plate/exp1/weights/best.pt。用验证集评估:
yolo detect val \ model=runs/plate/exp1/weights/best.pt \ data=plate_dataset/data.yaml \ imgsz=640单张图推理:
yolo detect predict \ model=runs/plate/exp1/weights/best.pt \ source=test_image.jpg \ conf=0.25 \ save=Trueconf是置信度阈值,默认 0.25。车牌检测场景下如果漏检多,可以降到 0.1;如果误检多,提到 0.5。推理结果默认保存在runs/detect/predict下,图像上会画出检测框和类别置信度。
4.4 小数据集训练的增强策略
1019 张图在目标检测里属于小数据集,容易过拟合。常见做法是开启数据增强:
yolo detect train \ data=plate_dataset/data.yaml \ model=yolov8n.pt \ epochs=200 \ imgsz=640 \ batch=16 \ hsv_h=0.015 \ hsv_s=0.7 \ hsv_v=0.4 \ degrees=10 \ translate=0.1 \ scale=0.5 \ fliplr=0.5 \ mosaic=1.0hsv_h/s/v控制色调、饱和度、亮度扰动,车牌颜色相对固定,这三个值别开太大;degrees旋转角度,车牌有倾斜场景可以开到 15;translate平移比例;scale缩放比例;fliplr水平翻转概率,车牌文字翻转后不自然,建议设 0 或 0.5 谨慎用;mosaic马赛克增强,小数据集上效果明显,保持 1.0。
5. 避坑与排查:车牌检测训练中最容易翻车的五个点
5.1 现象:训练 loss 正常下降但 mAP 始终为 0
原因:标签类别索引和 data.yaml 的names不匹配。比如标签里写的是0,但names列表为空或类别数nc写成了 0。
解决:打开一个标签文件确认第一列的值,再检查 data.yaml 的nc和names。nc必须等于names列表长度,标签里的类别索引必须在0到nc-1之间。
5.2 现象:训练报错 "No labels found in ..."
原因:YOLO 默认按images/train找图、按labels/train找标签,如果目录名不是这个对应关系,或者标签文件后缀不是.txt,就会报这个错。
解决:确认目录结构是images/train配labels/train,标签文件是.txt后缀。如果目录名不同,在 data.yaml 里显式指定train和val的路径,但标签目录 YOLO 会自动把images替换成labels,所以图像和标签的父目录名必须对应。
5.3 现象:训练到一半显存溢出
原因:batch太大或imgsz太高。1019 张图里如果有些图分辨率很高,统一 resize 到 640 后显存占用会上升。
解决:先把batch减半,还不行就降imgsz到 416。也可以用--cache ram或--cache disk控制数据缓存方式,ram 快但吃内存,disk 慢但省内存。
5.4 现象:验证集 mAP 比训练集低很多
原因:过拟合。小数据集上模型记住了训练样本,泛化能力差。
解决:增加数据增强、加 dropout、减小模型规模(从yolov8m换回yolov8n)、早停(patience=20)。另外检查训练集和验证集是否同分布,如果验证集里都是某种角度的车牌而训练集没有,也会导致指标差距大。
5.5 现象:推理时框位置偏移或框太大
原因:标签坐标归一化时用错了图像尺寸。比如标注时用的是原图尺寸,但训练时图像被 resize 了,如果标签没同步更新就会偏移。
解决:YOLO 格式的归一化坐标是相对于原图宽高的,训练时的 resize 由框架自动处理,不需要手动改标签。如果确认标签没问题但框还是偏,检查推理时的imgsz是否和训练时一致,不一致会导致框位置换算误差。
6. 进阶技巧:用这份数据集做跨版本对比与标签质量复核
数据集跑通之后,别急着换更大的模型。我一般会拿同一份 data.yaml 在 YOLOv8n、YOLO11n、YOLOv5n 上各跑一轮 100 epoch,固定随机种子,对比 mAP50 和推理速度。这样能直观看出不同版本在这个数据分布上的表现差异,比看论文里的通用指标靠谱得多。对比时注意把imgsz、batch、epochs保持一致,否则变量不唯一,结论没有参考价值。
# 三个版本各跑一轮,输出到不同目录 yolo detect train data=plate_dataset/data.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 project=runs/compare name=v8n yolo detect train data=plate_dataset/data.yaml model=yolo11n.pt epochs=100 imgsz=640 batch=16 project=runs/compare name=v11n python yolov5/train.py --data plate_dataset/data.yaml --weights yolov5n.pt --epochs 100 --img 640 --batch-size 16 --project runs/compare --name=v5n跑完后看runs/compare下三个目录的results.csv,重点对比最终metrics/mAP50-95和每轮平均训练时间。如果某个版本明显掉点,先排查权重加载是否正常,再检查该版本对 data.yaml 字段的解析是否有差异。
另一个值得做的动作是标签质量复核。用训练好的模型在训练集上推理一遍,把预测框和标注框做 IoU 对比,IoU 低于 0.5 的样本挑出来人工看。这些样本要么是标注框画偏了,要么是模型没学好。如果是标注问题,修正后重新训练往往能涨几个点。这个流程我每次拿到新数据集都会走一遍,比盲目调参有效得多。
从那以后我每次拿到带标签的数据集,都强制先跑一遍坐标越界检查和标签配对检查,再跑一轮小模型快速验证,确认数据没问题才上大模型。希望帮到你。
本文还有配套的精品资源,点击获取