2026/10/4 1:57:37

工地安全帽检测数据集详解:VOC/COCO/YOLO标注格式与YOLO11训练实战

工地安全帽检测数据集详解:VOC/COCO/YOLO标注格式与YOLO11训练实战 简介这是一份面向智慧工地安全监控场景的工人安全设备佩戴检测数据集涵盖建筑工地、道路施工、室内装修等真实场景包含部分遮挡与严重遮挡样本共划分14个类别覆盖安全帽、手套、护目镜、反光背心、口罩及坠物检测等正负样本适合用于YOLO等目标检测模型的训练与算法验证。资源包内为1个PDF文件大小约8.59MB内容包含数据集基本情况介绍、labelimg标注示意、数据缩略图及获取方式说明并额外提供支持GPU、CPU及Mac M芯片平台的YOLO11一键训练脚本与训练结果日志参考方便不同硬件环境快速上手。目前已有426人学习浏览该资源适合希望补充工地安全合规检测数据或进行智慧工地项目实践的开发者、算法工程师及研究人员使用。1. 工地安全帽检测数据集从标注格式到三平台训练的完整闭环做智慧工地项目的工程师都有个共同的痛点网上公开的安全装备数据集要么类别太少要么全是摆拍场景真正到工地现场一跑就垮。这份工地工人安全设备佩戴检测数据集一共3000张真实场景图片覆盖建筑工地、道路施工、室内装修等场景标了14个类别从Hardhat、Safety Vest、Gloves到NO-Hardhat、NO-Safety Vest这类负样本一应俱全最关键的是同时提供VOC、COCO、YOLO三种标注格式还附带YOLO11一键训练脚本GPU、CPU、Mac M芯片都能直接跑。对正在做智慧工地安全监控项目、或者需要给现有检测模型补充工地场景数据的人来说这份资源能直接省掉半个月的标注和格式转换时间。2. 三种标注格式怎么选VOC/COCO/YOLO 的结构差异与实际使用场景2.1 同一份数据三种格式各自解决什么问题先看这份数据集最核心的卖点同一批图片分别提供了xml、json、txt三种标签文件。很多第一次接触目标检测的人会以为这只是格式不一样实际用起来差别非常大。VOC格式xml是Pascal VOC组织定义的标注标准每个xml文件对应一张图片里面用object节点描述每个目标的类别和边界框坐标坐标是绝对值单位是像素。它的优势是可读性极强用文本编辑器打开就能看懂也方便写脚本做数据检查。COCO格式json把所有图片的标注集中在一个json文件里包含images、annotations、categories三个核心字段支持更丰富的标注类型比如分割多边形、关键点是目前学术论文和主流框架最常用的格式。YOLO格式txt则是每个txt文件对应一张图每行一个目标类别id x_center y_center width height注意这里全部是归一化后的相对坐标数值范围在0到1之间。这个数据集三种格式都有意味着你拿到手不需要再做格式转换想用哪个框架就直接喂哪个。我自己以前踩过坑找人标了一批数据只给了YOLO格式想试一下MMDetection就得自己写转换脚本边界框坐标从归一化转回像素坐标的时候出了好几次错浪费了一整天。所以看到三格式齐备这个配置我是很认可的。2.2 VOC标注文件的字段拆解训练前必须检查的三个节点VOC格式虽然直观但训练前有几个字段必须确认。拿这份数据集里的xml文件举例核心结构是这样的annotation folderimages/folder filenameIMG_20240315_143200.jpg/filename size width1920/width height1080/height depth3/depth /size object nameHardhat/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin452/xmin ymin318/ymin xmax612/xmax ymax421/ymax /bndbox /object /annotation这里要注意三点。第一name标签的取值必须和类别配置文件完全一致多一个空格、大小写不一致都会导致训练时类别错乱。这份数据集的类别名里有NO-Gloves、NO-Goggles这种带连字符的写法在YOLO训练配置里写类别名时千万别把连字符去掉。第二width和height是原图的尺寸不是缩放后的尺寸后续做数据增强或者resize时坐标要跟着比例换算。第三truncated表示目标是否被截断difficult表示目标是否难以识别这两个字段在训练时通常会被忽略但如果你想做更精细的难例挖掘这两个值就有参考价值了。2.3 COCO格式的annotations结构类别ID对齐是最大的坑COCO格式的json文件训练前最需要检查的是categories和annotations里的category_id是否一一对应。这份数据集的json结构大致是这样{ images: [ {id: 0, file_name: IMG_0001.jpg, width: 1920, height: 1080} ], annotations: [ { id: 0, image_id: 0, category_id: 1, bbox: [652, 381, 262, 398], area: 104276.0, iscrowd: 0 } ], categories: [ {id: 0, name: Fall-Detected}, {id: 1, name: Gloves} ] }COCO格式里bbox的四个数值是[x, y, width, height]代表边界框左上角坐标和框的宽高单位是像素。area是面积在COCO评估协议中计算mAP时要用到。iscrowd字段表示该目标是否属于密集人群值为1时在评估中会被特殊处理。我一般拿到COCO格式数据会先写个两分钟的脚本检查categories的name和id是否对应得合理不会出现两个类别共用一个id的情况。用这份数据集训练之前我也建议你先把json文件里的categories段落打印出来确认一遍因为来自labelimg导出的COCO格式有时会出现类别id从0开始还是从1开始的混乱某些框架默认从1开始你一旦混用了训练出来的模型类别就是歪的。2.4 YOLO格式的txt标签归一化坐标与类别id从0开始YOLO格式最简洁也最容易出问题。每个txt文件的每一行是类别id x_center y_center width height五个数值用空格分隔。这里x_center和y_center是目标中心点的归一化坐标width和height是归一化后的框宽高全部除以图片宽高。这份数据集用的是YOLO格式ultralytics YOLO11可以直接训练目录结构按images/train和labels/train组织。2 0.345833 0.462963 0.156250 0.368519 5 0.623958 0.694444 0.114583 0.259259第一行的2代表类别id注意YOLO的类别id从0开始所以如果你有14个类别id范围是0到13。第二行是Safety Vest和Person这类目标。这里最容易翻车的点在于data.yaml文件里的类别列表顺序必须和txt标签里数字id一一对应。这份数据集如果我猜得没错data.yaml里第0个类别是Fall-Detected第13个是Safety Vest顺序稍有调整整个训练结果就全乱了。我在实际项目中遇到过这种情况txt标签里id2是Goggles但data.yaml里第2个类别写的是Gloves训练完模型检测Goggles的时候输出的是Gloves的置信度折腾了一天才发现是类别顺序错位。所以拿到这份数据集的txt格式第一件事就是检查data.yaml的类别顺序和所有txt标签里出现的id是否互相匹配这个检查用下面这个脚本不到十分钟就能跑完。3. YOLO11 一键训练脚本GPU/CPU/Mac配置实测与参数解读3.1 三平台环境差异先搞清楚这份数据集附带YOLO11训练脚本支持GPU、CPU、Mac M芯片三种平台。先说明一下为什么这是个实用功能Ultralytics YOLO11框架默认会尝试用GPU训练但Mac M芯片的GPU和NVIDIA GPU架构不同PyTorch在这两个平台上的backend不一样所以很多人往Mac上一跑就报torch.cuda.is_available()为False然后直接退出。这份资源的价值就在于把这些平台差异在脚本里处理掉了。处理逻辑通常是这样的脚本检测当前环境有没有NVIDIA GPU有就自动用GPU训练没有就检查是不是Apple Silicon芯片是就启用MPS后端都不是就退回CPU训练。MPS是PyTorch为Apple芯片提供的GPU加速后端在PyTorch 1.12以上版本里默认支持但要注意MPS对某些算子的支持还不完整遇到不支持的算子会自动回退到CPU训练速度会突然掉下来。import torch def detect_device(): if torch.cuda.is_available(): device cuda print(检测到 NVIDIA GPU使用 GPU 训练) elif hasattr(torch.backends, mps) and torch.backends.mps.is_available(): device mps print(检测到 Apple Silicon 芯片使用 MPS 加速) else: device cpu print(未检测到 GPU使用 CPU 训练) return device device detect_device() print(f最终使用设备: {device})这段代码里torch.backends.mps.is_available()是检查MPS后端能否使用的标准方法在Mac M芯片的机器上返回True。判断顺序有个讲究先检查CUDA再检查MPS因为部分Mac机器可能装了NVIDIA驱动的外接GPU但这种情况极少见。实际跑脚本时建议在终端打印一下PyTorch版本和检测到的设备名确认没走错后端。3.2 跑通训练脚本的完整步骤拿到这份资源后从零开始跑通训练大概分五步。第一步准备目录结构把所有图片和标签按YOLO格式组织好。第二步写data.yaml配置。第三步调训练参数。第四步开始训练。第五步看训练日志判断效果。先看目录结构。YOLO11用ultralytics框架训练默认期望的目录组织方式是images/train、images/val、labels/train、labels/val四个目录。这份数据集如果已经分好train/val就直接用没有分的话用脚本划分import os import random import shutil image_dir dataset/images label_dir dataset/labels train_ratio 0.9 all_images [f for f in os.listdir(image_dir) if f.endswith((.jpg, .png, .jpeg))] random.seed(42) random.shuffle(all_images) split_idx int(len(all_images) * train_ratio) train_images all_images[:split_idx] val_images all_images[split_idx:] for split, imgs in [(train, train_images), (val, val_images)]: os.makedirs(fdataset/{split}/images, exist_okTrue) os.makedirs(fdataset/{split}/labels, exist_okTrue) for img_name in imgs: shutil.copy(os.path.join(image_dir, img_name), fdataset/{split}/images/) label_name img_name.rsplit(., 1)[0] .txt if os.path.exists(os.path.join(label_dir, label_name)): shutil.copy(os.path.join(label_dir, label_name), fdataset/{split}/labels/)这个脚本里有几个关键参数。train_ratio设为0.9意味着90%的数据用来训练、10%用来验证3000张图对应2700张训练、300张验证这个比例对大多数项目是够用的。random.seed(42)保证每次划分结果一致方便复现。注意脚本只复制图片和对应存在的txt标签偶尔有图片漏标了不会让训练直接崩溃但会在验证时产生警告后面避坑章节会细说。再说data.yaml这是YOLO训练的核心配置文件# dataset.yaml path: ./dataset train: train/images val: val/images nc: 14 names: 0: Fall-Detected 1: Gloves 2: Goggles 3: Hardhat 4: Ladder 5: Mask 6: NO-Gloves 7: NO-Goggles 8: NO-Hardhat 9: NO-Mask 10: NO-Safety Vest 11: Person 12: Safety Cone 13: Safety Vest这里path是数据集根目录的路径可以是相对路径也可以是绝对路径。train和val相对于path来写不写绝对路径的话训练脚本不在数据集根目录运行时容易找不到文件。nc是类别总数14names的键值对顺序就是txt标签里id的对应顺序。这份数据集的类别配置是这个项目成败的关键改任何一个名字都要同步改所有txt文件里的id。训练命令用ultralytics的标准写法yolo train modelyolo11s.pt datadataset.yaml epochs100 imgsz640 batch16 device0modelyolo11s.pt表示用YOLO11的small版本预训练权重作为起点。epochs100在3000张图上大概要跑几个小时要根据你的硬件来调整。batch16在显存不够时候往下调8G显存跑batch8就差不多了。device0指定用第一张NVIDIA GPUCPU跑的话改成devicecpu。训练完以后看结果ultralytics会在runs/detect/train/目录下生成一系列文件重点关注results.csv里的metrics/mAP50-95(B)和metrics/mAP50(B)两列。mAP50在0.5以上说明模型基本能用0.7以上算做得不错。如果训练集上mAP很高但验证集上很低那就是过拟合需要增加数据增强或加大正则化。3.3 脚本背后的参数调整逻辑一键训练脚本的优势在于把参数都预设好了但如果你想根据自己的场景调节奏需要理解几个关键参数之间的关系。imgsz640是输入图片尺寸YOLO11的默认值。这个值越大检测精度越高但显存占用和推理时延也越大。工地场景摄像头拍摄的画面通常比较宽如果目标是画面中较小的安全帽、手套imgsz640可能不太够可以试imgsz800甚至imgsz960代价是训练速度约慢30%。batch要跟imgsz和显存一起考虑。经验公式是8G显存配imgsz640极限能跑batch816G显存能跑batch16。如果你发现训练过程中显存溢出报错CUDA out of memory直接下调batch或者开启cacheTrue让数据缓存策略调整一下。训练脚本在CPU上跑的话要有心理准备。3000张图、14个类别、100个epochCPU训练可能要挂机跑两三天。这时建议把epochs降到50workers调低避免CPU训练时还开一堆线程吃满所有核心导致系统卡顿。4. 避坑排查工地检测数据集训练的常见问题与解决4.1 训练时报错 图片标签数量不匹配现象启动训练后终端刷出一堆告警类似WARNING: imgsz640, found 5 labels in xxx.txt或found no labels in xxx.jpg训练能继续但loss曲线明显异常。原因YOLO格式要求每张图片有且仅有一个同名的txt标签文件。数据在整理或拷贝的过程中部分图片丢失了对应标签或者空标签文件没被正确生成。labelimg标注时如果某张图没画任何框导出时可能不会生成txt文件这个和标注操作习惯有关。解决写个脚本检查一下每张图片是否都有对应标签并统计标签文件里是否有空文件import os image_dir dataset/images/train label_dir dataset/labels/train missing [] empty [] for img_name in os.listdir(image_dir): base os.path.splitext(img_name)[0] label_path os.path.join(label_dir, base .txt) if not os.path.exists(label_path): missing.append(img_name) else: if os.path.getsize(label_path) 0: empty.append(img_name) print(f缺少标签的图片: {len(missing)} 张) print(f标签为空的图片: {len(empty)} 张) for m in missing[:10]: print(f {m})缺标签的图片要么补标要么直接从训练集里剔除空标签文件建议删掉或补标不然后面验证mAP时这些空目标会影响背景类的判断。4.2 类别数量对不上VOC转YOLO时的经典翻车现象训练脚本跑完打印的类别数量是15或者13和预期14个不一致。特别是用ultralytics框架时nc值和实际标签里出现的最大类别id不匹配会导致索引越界或类别错位。原因VOC转YOLO的脚本在遍历xml文件时有些类别的名字带有空格或连字符比如NO-Safety Vest如果转换脚本用空格切分文本就会把一个类别拆成两个类别数就多了。反过来如果多个类别的名字写得不完全一致比如一处写Hardhat另一处写HardHat类别数会变少。解决训练前统一检查所有txt标签里出现的类别id集合再跟data.yaml比对import os import glob label_files glob.glob(dataset/labels/*/*.txt) all_ids set() for lf in label_files: with open(lf) as f: for line in f: parts line.strip().split() if parts: all_ids.add(int(parts[0])) print(f标签文件中出现的类别 id 集合: {sorted(all_ids)}) print(f类别数量: {len(all_ids)})如果输出的id集合里有大于13的数字或者缺失某个数字说明标注转换阶段就有问题要回到原始xml重新检查。不要指望训练时自动修复YOLO不会帮你做这个容错。4.3 Mac M芯片训练时报 libomp 编译错误现象在Mac M芯片机器上运行训练脚本终端报错RuntimeError: Failed to load libomp.dylib或Symbol not found: _GOMP_parallel。原因ultralytics依赖的一些PyTorch算子需要OpenMP并行库支持macOS系统自带的编译器环境里通常缺这个库。这是Mac环境跑深度学习框架的经典问题和数据集本身无关但很多人在Mac上第一次跑就直接卡在这里。解决brew install libomp装完以后重启终端再跑一次训练脚本。如果还是报错检查一下是不是conda环境的问题在conda环境里额外执行conda install llvm-openmp也可以解决。这个坑是Mac用户跑YOLO系列的必踩项提前装好省得浪费时间。4.4 CPU内存不足导致训练中断现象训练跑到几十个epoch之后系统内存占用飙升进程被OOM Killer杀掉终端显示Killed。原因YOLO11训练时默认开启了数据增强缓存ultralytics框架会把部分图片缓存到内存里加速读取。3000张图如果原图都是1920x1080缓存全部加载可能占用10G以上内存。加上训练过程中的临时变量16G内存的机器确实有耗尽的风险。解决训练命令加两个参数。cacheFalse可以关闭图片缓存workers2降低数据加载的并行度。这样内存占用能控制在4G以内代价是每个epoch的数据读取时间变长但总比训到一半被杀掉要好。yolo train modelyolo11s.pt datadataset.yaml epochs100 imgsz640 batch16 cacheFalse workers25. 训练结果分析技巧从日志判断模型能不能直接用训练完成后不要急着拿去部署先看几个关键指标。打开runs/detect/train/results.csv重点看最后几行的metrics/mAP50(B)和metrics/mAP50-95(B)。mAP50指的是IoU阈值取0.5时的平均精度均值这个指标对边界框位置的要求比较宽松大致能框住目标就算对。mAP50-95是对IoU从0.5到0.95按0.05步长取平均这个指标严格得多边界框稍微偏一点分数就会掉。工地场景下如果你追求的是安全帽、反光背心这类目标的有无判断mAP50在0.85以上就可以考虑上线如果要做精确的违规检测并联动处罚系统最好要求mAP50-95也到0.6以上。第二个要关注的是train/box_loss和val/box_loss两条loss曲线。训练正常的模型两条曲线都应该持续下降然后趋于平稳。如果train_loss一直在降但val_loss在第50个epoch开始反弹说明过拟合了。这时可以调低epochs到60或者开启更强的数据增强比如hsv_h0.02调低颜色增强幅度。还有一个容易忽略但很重要的指标是metrics/precision(B)和metrics/recall(B)。精度表示模型检测出的目标里有多少是对的召回表示真正的目标被找出来多少。工地安全检测场景中漏检的代价比误检高得多一个没戴安全帽的工人被漏掉可能直接导致安全事故所以调参时要偏向高召回。如果recall偏低说明模型的锚框设置可能不太适合小目标可以考虑用YOLO11自带的自动锚框计算功能让框架根据数据集重新计算锚框参数yolo train modelyolo11s.pt datadataset.yaml epochs100 imgsz640 batch16 workers8不加anchorsNone参数时ultralytics会自动计算锚框这比手动调参靠谱得多。拿数据集附带的训练日志来对照是个好习惯。如果博主的训练日志里mAP50在0.9左右而你自己复现只有0.7先不要怀疑数据集有问题优先检查你的数据划分是否一致、class weights是否初始化一样、随机种子是否固定。YOLO的训练结果受随机种子影响波动1到2个百分点很正常但差太多就要检查环境了。训练完成之后我习惯做一次可视化验证。用训练好的权重对验证集图片批量推理把结果画出来人工检查yolo predict modelruns/detect/train/weights/best.pt sourcedataset/val/images saveTrue跑完以后打开runs/detect/predict/目录下的图片重点看三个地方有没有漏检远处的小目标有没有把背景误检成Hardhat或PersonNO-Hardhat和Hardhat这两类有没有混淆。工地场景里戴了黄色安全帽和没戴的工人在画面中颜色接近是老生常谈的类别混淆问题。如果发现NO-Hardhat和Hardhat严重混淆可以在训练时给这两个类别加不同的样本权重或者把这两类的训练图片数量手动调均衡一些。从那以后我拿到任何目标检测数据集第一件事永远是检查类别配置和标签数量不急着开训练。花二十分钟把标签文件系统性扫一遍省下来的是后面好几天排错的精力。这份工地数据集能在几分钟内跑通YOLO11训练前提是这三种格式的标签和脚本本身没被人为改动过。希望这份拆解能帮你把时间花在调模型和做工程上而不是耗在数据格式的坑里希望帮到你。本文还有配套的精品资源点击获取