ARTICLE DETAIL

资讯详情

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

驾驶员安全带检测数据集与YOLOv8训练实战指南

驾驶员安全带检测数据集与YOLOv8训练实战指南 简介这是一份面向计算机视觉初学者与目标检测开发者的驾驶员安全带佩戴检测数据集可直接用于YOLO系列模型的训练与验证帮助解决车内场景下安全带识别这一典型应用问题。资源包共2000个文件以1556个txt标注文件、443张jpg图像和1个py可视化脚本为主压缩包约63.76MB标注采用YOLO相对坐标格式类别仅seatbelt一类。数据已按YOLOv5目录结构划分训练集含1201张图片及对应标签验证集含354张图片及对应标签并附有类别文本文件开箱即可投入训练。配套的可视化脚本无需修改随机传入一张图片即可绘制边界框并保存到当前目录便于快速核验标注质量。目前已有139人学习适合需要快速搭建安全带检测基线、验证模型效果或开展课程实践的用户参考使用。1. 驾驶员安全带检测数据集从拿到手到跑通 YOLOv8 的第一公里拿到一个标注好的驾驶员安全带检测数据集最怕的不是模型训不起来而是打开压缩包发现目录结构看不懂、class 文件对不上、可视化脚本跑出一堆乱框。这个标题指向的正是一套开箱即用的工程化资源划分好的训练/验证/测试集、类别定义文件、以及配套的数据可视化脚本。它解决的是从零采集和标注的成本问题适合两类人——想快速验证安全带检测方案可行性的算法工程师以及需要把检测能力嵌入车载终端或车队管理系统的开发者。安全带检测本身属于小目标、遮挡多、光照变化剧烈的场景驾驶员坐姿、衣着颜色、方向盘遮挡都会影响召回所以数据集的质量和划分策略直接决定模型上限。这一章先把这套资源的结构和用途讲清楚后面几章再拆训练、调参和排错。2. 数据集目录结构与 class 文件先看懂再动手2.1 划分好的数据集长什么样一套规范的 YOLO 格式安全带检测数据集通常按下面的目录组织。不同来源的包可能命名略有差异但核心结构一致safety_belt_dataset/ ├── images/ │ ├── train/ # 训练集图片 │ ├── val/ # 验证集图片 │ └── test/ # 测试集图片 ├── labels/ │ ├── train/ # 训练集标注 txt │ ├── val/ │ └── test/ ├── classes.txt # 类别名称每行一个 └── data.yaml # YOLO 训练配置入口图片和标签必须同名同层级比如images/train/001.jpg对应labels/train/001.txt。标签文件每行格式是class_id x_center y_center width height坐标全部归一化到 0~1。如果拿到的是 VOC 的 XML 或 COCO 的 JSON需要先转换这一步后面会给脚本。划分比例常见的是 7:2:1 或 8:1:1。安全带检测里我一般会保证验证集和测试集覆盖不同光照和车型否则指标虚高。如果数据集已经划分好先别急着训用可视化脚本抽查几十张确认框的位置和类别没错。2.2 class 文件与 data.yaml 的对应关系classes.txt里每行一个类别名顺序就是 class_id。安全带检测常见两类seatbelt已系和no_seatbelt未系有的数据集会拆成driver_seatbelt、passenger_seatbelt等。关键是data.yaml里的names必须和classes.txt顺序完全一致差一行整个训练就全错位。# data.yaml path: ./safety_belt_dataset train: images/train val: images/val test: images/test nc: 2 names: 0: seatbelt 1: no_seatbeltnc是类别数必须等于names的条目数。path用相对路径时训练命令要在数据集父目录执行否则 YOLO 找不到图片。我习惯写成绝对路径省得后面换目录翻车。提示改完data.yaml后用python -c import yaml; print(yaml.safe_load(open(data.yaml)))确认能正常解析YAML 缩进错一个空格就会静默失败。2.3 用可视化脚本抽查标注质量可视化脚本的作用是把标注框画回图片上肉眼确认有没有漏标、错标、框偏移。下面是一个不依赖额外库的检查脚本只用 OpenCV 和 osimport cv2 import os import random # 数据集根目录按实际路径改 ROOT ./safety_belt_dataset CLASSES [seatbelt, no_seatbelt] # 每个类别颜色不同方便区分 COLORS [(0, 255, 0), (0, 0, 255)] def draw_one(img_path, label_path): img cv2.imread(img_path) if img is None: print(f读图失败: {img_path}) return h, w img.shape[:2] if os.path.exists(label_path): with open(label_path) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue cid, x, y, bw, bh int(parts[0]), *map(float, parts[1:]) # 归一化坐标还原成像素 x1 int((x - bw / 2) * w) y1 int((y - bh / 2) * h) x2 int((x bw / 2) * w) y2 int((y bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), COLORS[cid % len(COLORS)], 2) cv2.putText(img, CLASSES[cid], (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, COLORS[cid % len(COLORS)], 2) cv2.imshow(check, img) cv2.waitKey(0) # 随机抽 20 张训练集图片 img_dir os.path.join(ROOT, images/train) files [f for f in os.listdir(img_dir) if f.endswith((.jpg, .png))] for fname in random.sample(files, min(20, len(files))): stem os.path.splitext(fname)[0] draw_one(os.path.join(img_dir, fname), os.path.join(ROOT, labels/train, stem .txt)) cv2.destroyAllWindows()逻辑说明脚本读取图片和同名 txt把归一化坐标还原成像素坐标后画框。COLORS按类别索引取色cid % len(COLORS)防止类别数超过颜色数时越界。random.sample抽 20 张避免只看前几张都是同一场景。参数上ROOT改成你的数据集路径CLASSES必须和classes.txt一致。如果框画出来偏了多半是坐标没归一化或图片被 resize 过先查这两点。3. 用 YOLOv8 训练安全带检测环境、命令与参数3.1 环境配置与依赖安装YOLOv8 通过 ultralytics 包安装Python 建议 3.8~3.11。Anaconda 环境下先建独立环境避免和系统里的 torch 冲突conda create -n seatbelt python3.10 -y conda activate seatbelt # 有 GPU 的话先按 CUDA 版本装 torch再装 ultralytics pip install ultralytics opencv-python pyyaml装完用yolo checks验证会打印 torch 版本、CUDA 是否可用、GPU 型号。如果CUDA available是 False训练会退回 CPU速度差几十倍。V100 这类卡记得装对应 CUDA 的 torch别直接pip install torch拉默认版本。3.2 训练命令与关键参数最小训练命令就一行但参数决定成败yolo detect train \ data./safety_belt_dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/seatbelt \ nameexp1model选yolov8n.pt是轻量版车载端部署优先追求精度换yolov8s.pt或yolov8m.pt。imgsz640是默认输入尺寸安全带属于中小目标如果图片里驾驶员占比小可以提到 960但显存和速度要权衡。batch按显存调V100 16G 跑 640 可以到 32。lr0初始学习率 0.01 是 YOLOv8 常用值数据量小于 2000 张时降到 0.005 更稳。patience20表示 20 轮没提升就早停省时间。训练日志里重点看mAP50和mAP50-95以及每个类别的precision/recall。安全带检测里no_seatbelt的召回通常比seatbelt低因为未系状态样本少、遮挡多。如果某一类 recall 长期低于 0.6先查该类样本量再考虑加数据或调cls损失权重。3.3 从 VOC/COCO 转 YOLO 格式如果拿到的不是 YOLO txt而是 VOC XML用下面脚本批量转import xml.etree.ElementTree as ET import os # 类别映射按你的 classes.txt 顺序改 CLASS_MAP {seatbelt: 0, no_seatbelt: 1} def voc_to_yolo(xml_path, out_path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in CLASS_MAP: continue cid CLASS_MAP[name] bbox obj.find(bndbox) x1 float(bbox.find(xmin).text) y1 float(bbox.find(ymin).text) x2 float(bbox.find(xmax).text) y2 float(bbox.find(ymax).text) # 转成中心点宽高并归一化 xc (x1 x2) / 2 / w yc (y1 y2) / 2 / h bw (x2 - x1) / w bh (y2 - y1) / h lines.append(f{cid} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}) with open(out_path, w) as f: f.write(\n.join(lines)) # 批量处理 xml_dir ./VOC/Annotations out_dir ./labels/train os.makedirs(out_dir, exist_okTrue) for f in os.listdir(xml_dir): if f.endswith(.xml): voc_to_yolo(os.path.join(xml_dir, f), os.path.join(out_dir, f.replace(.xml, .txt)))逻辑说明解析 XML 拿到图片宽高和每个框的角点坐标转成 YOLO 要求的中心点加宽高并归一化。CLASS_MAP必须和classes.txt顺序一致否则类别全乱。:.6f保留六位小数避免精度损失。转换后务必用 2.3 的可视化脚本抽查XML 里偶尔有宽高为 0 的脏框转出来会变成异常值。4. 安全带检测的避坑与排查那些让 mAP 掉点的细节4.1 类别顺序错位导致全盘皆错现象训练 loss 正常下降但验证时框的位置对、类别全反seatbelt和no_seatbelt互换。原因data.yaml的names顺序和标注文件里的 class_id 不一致或者classes.txt改过但没同步。解决训练前用脚本统计每个 class_id 的出现次数和classes.txt逐行核对确认 0 对应哪个类。改完重新生成data.yaml别手动改一半。4.2 图片和标签不同名导致静默丢样本现象训练集明明有 3000 张日志里train只有 2400 张。原因YOLO 按同名匹配图片和标签.jpg和.JPG、.jpeg和.jpg混用或者标签文件名多了空格。解决统一扩展名用脚本批量重命名训练前跑一遍len(os.listdir(images/train))和len(os.listdir(labels/train))对比差值超过 5% 就要查。4.3 小目标漏检与 imgsz 的取舍现象系了安全带的驾驶员检测正常但安全带本身细长条经常漏。原因安全带在 640 输入下可能只有十几个像素宽下采样后特征丢失。解决把imgsz提到 960 或 1280或者在数据增强里关掉mosaicmosaic0.0因为 mosaic 会把小目标拼得更小。代价是显存和训练时间上升V100 上 1280 大概只能跑 batch 8。4.4 验证集指标虚高但实车翻车现象mAP50到 0.95装到车上误报一堆。原因验证集和训练集来自同一批视频光照、车型、驾驶员高度相似模型过拟合到场景而非目标。解决划分时按视频或按驾驶员分组保证验证集里有训练集没见过的车型和光照。如果数据集已经划分好至少把测试集单独留出来训练全程不碰最后只跑一次。4.5 置信度门限没调导致误报现象默认conf0.25时方向盘纹理、深色衣服被误判成安全带。原因安全带和某些纹理在低分辨率下特征接近。解决推理时把conf提到 0.4~0.5同时开iou0.5做 NMS。用验证集画 PR 曲线找 recall 和 precision 的平衡点别拍脑袋定。如果业务上漏检代价高就保 recall 牺牲一点 precision反之亦然。5. 进阶技巧用混淆矩阵和可视化脚本闭环验证训练完不是看个 mAP 就结束。混淆矩阵能告诉你模型到底把什么认成了什么。YOLOv8 训练结束会在runs/seatbelt/exp1/下生成confusion_matrix.png重点看非对角线如果no_seatbelt大量被预测成seatbelt说明未系样本的特征没学好要么加样本要么检查标注里有没有把未系标成已系。我习惯在可视化脚本里加一个推理模式把模型预测框和真实框叠在同一张图上绿色是 GT红色是预测一眼看出漏检和误检的位置from ultralytics import YOLO import cv2 model YOLO(runs/seatbelt/exp1/weights/best.pt) results model.predict(test_images/, conf0.4, iou0.5, saveTrue) # saveTrue 会把画好框的图存到 runs/detect/predict/参数上conf0.4是安全带场景的起步值iou0.5控制重叠框合并。如果发现同一根安全带被画了两个框把iou降到 0.4如果相邻两个驾驶员的安全带被合并成一个把iou提到 0.6。这个值没有万能解按你的摄像头视角和驾驶员间距调。还有一个容易忽略的点测试集推理完把误报的图单独挑出来看往往能发现标注规范问题。比如有的标注把安全带卡扣也算进框有的只框了肩带没框腰带模型学到的边界就不一致。统一标注规范比调参涨点更实在。我自己踩过最深的坑是拿一个划分好的数据集直接训没检查 class 顺序结果两周的实验全废混淆矩阵里两类完全颠倒。从那以后任何数据集到手先跑可视化脚本抽 50 张再统计类别分布最后才开训练。这个习惯帮我省下的时间远比调参多。希望帮到你。本文还有配套的精品资源点击获取
返回列表