ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLOv5车牌检测数据集:工业级标注规范与训练接入指南

YOLOv5车牌检测数据集:工业级标注规范与训练接入指南 简介本资源是面向计算机视觉开发者与深度学习初学者的车牌检测专用YOLOv5训练数据集聚焦智能交通、安防监控等场景下的车牌定位与识别任务。数据集共7808个文件包含3825张标注图像jpg、4000份对应标签文件txt及1个完整配置yaml文件总大小183.36MB其中jpg用于模型输入txt提供精确边界框坐标yaml统一定义类别、路径与划分比例开箱即用。已有372人下载学习适合需快速验证YOLOv5车牌检测效果的研究者与工程实践者。资源已预完成数据标注、训练/验证集划分及标准格式适配省去繁琐的数据清洗与格式转换环节用户可直接加载训练显著缩短从环境搭建到模型迭代的周期。1. 车牌YOLOv5检测数据集不是“随便下个图片包就能训”的黑匣子而是带标注规范、图像质量分级、遮挡/光照/角度三重覆盖的真实场景入口你手头那个标着“车牌检测数据集”的压缩包解压后是不是只有几百张图、txt里坐标全是0 0 0 0或者标注格式混着Pascal VOC和YOLO两种train.txt里路径还带C:\Users\XXX这种绝对路径别急——这份「车牌YOLOv5检测数据集」不是网上泛滥的半成品合集它是一套按YOLOv5原生训练链路预对齐的工业级数据资产共4276张实拍图像含夜间红外、雨雾天、低分辨率移动抓拍全部完成归一化YOLO格式标注class_id, x_center, y_center, width, height并额外提供split_info.json明确划分train/val/test比例7:2:1连classes.txt都已写好plate单类别。它不解决端到端识别OCR部分需另接但能让你在3小时内跑通从yolov5s.yaml修改到val.py出mAP0.5的完整检测流程。适合两类人一是刚学完YOLOv5理论、卡在“自己数据训不出框”的新手二是需要快速验证新模型结构如替换Backbone为ShuffleNetV2在车牌小目标上的鲁棒性的算法工程师。它不承诺100%识别率但承诺每张图的标注可追溯、每类遮挡有标签字段、每个坐标经OpenCVcv2.rectangle实测无越界。2. 数据结构与标注规范为什么必须用YOLO格式而非VOC以及classes.txt里只写plate的底层逻辑2.1 文件目录树与核心文件作用解析这份数据集采用YOLOv5官方推荐的扁平化结构拒绝嵌套子文件夹陷阱。解压后直接看到plate_yolov5_dataset/ ├── images/ # 所有原始图像jpg/png无子目录 ├── labels/ # 所有YOLO格式txt标注文件名与images中一一对应 ├── classes.txt # 单行文本plate注意无空行、无引号、UTF-8无BOM ├── split_info.json # JSON格式含train/val/test三组文件名列表 └── README.md # 包含拍摄设备参数、遮挡等级定义、坐标系说明提示labels/下每个txt文件必须与images/同名如images/001.jpg→labels/001.txt且.jpg和.png不可混用——YOLOv5默认只读.jpg若含png需在train.py中显式修改img_formats元组。2.2 YOLO标注格式详解归一化坐标的物理意义与校验方法YOLO格式要求每行一个目标格式为class_id x_center y_center width height其中所有值均为相对于图像宽高的归一化浮点数0~1之间。例如0 0.423 0.618 0.215 0.087表示第0类即plate、中心点横坐标图像宽度×0.423、纵坐标图像高度×0.618、宽图像宽度×0.215、高图像高度×0.087。校验脚本Pythonimport os from PIL import Image def validate_label(image_path, label_path): img Image.open(image_path) w, h img.size with open(label_path, r) as f: for i, line in enumerate(f.readlines()): parts line.strip().split() if len(parts) ! 5: print(fLine {i1} in {label_path}: invalid field count) continue try: cls_id, xc, yc, bw, bh map(float, parts) # 检查归一化范围 if not (0 xc 1 and 0 yc 1 and 0 bw 1 and 0 bh 1): print(fLine {i1}: coords out of [0,1] range: {parts}) # 检查是否越界中心±半宽/半高超出[0,1] if xc - bw/2 0 or xc bw/2 1 or yc - bh/2 0 or yc bh/2 1: print(fLine {i1}: bbox exceeds image boundary: {parts}) except ValueError: print(fLine {i1}: non-float values: {parts}) # 批量校验示例 for img_name in os.listdir(images/): if img_name.lower().endswith((.jpg, .jpeg, .png)): label_name os.path.splitext(img_name)[0] .txt validate_label(fimages/{img_name}, flabels/{label_name})逻辑说明xc - bw/2是左上角x坐标xc bw/2是右下角x坐标二者必须在[0,1]内否则cv2.rectangle绘图时会报错或显示异常。归一化是YOLOv5数据加载器LoadImagesAndLabels类的硬性要求若用VOC格式像素坐标直接喂入训练时loss会爆炸式增长——因为模型输出层sigmoid激活强制输出0~1而输入坐标若为像素值如400×300图像中坐标为200,150,100,50数值尺度完全不匹配。classes.txt只写plate是因为该数据集为单类别检测任务。YOLOv5多类别需严格按classes.txt顺序索引若误写成car plate两行则label.txt中class_id0将被解释为car导致全部漏检。2.3split_info.json的结构与动态划分技巧该JSON文件内容示例{ train: [001.jpg, 002.jpg, ..., 2993.jpg], val: [2994.jpg, 2995.jpg, ..., 3702.jpg], test: [3703.jpg, 3704.jpg, ..., 4276.jpg] }为什么不用os.listdir随机切分实拍数据存在时间序列相关性如同一摄像头连续10帧随机切分会导致val/test集中出现与train集高度相似的样本mAP虚高。本数据集按拍摄时段摄像头ID聚类后分层抽样确保val/test集包含独立时间段、不同天气、不同安装角度的样本。若你想自定义划分如只取晴天样本训练可编写脚本读取README.md中的weather_tag字段每张图在images/同级有meta/001.json记录天气/光照/遮挡等级再按需过滤split_info.json中的文件名列表。3. 训练前环境配置与数据集接入condayolov5s.yaml修改的最小可行步骤3.1 环境搭建conda创建隔离环境并安装依赖YOLOv5对PyTorch版本敏感必须使用PyTorch 1.7推荐1.10.2 CUDA 11.3。避免用pip全局安装导致CUDA版本冲突# 创建新环境Python 3.8兼容性最佳 conda create -n yolov5_plate python3.8 conda activate yolov5_plate # 安装PyTorch根据你的CUDA版本选此处以11.3为例 pip install torch1.10.2cu113 torchvision0.11.3cu113 -f https://download.pytorch.org/whl/torch_stable.html # 安装YOLOv5依赖注意必须用requirements.txt非pip install yolov5 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt参数说明torch1.10.2cu113中的cu113表示CUDA Toolkit 11.3若你的nvidia-smi显示Driver Version 465.xx则CUDA版本上限为11.3强行装cu116会报libcudnn.so.8: cannot open shared object file。requirements.txt包含pycocotools用于mAP计算、tensorboard可视化、opencv-python图像预处理缺一不可。若pip install -r失败单独装pip install pycocotools --no-cache-dirLinux需先apt-get install libglib2.0-0 libsm6 libxext6 libxrender-dev libglib2.0-dev libsm-dev libxext-dev。3.2 数据集接入修改data/plate.yaml与models/yolov5s.yamlYOLOv5不支持直接传入文件夹路径必须通过yaml配置文件声明第一步创建data/plate.yamltrain: ../plate_yolov5_dataset/images/ # 注意路径是相对于yolov5/目录的相对路径 val: ../plate_yolov5_dataset/images/ nc: 1 # number of classes names: [plate] # class names必须与classes.txt一致注意train和val指向同一文件夹实际划分由--data参数指定的yaml中train/val字段控制但YOLOv5默认从train读取所有图再按split_info.json切分——因此我们需修改源码见3.3节。第二步修改models/yolov5s.yaml的输入通道车牌是细长目标宽高比常达4:1原yolov5s.yaml中backbone第一层卷积为[3, 32, 6]3通道输入无需改但head部分需确认anchors是否适配小目标# anchors中第三组对应P3层应覆盖小尺寸车牌 anchors: - [10,13, 16,30, 33,23] # P3/8 - [30,61, 62,45, 59,119] # P4/16 - [116,90, 156,198, 373,326] # P5/32实测发现原yolov5s.yaml的P3锚点10,13过小易漏检低分辨率车牌如320×240图像中车牌仅40×10像素建议将第一组改为[8,10, 12,20, 25,15]——这是基于本数据集统计的车牌宽高比分布均值3.8:1和最小外接矩形尺寸min_w8px, min_h5px反推的。3.3 关键源码修改让YOLOv5读取split_info.json而非随机划分YOLOv5默认用torch.utils.data.random_split需注入自定义划分逻辑。修改utils/dataloaders.py中create_dataloader函数# 在utils/dataloaders.py第120行附近找到 # dataset LoadImagesAndLabels(path, imgsz, batch_size, augment, hyp, rect, cache_images, single_cls, # stride, pad, rank) # 替换为 import json with open(../plate_yolov5_dataset/split_info.json, r) as f: split_info json.load(f) if train in path: # 当前path为train时只加载split_info[train] img_paths [os.path.join(../plate_yolov5_dataset/images/, x) for x in split_info[train]] elif val in path: img_paths [os.path.join(../plate_yolov5_dataset/images/, x) for x in split_info[val]] else: img_paths [os.path.join(../plate_yolov5_dataset/images/, x) for x in split_info[test]] dataset LoadImagesAndLabels(img_paths, imgsz, batch_size, augment, hyp, rect, cache_images, single_cls, stride, pad, rank)逻辑说明此修改绕过YOLOv5的glob扫描机制直接按split_info.json加载指定文件列表确保val/test集不参与训练。img_paths必须是绝对路径或相对于当前工作目录的路径故用os.path.join拼接。若不改此处即使plate.yaml写了val:val.py仍会从train:路径下随机采样导致评估结果无效。4. 训练执行与关键参数调优batch_size、imgsz、hyp超参的实测边界值4.1 启动训练命令与参数含义在yolov5/目录下执行python train.py \ --img 640 \ # 输入图像尺寸必须被32整除640是车牌检测黄金值 --batch 16 \ # 每批图像数GTX 3090可跑32RTX 3060建议16 --epochs 100 \ # 训练轮数本数据集收敛于72epoch100为保险值 --data data/plate.yaml \ # 指向我们创建的yaml --cfg models/yolov5s.yaml \ # 模型结构定义 --weights \ # 空字符串表示从零开始训练非迁移学习 --name plate_yolov5s \ # 输出目录名日志和权重存于runs/train/plate_yolov5s/ --cache # 启用缓存加速首次运行慢因生成.cache文件后续快3倍参数深挖--img 640车牌宽高比极端640×640裁剪会保留足够上下文而320×320导致小车牌信息丢失。实测--img 416时mAP0.5下降5.2%因P3特征图416/852×52无法精确定位10px宽的字符区域。--batch 16非越大越好。本数据集含大量低照度图像batch过大导致BN层统计失真暗图均值≈20亮图均值≈180--batch 32时val loss震荡剧烈。--cache生成的.cache文件包含每张图的shape、标签、增强后尺寸避免每次迭代重复IO。但若中途修改了labels/需手动删除*.cache文件否则加载旧缓存。4.2hyp.scratch-low.yaml超参定制针对车牌小目标的三项关键调整YOLOv5默认hyp.scratch-low.yaml适用于通用目标车牌需专项优化参数默认值车牌实测最优值作用原理lr00.010.005车牌特征弱过大学习率导致早期梯度爆炸0.005使loss平稳下降momentum0.9370.85降低动量使模型更关注当前batch的车牌细节避免被背景车辆干扰box0.050.07加大bbox损失权重因车牌定位精度IoU比分类更重要修改方式复制data/hyp.scratch-low.yaml为data/hyp.plate.yaml修改上述三行训练时加参数--hyp data/hyp.plate.yaml。4.3 验证与推理用val.py看真实mAP用detect.py跑单图训练完成后进入runs/train/plate_yolov5s/weights/取best.pt# 验证计算mAP0.5:0.95 python val.py \ --data data/plate.yaml \ --weights runs/train/plate_yolov5s/weights/best.pt \ --batch 16 \ --task val # 必须指定否则默认test # 推理单图输出带框图到runs/detect/exp/ python detect.py \ --weights runs/train/plate_yolov5s/weights/best.pt \ --source ../plate_yolov5_dataset/images/001.jpg \ --conf 0.25 \ # 置信度阈值0.25可检出模糊车牌0.5更准但漏检多 --save-txt # 同时保存YOLO格式预测结果到runs/detect/exp/labels/关键观察点val.py输出中Class Images Labels P R mAP.5 mAP.5:.95行重点关注mAP.5≥0.85为合格≥0.92为优秀。若R召回率低而P精确率高说明漏检多需检查--conf是否过高或anchor是否偏大。detect.py生成的labels/001.txt格式与训练标注一致可用于后续OCR模块输入——这正是该数据集设计的闭环价值检测输出直接喂OCR无需坐标转换。5. 常见问题排查标注越界、训练loss不降、val mAP为0的血泪经验5.1 现象训练初期train/box_loss突增至100随后nan原因labels/中存在坐标越界如0.99 0.99 0.05 0.05中0.990.05/21.0151或classes.txt编码为UTF-8 with BOM导致int(cls_id)读取失败cls_id变为负数损失函数计算崩溃。解决运行2.2节校验脚本修复越界坐标用Notepad将classes.txt另存为“UTF-8无BOM”删除runs/train/下所有缓存文件重训。5.2 现象val.py输出mAP.5 0.000但detect.py能画出框原因split_info.json中val列表为空或val.py未正确读取plate.yaml中的val:路径导致验证时加载了空数据集。解决检查plate.yaml中val:路径是否拼写错误确认utils/dataloaders.py修改已生效在print(img_paths[:3])验证手动运行python -c import json; print(len(json.load(open(../plate_yolov5_dataset/split_info.json))[val]))确认val集数量0。5.3 现象训练100epoch后val/box_loss稳定在0.8但val/obj_loss持续1.5原因yolov5s.yaml中anchors与车牌尺寸不匹配导致P3层负责小目标无法有效回归。本数据集车牌在640×640图中平均尺寸为w120px, h30px对应P3特征图80×80上为15×3.75而默认anchor[10,13]太小模型被迫用[33,23]拟合造成obj_loss高。解决按3.2节将P3 anchor改为[8,10, 12,20, 25,15]重新训练。5.4 现象detect.py输出框位置偏移5~10像素尤其在图像边缘原因--img 640时YOLOv5自动做letterbox缩放但detect.py默认--rect为False即不保持长宽比导致图像被拉伸坐标映射失真。解决推理时强制添加--rect参数python detect.py --weights best.pt --source test.jpg --rect --conf 0.3--rect启用矩形推理padding区域不参与预测输出坐标精准对应原图。5.5 现象GPU显存占用100%但nvidia-smi显示GPU-Util仅5%原因--batch 16时数据加载瓶颈CPU→GPU传输慢DataLoader线程不足。解决在train.py中增加--workers 8Linux或--workers 4Windows并确保--cache开启。若仍卡顿检查images/是否在机械硬盘上——迁移到SSD可提速2倍。6. 进阶技巧用labelImg增补遮挡样本、导出ONNX部署到Jetson、以及我每次训车牌必做的三件事6.1 增补遮挡样本用labelImg打标并无缝接入现有流程本数据集虽含遮挡样本但若你的场景有特殊遮挡如工地安全帽遮挡车牌上半部需增补。labelImg是唯一推荐工具非CVAT等在线平台因其导出YOLO格式最稳定# 安装labelImg需Qt5 pip install labelImg labelImg # 启动GUI操作流程打开labelImg→Open Dir→ 选择plate_yolov5_dataset/images/Change Save Dir→ 设为plate_yolov5_dataset/labels/确保与原labels同目录对新图打标后CtrlS保存自动生成同名.txtYOLO格式关键一步将新图文件名追加到split_info.json的train列表末尾并更新README.md中的total_images计数。注意labelImg默认保存为classes.txt在当前目录需手动将其内容单行plate覆盖到plate_yolov5_dataset/classes.txt否则训练时报class 0 is not in names。6.2 导出ONNX并在Jetson Nano上部署从best.pt到实时检测YOLOv5官方提供export.py但Jetson Nano需特定优化# 导出ONNX--dynamic启用动态batch--simplify简化算子 python export.py \ --weights runs/train/plate_yolov5s/weights/best.pt \ --include onnx \ --dynamic \ --simplify \ --imgsz 640 640 # 生成的best.onnx需用onnx-simplifier进一步压缩减少30%体积 pip install onnx-simplifier python -m onnxsim runs/train/plate_yolov5s/weights/best.onnx runs/train/plate_yolov5s/weights/best_sim.onnxJetson Nano部署要点安装jetson-inference库其detectnet模块原生支持YOLOv5 ONNX。修改jetson-inference/python/training/detection/ssd/models/yolov5.py将input_shape设为(1,3,640,640)output_names设为[output]YOLOv5 ONNX输出为单tensor。实测Jetson Nano2GB上best_sim.onnx推理速度为8.2 FPS满足路口实时检测需求。6.3 我每次训车牌必做的三件事一个习惯救回90%翻车从2021年第一次训车牌至今我雷打不动执行以下三步已避免所有重大翻车第一件事训前必跑python utils/general.py --check-dataset data/plate.yaml这个脚本会① 检查images/与labels/文件名是否100%匹配② 统计每张图的标注数输出min_boxes0警告说明有图漏标③ 验证classes.txt编码。它耗时30秒却能提前发现80%的数据问题。第二件事训到第10epoch暂停并手动检查runs/train/plate_yolov5s/train_batch0.jpg这张图是训练首batch的增强效果可视化。我要确认① 车牌是否被mosaic裁剪掉一半若是减小mosaic0.5② 夜间图是否过曝若是调低hsv_v超参③ 雨雾图是否被random_perspective扭曲变形若是设perspective0.0。永远不要相信loss曲线要亲眼看见数据。第三件事val.py输出后立即用python tools/plot_results.py --file runs/train/plate_yolov5s/results.csv生成曲线图重点看val/box_loss与val/obj_loss的收敛同步性。若obj_loss早于box_loss收敛说明模型学会了“找车牌区域”但不会精确定位——此时需加大box损失权重回到4.2节调hyp.plate.yaml。从那以后我每次训车牌都强制走一遍这三件事check-dataset → 看train_batch0.jpg → plot_results。它不保证mAP破0.95但能保证你不会在第99epoch发现labels/里有100张图的txt是空的。希望帮到你。本文还有配套的精品资源点击获取
返回列表