ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

工地反光背心检测数据集:YOLO格式2700张训练图实战解析

工地反光背心检测数据集:YOLO格式2700张训练图实战解析 简介这份资源面向计算机视觉学习者与工地安全检测方向的开发者提供一套可直接用于YOLO目标检测的反光背心穿戴识别数据集帮助解决安全帽、反光衣等场景下目标检测模型训练与验证的数据来源问题。数据按YOLOv5标准文件夹结构组织包含训练集约2700张、验证集约770张、测试集约390张图片及对应标签文件类别共2类具体以classes文件为准可直接接入YOLO检测流程。压缩包为7z格式共约2000个文件以1999个txt标签文件和1个py可视化脚本为主整体约398.38MB。其中可视化脚本无需修改即可运行随机传入一张图片便能绘制边界框并保存到当前目录便于快速核查标注质量。目前已有380人学习浏览适合需要快速搭建工地安全检测基线、验证数据分布与标注格式的读者参考使用。1. 工地反光背心检测数据集2700 张训练图能跑出什么结果工地安全帽和反光背心检测是目标检测落地最典型的场景之一但真正动手时卡住大多数人的不是模型结构而是数据。网上开源的安全类数据集要么类别混乱要么标注格式不统一要么图片数量太少撑不起训练。这份 YOLO 格式的工地反光背心数据集直接按 YOLOv5 的目录结构组织好了训练集、验证集和测试集类别只有两个——穿戴反光背心和没穿反光背心标签是标准的 txt 格式还附带一个可视化脚本随机传一张图就能把边界框画出来存到当前目录。适合正在做工地安全监控、边缘端部署检测模型或者想拿一份干净的二分类数据集快速验证 YOLO 训练流程的从业者。下面从目录结构、标签格式、可视化验证到训练参数把这份资源拆开讲清楚。2. 数据集目录结构与 YOLO 标签格式拆解2.1 按 YOLOv5 规范组织的目录长什么样拿到一份数据集第一件事不是急着训练而是先确认目录结构对不对。YOLOv5 对数据目录有明确的约定常见做法是根目录下放images和labels两个文件夹各自再分train、val、test三个子集。这份资源就是按这个规范来的训练集约 2700 张图片加对应标签验证集约 770 张测试集约 390 张。图片是 jpg 格式标签是同名的 txt 文件文件名一一对应比如img_006_jpg.rf.dc1bdef4e66822aeecbcb764b1a9ba83.txt对应同名的图片文件。这种命名里带.rf.和长哈希串的风格是 Roboflow 导出时自动生成的不影响使用但要注意图片和标签的文件名必须完全一致只差扩展名。如果你后续要自己增补数据命名规则也得对齐否则 YOLO 在加载时会找不到标签直接报No labels found或者把没有标签的图当负样本处理训练结果会莫名其妙地差。目录结构大致如下dataset/ ├── images/ │ ├── train/ # 约 2700 张 jpg │ ├── val/ # 约 770 张 jpg │ └── test/ # 约 390 张 jpg ├── labels/ │ ├── train/ # 对应 txt 标签 │ ├── val/ │ └── test/ ├── classes.txt # 类别定义 └── show.py # 可视化脚本提示不同版本的 YOLO 对目录层级要求略有差异YOLOv5 和 YOLOv8 都支持这种images/labels分离的结构但 data.yaml 里的路径写法要对应调整。2.2 标签 txt 里每一行到底存了什么YOLO 格式的标签文件是纯文本每一行代表一个目标框格式是class_id x_center y_center width height后四个值都是归一化到 0 到 1 之间的浮点数。这份数据集的类别只有两个所以 class_id 只可能是 0 或 1具体哪个对应“穿戴反光背心”、哪个对应“没穿”要看 classes.txt 里的顺序。常见做法是 0 表示没穿1 表示穿戴但不同来源的数据集可能反过来训练前一定要打开 classes.txt 确认。举个例子一行标签可能是这样1 0.5234 0.6120 0.0890 0.2340意思是这个框属于类别 1中心点在图片宽高的 52.34% 和 61.20% 位置框的宽高分别占整图的 8.9% 和 23.4%。归一化的好处是图片无论怎么缩放标签都不用改这也是 YOLO 系列一直沿用这种格式的原因。用几行 Python 就能快速统计每个类别的框数量和分布判断数据是否均衡import os from collections import Counter label_dir dataset/labels/train counter Counter() for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue with open(os.path.join(label_dir, fname)) as f: for line in f: parts line.strip().split() if len(parts) 5: counter[parts[0]] 1 print(类别分布, dict(counter))这段代码遍历训练集所有标签文件统计每个 class_id 出现的次数。如果两个类别数量差距过大比如一个 5000 框、另一个只有 300 框训练时就要考虑用加权损失或者过采样来平衡。参数上label_dir换成 val 或 test 就能看验证集和测试集的分布建议三个子集都跑一遍确认划分是否合理。2.3 classes.txt 与 data.yaml 的对应关系classes.txt 里每行一个类别名顺序就是 class_id 的顺序。这份数据集里两行分别是穿戴反光背心和没穿反光背心具体顺序以文件为准。训练时还需要一个 data.yaml把图片路径、类别数和类别名告诉 YOLO。常见写法path: ./dataset train: images/train val: images/val test: images/test nc: 2 names: 0: vest 1: no_vestnc是类别数这里填 2names的顺序必须和 classes.txt 完全一致否则训练出来的模型会把类别搞反推理时把没穿背心的框标成穿戴这种错误在验证阶段看混淆矩阵才能发现属于典型的血泪经验。路径写法上path是根目录train、val、test是相对路径YOLOv5 和 YOLOv8 都认这种写法。3. 可视化脚本 show.py 的运行与边界框验证3.1 show.py 怎么跑起来可视化脚本是这份资源里最实用的部分之一。它的逻辑很简单随机传入一张图片脚本读取对应的标签文件把归一化的坐标还原成像素坐标用矩形框画在图上然后保存到当前目录。运行方式通常是命令行传参python show.py --image dataset/images/train/img_006_jpg.rf.dc1bdef4e66822aeecbcb764b1a9ba83.jpg脚本内部会做几件事用 OpenCV 或 PIL 读图根据图片文件名找到同目录下 labels 文件夹里的同名 txt逐行解析 class_id 和四个归一化坐标乘以图片宽高得到像素坐标再用cv2.rectangle画框、cv2.putText写类别名最后cv2.imwrite保存。如果脚本里用的是相对路径找标签那运行时的当前目录就很重要建议在数据集根目录下执行或者把脚本里的路径改成绝对路径。3.2 画出来的框能验证什么可视化不只是为了好看它能帮你快速判断几件事。第一标签和图片是否对齐如果框整体偏移或者尺寸明显不对说明标签在导出时可能出了问题。第二类别是否正确穿戴和没穿的框颜色或标签应该区分开如果发现大量误标这份数据就需要清洗。第三小目标比例反光背心在远景图里可能只占几十个像素如果框太小训练时就要考虑用更大的输入尺寸或者专门的小目标检测策略。我一般会随机抽 20 到 30 张图跑一遍可视化覆盖训练集、验证集和测试集重点看边缘场景——夜间、逆光、多人重叠、背心被遮挡。这些场景的标注质量直接决定模型上线后的误报率。如果发现某类场景标注普遍不准宁可把这几张剔掉也不要让脏数据进训练集。3.3 脚本改造批量可视化与类别过滤原脚本一次只处理一张图实际用的时候往往需要批量看。可以在原脚本基础上加一个循环遍历整个目录import os import cv2 img_dir dataset/images/train label_dir dataset/labels/train out_dir vis_output os.makedirs(out_dir, exist_okTrue) for fname in os.listdir(img_dir): if not fname.lower().endswith((.jpg, .png)): continue img_path os.path.join(img_dir, fname) label_path os.path.join(label_dir, os.path.splitext(fname)[0] .txt) if not os.path.exists(label_path): continue img cv2.imread(img_path) h, w img.shape[:2] with open(label_path) as f: for line in f: cid, x, y, bw, bh line.strip().split() x, y, bw, bh map(float, (x, y, bw, bh)) x1 int((x - bw / 2) * w) y1 int((y - bh / 2) * h) x2 int((x bw / 2) * w) y2 int((y bh / 2) * h) color (0, 255, 0) if cid 1 else (0, 0, 255) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.imwrite(os.path.join(out_dir, fname), img)这段代码批量处理训练集所有图片把画好框的图存到vis_output目录。color那行按 class_id 区分颜色方便一眼看出类别分布。参数上img_dir和label_dir换成 val 或 test 就能看其他子集out_dir可以改成你习惯的输出位置。跑完之后翻一遍输出图比看损失曲线更能发现数据问题。4. 用这份数据集训练 YOLO 的关键参数与避坑4.1 训练命令与核心参数怎么设数据确认没问题后就可以开训了。以 YOLOv5 为例常见命令是python train.py --img 640 --batch 16 --epochs 100 --data data.yaml --weights yolov5s.pt --cache--img 640是输入尺寸反光背心在图中占比不大时可以提到 800 甚至 1024但显存占用会明显上升。--batch 16是批大小显存不够就降到 8 或 4同时把学习率按比例调小。--epochs 100对 2700 张图来说通常够用如果验证集 mAP 在 80 轮后还在涨可以加到 150。--weights yolov5s.pt用预训练权重比从头训收敛快很多这也是为什么建议先用小模型跑通再换大模型。--cache把图片缓存到内存加快读取但数据量大时注意内存占用。训练过程中重点看三个指标mAP0.5、precision和recall。工地场景对漏检容忍度低recall 比 precision 更重要如果 recall 偏低优先检查标注是否漏框而不是急着调模型。4.2 避坑这份数据集最容易翻车的五个地方现象一训练一开始就报No labels found。原因通常是 data.yaml 里的路径写错或者图片和标签文件名不一致。解决方法是先用os.listdir对比 images 和 labels 目录下的文件名集合确认一一对应再检查 yaml 里的相对路径是否从正确的根目录出发。现象二训练 loss 正常下降但验证 mAP 一直是 0。大概率是类别顺序搞反了或者 names 里的类别数和 nc 对不上。打开 classes.txt 和 data.yaml 逐行核对确保顺序和数量完全一致。这种错误在混淆矩阵里表现为所有预测都集中到一个类别。现象三可视化时框的位置整体偏移。原因可能是标签在导出时用了不同的归一化基准比如按 padding 后的图算的而原图没有 padding。解决办法是拿几张图手动量一下框的像素坐标和标签还原出来的坐标对比确认偏差是系统性的还是随机的。现象四小目标漏检严重。反光背心在远景图里可能只有 20 到 30 像素宽640 输入下特征几乎消失。常见做法是把输入尺寸提到 1024或者在数据增强里加 mosaic 和 copy-paste增加小目标样本。也可以换用带 P2 检测层的模型结构专门抓小目标。现象五验证集和测试集分布不一致。如果验证集 mAP 很高但测试集掉得厉害说明划分时没有按场景分层。解决方法是重新划分确保训练、验证、测试三个子集里都包含白天、夜间、多人、单人等不同场景而不是随机切分。4.3 数据增强与类别平衡的实操建议这份数据集两个类别天然不均衡工地上穿戴反光背心的样本通常远多于没穿的。训练时可以在 YOLO 的 hyp 配置文件里调fl_gamma或者用--balance类的采样策略。更直接的办法是在数据加载阶段对少数类做过采样或者用 mosaic 增强时提高少数类图片的拼接概率。增强参数上hsv_h、hsv_s、hsv_v控制色调、饱和度、亮度扰动工地场景光照变化大可以适当调大。degrees旋转角度建议控制在 10 度以内因为反光背心的朝向在真实场景里不会剧烈旋转。translate和scale可以正常开增加位置和尺度多样性。如果发现模型对夜间场景表现差可以专门收集夜间图做补充而不是靠增强硬造。5. 从训练到部署验证模型是否真的可用的几个技巧训练完拿到best.pt别急着上线。我一般会走一遍完整的验证流程确认模型在真实场景下不掉链子。第一步是用测试集跑val.py看 mAP、precision、recall 三个指标的绝对值而不是只看训练曲线。测试集 mAP 比验证集低 5 个点以内算正常低太多说明过拟合或者划分有问题。第二步是拿一批训练集里没出现过的工地实拍图做推理重点看误报和漏报。误报多说明模型把类似背心的颜色或形状当成了目标漏报多说明小目标或者遮挡场景没学好。这时候可以调低置信度阈值看召回能不能上来但阈值太低会引入大量误报需要根据业务容忍度找平衡点。第三步是看推理速度。如果用 YOLOv5s在普通 GPU 上单张图推理通常在 10 毫秒以内边缘设备上可能到几十毫秒。工地监控往往要求实时如果速度不够可以换更小的模型或者用 TensorRT 加速。导出 ONNX 或 TensorRT 引擎时注意输入尺寸和归一化参数要和训练时一致否则精度会掉。最后一步是做一个简单的混淆矩阵看两个类别之间有没有互相误判。穿戴和没穿在颜色上差异明显正常情况混淆应该很少如果混淆严重说明标注里可能有一批图把两个类别标反了需要回头清洗。从那以后我每次拿到新数据集都强制先跑一遍可视化加类别统计再开始训练这个习惯帮我省下了大量返工时间。希望这份拆解能帮到你顺利跑通自己的检测流程。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进