ARTICLE DETAIL

资讯详情

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

驾驶员安全带检测数据集:YOLO格式开箱即用与训练避坑指南

驾驶员安全带检测数据集:YOLO格式开箱即用与训练避坑指南 简介本资源为驾驶员佩戴安全带检测的YOLO格式数据集面向从事目标检测学习与车辆安全场景开发的学生、算法工程师及竞赛参与者可直接用于YOLOv5等框架的训练与验证。数据按YOLOv5标准目录组织标注采用classes、x_centre、y_centre、w、h的相对坐标格式仅含seatbelt一个类别其中训练集1201张图片及对应1201个标签文件验证集354张图片及354个标签文件划分清晰、开箱即用。压缩包共2000个文件以1556个txt标签、443张jpg图像和1个py脚本为主整体约63.76MB体积轻便便于传输与本地部署。资源附带可视化脚本随机传入一张图片即可绘制边界框并保存到当前目录无需修改即可运行方便快速核验标注质量。目前已有139人学习适合需要现成安全带检测数据、快速验证模型效果或搭建车辆安全监测原型的读者参考使用。1. 驾驶员安全带检测数据集1201 张训练图 354 张验证图开箱即用的 YOLO 落地包拿到一份标注好的数据集最怕的不是模型训不动而是格式对不上、类别文件缺失、可视化脚本跑不起来。这套驾驶员佩戴安全带检测数据集直接按 YOLO 目录结构组织训练集 1201 张图配 1201 个 txt 标签验证集 354 张图配 354 个 txt 标签类别只有一类 seatbelt标注采用 YOLO 相对坐标格式class、x_centre、y_centre、w、h。它解决的是从零标注到能开训之间那段最耗时的脏活适合做车载安全监测、DMS 驾驶员状态分析、以及想快速验证 YOLOv5/v8 训练流程的从业者。可视化脚本随机抽一张图就能画框存盘不用改代码先看数据质量再决定要不要投入训练。2. 目录结构与标注格式先对齐 YOLO 的读取逻辑2.1 为什么这套目录能直接喂给 YOLOv5YOLOv5 的数据加载器对目录结构有硬性约定图片和标签分开放标签路径由图片路径推导而来。这套数据集按datasets/images/train、datasets/images/val、datasets/labels/train、datasets/labels/val组织正好命中 YOLOv5 默认的路径推导规则。图片文件名里带.rf.后缀是 Roboflow 导出时的哈希标记不影响读取但要注意图片和标签的主干名必须严格一致——SEatbelt-212-_jpg.rf.2afa941d...jpg对应的标签必须是SEatbelt-212-_jpg.rf.2afa941d...txt差一个字符就会在训练时被当成无标签样本跳过。常见做法是先用一条命令核对图片和标签的配对情况避免训练到一半才发现有孤儿文件。下面这段脚本遍历 train 和 val 两个目录输出缺失标签的图片和缺失图片的标签import os for split in [train, val]: img_dir fdatasets/images/{split} lbl_dir fdatasets/labels/{split} imgs {os.path.splitext(f)[0] for f in os.listdir(img_dir)} lbls {os.path.splitext(f)[0] for f in os.listdir(lbl_dir)} # 图片有但标签没有 missing_lbl imgs - lbls # 标签有但图片没有 missing_img lbls - imgs print(f[{split}] 图片 {len(imgs)} 张, 标签 {len(lbls)} 个) print(f 缺标签: {len(missing_lbl)}, 缺图片: {len(missing_img)}) if missing_lbl: print( 示例:, list(missing_lbl)[:3])逻辑说明用集合差集找出不配对的文件。参数上split对应 train 和 val 两个子集路径按数据集实际存放位置调整。如果输出缺标签数量不为零优先检查是不是文件名里的.rf.哈希段被改动过或者标签文件被误删。这一步花两分钟能省掉后面排查 loss 不下降的几个小时。2.2 相对坐标标注的数值边界YOLO 格式的标注是归一化后的相对坐标每行五个值类别索引、中心点 x、中心点 y、宽、高全部在 0 到 1 之间。这套数据集的类别只有 seatbelt 一类所以类别索引恒为 0。实际检查时重点看有没有超出 [0,1] 的值以及宽高是否出现 0 或负数——这两种情况在训练时不会报错但会让边界框回归变成玄学loss 震荡却找不到原因。import os lbl_dir datasets/labels/train bad [] for f in os.listdir(lbl_dir): with open(os.path.join(lbl_dir, f)) as fp: for i, line in enumerate(fp): parts line.strip().split() if len(parts) ! 5: bad.append((f, i, 字段数不对)) continue cls, x, y, w, h map(float, parts) # 检查坐标范围和宽高有效性 if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): bad.append((f, i, f越界: {x},{y},{w},{h})) print(f异常标注行数: {len(bad)}) for b in bad[:5]: print(b)逻辑说明逐行解析标签校验字段数和数值范围。参数上0 w 1排除了宽高为零的退化框。如果异常行数较多说明标注导出环节有问题需要回到标注工具重新导出如果只有零星几行可以手动修正或直接删除对应图片。这套数据集标注质量整体可控但批量数据难免有个别漏网之鱼跑一遍心里有底。3. 可视化脚本与数据质量核查先看再训3.1 随机抽图绘制边界框的脚本拆解数据集自带可视化 py 文件随机传入一张图片即可绘制边界框并保存在当前目录。这个脚本的价值在于训练前用肉眼确认标注框是否贴合目标尤其是安全带这种细长目标标注偏移几个像素在数值上不明显但画出来一眼就能看出问题。脚本无需更改即可运行核心逻辑是读图、读对应标签、把相对坐标还原成像素坐标、画框、存图。import cv2 import os import random img_dir datasets/images/train lbl_dir datasets/labels/train # 随机抽一张图 img_name random.choice(os.listdir(img_dir)) img_path os.path.join(img_dir, img_name) lbl_path os.path.join(lbl_dir, os.path.splitext(img_name)[0] .txt) img cv2.imread(img_path) h, w img.shape[:2] with open(lbl_path) as f: for line in f: cls, x, y, bw, bh map(float, line.split()) # 相对坐标转像素坐标 cx, cy int(x * w), int(y * h) pw, ph int(bw * w), int(bh * h) x1, y1 cx - pw // 2, cy - ph // 2 x2, y2 cx pw // 2, cy ph // 2 cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, seatbelt, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite(vis_result.jpg, img) print(f已保存 vis_result.jpg, 来源: {img_name})逻辑说明random.choice随机选图保证每次运行看到的样本不同。参数上x * w和y * h是相对坐标转像素坐标的关键pw // 2和ph // 2从中心点反推左上角和右下角。画框颜色用绿色线宽 2类别文字标在框上方。如果运行后图片里没有框先确认标签文件是否存在、路径是否拼对如果框的位置明显偏移说明标注时的图像尺寸和当前读取的尺寸不一致需要核对原图是否被缩放或裁剪过。3.2 用统计分布判断数据集是否值得训可视化看单张图是定性检查批量统计标注框的宽高分布和位置分布是定量检查。安全带检测有个特点目标通常出现在画面中下部宽高比偏扁长。如果统计出来大量框集中在画面顶部或宽高比接近正方形大概率是标注串行或类别混淆。下面这段脚本统计训练集所有框的中心点 y 坐标和宽高比import os import numpy as np lbl_dir datasets/labels/train ys, ratios [], [] for f in os.listdir(lbl_dir): with open(os.path.join(lbl_dir, f)) as fp: for line in fp: _, x, y, w, h map(float, line.split()) ys.append(y) ratios.append(w / h if h 0 else 0) ys np.array(ys) ratios np.array(ratios) print(f中心点 y 均值: {ys.mean():.3f}, 中位数: {np.median(ys):.3f}) print(f宽高比均值: {ratios.mean():.2f}, 中位数: {np.median(ratios):.2f}) print(fy 0.3 的框占比: {(ys 0.3).mean():.2%})逻辑说明ys收集所有框的中心点纵坐标ratios收集宽高比。参数上y 0.3统计画面顶部区域的框占比安全带检测这个比例应该很低。如果均值和中位数偏离预期比如 y 均值接近 0.5 且宽高比接近 1就要怀疑标注是否把整张图或错误区域框了进去。这一步不直接改数据但决定了要不要在训练前做一轮清洗。4. 训练配置与类别文件从 data.yaml 到训练启动4.1 class 文件与 data.yaml 的对应关系数据集里的类别文本文件只有一行seatbelt对应类别索引 0。YOLOv5 训练时需要一份 data.yaml 告诉它去哪里找数据、有几个类别、类别名是什么。这份 yaml 不用自己从零写按数据集实际路径填就行# data.yaml train: datasets/images/train val: datasets/images/val nc: 1 names: [seatbelt]逻辑说明train和val指向图片目录YOLOv5 会自动推导同级的 labels 目录。nc是类别数这里为 1。names是类别名列表顺序必须和标签里的类别索引一致——如果标签里 seatbelt 是 0names 里 seatbelt 就必须在第一个。常见翻车点是 names 写成了中文或带了空格导致训练时类别名解析失败。改完 yaml 后用 YOLOv5 自带的检查命令跑一遍确认数据路径和类别数被正确识别。4.2 训练参数怎么设才不浪费这 1201 张图1201 张训练图在 YOLO 任务里属于小到中等规模直接上大模型容易过拟合用 nano 或 small 版本更稳。常见做法是从预训练权重起步冻结 backbone 先跑几轮再解冻全量微调。下面是一条可复现的训练命令python train.py \ --data data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --freeze 10 \ --cache逻辑说明--weights yolov5s.pt加载预训练权重小数据集上比从零训收敛快得多。--img 640是输入尺寸安全带目标不算特别小640 够用如果显存吃紧可以降到 416。--batch 16在单卡 8G 显存上比较稳显存更大可以往上加。--freeze 10冻结前 10 层先让检测头适应新类别避免一开始就把预训练特征带偏。--cache把图片缓存到内存1201 张图占用不大能明显加快每个 epoch 的读取速度。训练启动后重点看三个指标box_loss 是否稳定下降、mAP0.5 是否在 30 轮后开始爬升、验证集 loss 是否和训练集同步下降。如果训练集 loss 降但验证集 loss 涨就是过拟合信号需要减 epoch 或加数据增强。4.3 置信度门限与推理验证训练完拿验证集图片跑推理默认置信度门限 0.25 有时会漏掉遮挡严重的安全带。安全带被方向盘或手臂挡住时模型输出的置信度会偏低这时候把门限降到 0.1 到 0.15 之间能召回更多目标但误检也会增加。实际操作是先用默认门限跑一批图看漏检和误检的比例再决定往哪个方向调。推理命令里--conf控制门限--iou控制 NMS 的 IoU 阈值python detect.py \ --weights runs/train/exp/weights/best.pt \ --source datasets/images/val \ --conf 0.15 \ --iou 0.45 \ --save-txt逻辑说明--source指向验证集目录批量跑完能直观看到模型在未见过的图上的表现。--conf 0.15降低门限召回遮挡目标--iou 0.45是 NMS 的默认值如果同一目标出现多个重叠框可以适当调低。--save-txt把预测结果存成 txt方便和真实标签做对比统计。跑完后重点看两类图一类是明明系了安全带但没框出来的一类是没系却框出安全带的这两类错误直接决定这个模型能不能上实际场景。5. 避坑与排查标注、路径、显存里的那些坑5.1 训练时提示“no labels found”现象训练启动后日志里反复出现No labels found或者Labels统计为 0。原因YOLOv5 根据图片路径推导标签路径如果 labels 目录和 images 目录不在同级或者标签文件名和图片文件名主干不一致就会找不到。解决用第 2 章里的配对脚本先核对一遍确认datasets/labels/train和datasets/images/train同级且每个 jpg 都有同名 txt。如果目录结构没问题检查 data.yaml 里的 train 路径是不是写成了绝对路径但实际是相对路径。5.2 可视化脚本画出来的框位置偏移现象运行可视化脚本后框的位置和实际目标对不上整体偏移或大小不对。原因标注时的图像尺寸和当前读取的图像尺寸不一致常见于图片被缩放或裁剪后标签没有同步更新。解决打印img.shape确认当前图像宽高再抽查标签文件里的坐标是否基于同一尺寸。如果数据集是从其他格式转换来的转换脚本里可能漏了尺寸归一化这一步。这套数据集标注和图片是配套导出的正常不会出现但如果你自己替换了部分图片就要重新核对。5.3 显存不足导致训练中断现象训练跑了几轮后报CUDA out of memory。原因--batch设得太大或者--img尺寸过高1201 张图在 640 尺寸下 batch 16 通常没问题但如果同时开了--cache且内存也吃紧会间接影响。解决先把 batch 降到 8 或 4再考虑降 img 到 416。如果降了还报检查是不是有其他进程占着显存。另一个容易忽略的点是--workers设得过高数据加载进程太多也会吃内存一般设 4 到 8 就够。5.4 验证集 mAP 始终为 0现象训练 loss 在降但验证集 mAP 一直是 0。原因验证集的标签路径或类别索引和训练集不一致比如训练集类别索引是 0验证集标签里写成了 1。解决分别抽查 train 和 val 的标签文件确认类别索引都是 0。另一个可能是 data.yaml 里的 val 路径指向了空目录或错误目录导致验证时没有加载到任何标签。用ls datasets/labels/val | wc -l确认标签数量是 354和图片数量对得上。5.5 推理时框出一堆无关区域现象detect.py 跑出来的图里背景区域被框成 seatbelt。原因置信度门限设得太低或者模型过拟合到了背景纹理。解决先把--conf调回 0.25 看是否消失如果消失说明是门限问题如果还在检查训练时是否用了过多的背景图或增强过猛。安全带检测的背景主要是车内饰如果训练集里某些内饰纹理反复出现且标注框附近有相似纹理模型容易混淆。这时候需要补充负样本或调整数据增强的裁剪比例。6. 进阶技巧用验证集反推标注质量与模型上限训练完一轮后别急着调参先把验证集的预测结果和真实标签做一次逐图对比。具体做法是用--save-txt跑完推理然后写个小脚本统计每张图的预测框数量和真实框数量的差值。差值大的图分两类预测多真实少说明误检预测少真实多说明漏检。把这两类图各抽十张出来看能快速定位是标注问题还是模型问题。import os pred_dir runs/detect/exp/labels gt_dir datasets/labels/val for f in os.listdir(gt_dir): gt_n sum(1 for _ in open(os.path.join(gt_dir, f))) pred_path os.path.join(pred_dir, f) pred_n sum(1 for _ in open(pred_path)) if os.path.exists(pred_path) else 0 if abs(gt_n - pred_n) 2: print(f{f}: 真实 {gt_n}, 预测 {pred_n})逻辑说明逐图对比真实框和预测框数量差值大于等于 2 的挑出来人工复核。参数上pred_dir是推理输出目录gt_dir是验证集标签目录。如果某张图真实框有 3 个但预测只有 1 个先看这张图的标注是不是把多个安全带实例标成了一个或者标注框严重偏离目标。如果真实框和预测框数量一致但位置对不上那就是回归精度问题需要检查训练时的 box_loss 曲线。另一个实用技巧是用验证集 mAP 反推数据量是否够用。1201 张训练图在单类别检测任务里如果 mAP0.5 在 50 轮后稳定在 0.85 以上说明数据量和标注质量都过关如果卡在 0.6 到 0.7 上不去优先怀疑标注一致性而不是模型容量。我一般会从验证集里挑 20 张 mAP 最低的图逐张看标注框是否贴合安全带边缘——很多时候不是模型学不会是标注本身就框歪了。从那以后我每次拿到新数据集都强制先跑一遍配对检查和分布统计再抽图可视化最后才动训练命令。这三步走完后面踩坑的概率能降一大半。希望帮到你。本文还有配套的精品资源点击获取
返回列表