简介:YOLOv5格式的建筑工地安全隐患检测数据集,面向计算机视觉开发者与安全监控场景,覆盖头盔、口罩、车辆等十类常见隐患目标,适用于目标检测模型训练和算法验证。资源包共2000个文件,以YOLOv5规范的txt标签文件为主,并附带1个Python可视化脚本,压缩包整体148.9MB,标签文件已按训练集和验证集划分,可直接对接到YOLOv5训练流程。目前已有611人学习下载。数据集采用640×640分辨率的RGB图像,并完成mosaic增强,提升小目标和复杂背景下的检测效果;使用者无需额外处理标注格式,即可开始训练。可视化脚本支持随机读取一张图片并绘制边界框,输出结果保存至当前目录,便于快速检验标签正确性或用于项目汇报展示。无论是目标检测入门实践,还是工地安全监测项目开发,都可以基于该数据集快速搭建训练管线。
1. 建筑工地安全隐患检测数据集:一份能直接开跑的YOLOV5格式数据长什么样
安全员每天在工地上来回巡检,拍回来的照片动辄上百张,逐张翻看有没有人没戴安全帽、有没有人越过基坑边缘,眼睛很快就疲劳了。与其靠肉眼硬撑,不如让目标检测模型替人先过一遍。目标检测数据集(YOLOV5目录格式)这份材料,就是为这类“智慧工地”场景准备的标准训练原料:建筑工地安全隐患检测,10个风险类别,目录与标签文件按YOLOV5训练脚本的习惯排好,拿到手就能开始跑train.py,不必先折腾格式转换。
这份数据的价值不只是“有标注框”这么简单。10个类别覆盖了工地最常见的三块风险:个人防护装备是否佩戴到位(安全帽、反光衣)、危险行为(吸烟、使用手机)、以及机械设备与明火(车辆、挖掘机、电焊火源)。适合两类人用:一类是做智慧工地、施工安全告警系统的工程师,需要一份起步数据来验证方案;另一类是刚接触YOLOv5、想用自己的数据跑通完整训练流程的初学者。下面我们从数据组织方式讲起,一路讲到训练参数和踩坑点,最后给出让这份数据持续增值的实践做法。
2. 从采集照片到YOLO标签:10类隐患怎么标、目录骨架怎么搭
2.1 10个类别怎么划分:别把“人”和“违规行为”混在一个框里
拿到工地照片后的第一个决策是类别表。常见的方案是把“人”作为一个基础类,把人身上的防护装备和危险行为拆成独立类,框可以重叠。这样做的原因是推理阶段你需要知道两件事:现场有多少人、其中有多少人违规。下面的10类划分是我在类似项目里常用的方案,也能对应到常见的工地安全巡检条款:
0: person # 普通人员(含佩戴/未佩戴完整装备的个体) 1: helmet # 安全帽(佩戴状态) 2: no-helmet # 未佩戴安全帽(头部区域) 3: vest # 反光衣(穿戴状态) 4: no-vest # 未穿戴反光衣(躯干区域) 5: phone # 低头看手机 6: smoking # 吸烟(手部+烟雾区域) 7: truck # 工程运输车辆 8: excavator # 挖掘机/工程机械 9: fire # 明火/电焊火花注意几个易混点。第一,helmet和no-helmet标注的是同一类目标的两种状态,标注员最容易犯的错是把“正确佩戴”和“未佩戴”的边界划错,比如把安全帽抓在手里的工人标成helmet。第二,vest与no-vest的判定以“是否穿在身上”为准,拿在手上或搭在肩上的不算穿戴。第三,smoking的框建议包含手部与烟雾,只标脸容易漏掉烟头火花。第四,fire不单指火焰,电焊的弧光、切割产生的火花都算。每个框要贴合目标,不要为省事把整个工人身体圈进去替代头部或躯干框。
类别表一旦确定,就不要频繁增删。因为YOLO的类别ID是线性索引,训练中途插入新类会导致已有的标签文件全部错位,重标代价极高。如果你的场景确实需要新增类别,我一般会单独建一个新数据集目录,重新走一遍标注与转换,而不是在原标签上硬改ID。
2.2 YOLOV5标签目录骨架:images 和 labels 必须一一对应
YOLOV5的官方训练脚本对数据目录有明确的约定,必须先按这个骨架排布:
dataset/ ├── images/ │ ├── train/ # 训练图像 │ │ ├── 0001.jpg │ │ └── 0002.jpg │ └── val/ # 验证图像 │ ├── 0101.jpg │ └── 0102.jpg ├── labels/ │ ├── train/ # 训练标签 │ │ ├── 0001.txt │ │ └── 0002.txt │ └── val/ # 验证标签 │ ├── 0101.jpg │ └── 0102.jpg # 注意:labels目录里是txt,这里仅示意文件名对应核心规则只有一条:images与labels下同名文件必须成对出现,且images/train/0001.jpg只能对应labels/train/0001.txt,不能跨目录找。每个txt文件里存放该图所有目标的标注,每行格式为:
class_id x_center y_center width height其中坐标全部归一化到0~1范围。例如一张640x480的图上,某个未戴安全帽的人头部框中心在(320, 120),宽120、高100像素,对应txt行就是:
2 0.5 0.25 0.1875 0.2083这里2是no-helmet的类别ID;0.5是320除以640的x中心坐标;0.25是120除以480的y中心坐标;0.1875和0.2083分别是宽高归一化后的比值。注意YOLO格式用的是中心点坐标加宽高,不是左上角和右下角,从VOC格式转换时最容易在这里翻车。
2.3 把散图整理成YOLOV5目录:一段可复用的构建脚本
如果你手里的原始文件是“一个文件夹里几百张jpg,外加一份VOC或COCO标注文件”,最常见的做法是先读标注,把图像按8:2切分到train和val,再根据标注内容生成对应的txt。下面给出一个最小化的Python脚本,功能是把散落的图像按比例切分并建好空标签目录,适合在正式转换前先用它搭骨架:
import os import random import shutil from pathlib import Path # 配置文件 raw_image_dir = Path("./raw_images") # 原始图片所在目录 dataset_root = Path("./construction_safety") # 输出的数据集根目录 train_ratio = 0.8 # 训练集占比 random.seed(42) # 1. 创建YOLOV5目录骨架 for split in ["train", "val"]: (dataset_root / "images" / split).mkdir(parents=True, exist_ok=True) (dataset_root / "labels" / split).mkdir(parents=True, exist_ok=True) # 2. 收集所有图片,按比例切分 images = list(raw_image_dir.iterdir()) random.shuffle(images) train_count = int(len(images) * train_ratio) for idx, img_path in enumerate(images): split = "train" if idx < train_count else "val" dst_img = dataset_root / "images" / split / img_path.name shutil.copy(img_path, dst_img) # 3. 生成空的同名标签文件(等待标注工具填充) txt_name = img_path.stem + ".txt" dst_txt = dataset_root / "labels" / split / txt_name dst_txt.touch(exist_ok=True) print(f"Images: train={train_count}, val={len(images) - train_count}") print("Empty labels created. Now annotate them with LabelImg/CVAT.")这个脚本的逻辑分三层:第一层创建images/train、images/val、labels/train、labels/val四个目录;第二层按8:2比例随机切分图片文件并复制过去;第三层为每张图创建一个同名空txt文件,确保后续标注时不会有“图有标无影”或“标签找不到图”的问题。切分时用了random.seed(42)固定随机种子,这样多次运行结果一致,方便复现。如果原始数据来自同一个视频的连续帧,记得不要用这种全局随机切分,而是要按视频片段分组,否则验证集泄露会让你部署后掉点,这一点在第4章专门讲。
2.4 标注工具的选型:LabelImg适合小批、CVAT适合团队
数据量在几百张以内时,我一般用LabelImg手动标注,它可以直接导出YOLO格式的txt文件。操作路径是:打开图片后先选择类别,再画框,保存时格式选YOLO。注意LabelImg默认保存的是绝对路径的JPEGImages列表文件,如果你把图片移动了位置,重新打开时对应的txt文件路径会失效,所以建议把图片先按上面的骨架放好,再在LabelImg里打开images/train目录,让标注文件直接落在对应的labels/train目录下。当数据量到几千张或多人协作标注时,推荐换用CVAT或Roboflow。CVAT导出YOLO格式会自动帮你把标签文件按文件名配对,但它导出的zip包里是obj_train_data目录结构,仍需要按2.2节的骨架重新整理一次。
3. 把数据集喂给训练脚本:数据yaml、超参数与验证指标
3.1 手写 dataset.yaml:path写对,否则训练脚本找不到数据
YOLOV5通过一个yaml文件描述数据集位置和类别映射,文件本身没有任何“魔法字段”,全部是明文配置。以下是一份可直接使用的配置:
path: /home/user/construction_safety # 数据集绝对路径 train: images/train # 相对path的训练图目录 val: images/val # 相对path的验证图目录 test: images/test # 可选,测试图目录 nc: 10 names: 0: person 1: helmet 2: no-helmet 3: vest 4: no-vest 5: phone 6: smoking 7: truck 8: excavator 9: firepath字段的写法值得说清楚。YOLOV5在train.py内部会用Path(data["path"])拼接train和val的相对路径。如果你把train写成绝对路径/home/user/construction_safety/images/train,那么path字段可以留空;反过来如果你的数据目录就在项目的datasets子目录里,也可以把path写成相对路径,比如path: ./datasets。我在实际使用中更推荐path写绝对路径、train和val写相对路径,因为训练脚本会重置工作目录,相对路径一旦和预期位置不一致就会报AssertionError: train: labels not found之类的问题。nc必须与names列表实际长度一致,多写一个少写一个,损失函数计算类别数时就会对不上,训练结果会显得很奇怪,损失一直不降。
3.2 训练命令与超参数:从yolov5s起步、把imgsz和batch先定稳
准备好yaml后,训练命令比想象中简单:
cd yolov5 python train.py --data construction_safety.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --hyp data/hyps/hyp.scratch-low.yaml我通常第一次跑用yolov5s.pt作为预训练权重,原因很简单:s模型参数量适中,单张RTX 3060级别的显卡就能在batch 16下稳定训练,而且预训练权重来自COCO数据集,其中的person类与工地场景高度相关,迁移学习效果立竿见影。如果你换用yolov5n.pt,训练速度快但小目标检测能力会明显下降;换用yolov5l.pt则要关注显存占用,batch 16训练时约需12G以上显存,内存不足会直接OOM。
关键参数按我的经验设置如下:--img 640是输入图像边长。工地监控画面里的人脸小目标可能只有20x30像素,如果发现验证集上小目标漏检率很高,把img调到1280往往能救回来一批,但训练时间会变成约4倍。--batch 16在batch size对精度的影响上处于甜点区,小于8时训练不稳定,BN层的统计量波动大。--epochs 100对千张级别的数据集够用,再多容易过拟合。如果你不想手动调学习率,直接使用默认的hyp.scratch-low.yaml即可,里面已经定义了对工地场景友好的增强参数:mosaic: 1.0表示每张训练图都有概率进行马赛克增强,把四张图拼在一起训练,这对小目标检测很重要,因为拼图后小目标的数量和上下文多样性都会增加。如果显存不足导致mosaic时报错,可以在yaml里把mosaic: 0.5,或者直接关掉mosaic: 0.0。
3.3 验证阶段看什么:mAP之外更要看混淆矩阵和PR曲线
训练完成后,先用官方验证脚本看一眼整体效果:
python val.py --data construction_safety.yaml \ --weights runs/train/exp/weights/best.pt \ --img 640 \ --conf-thres 0.25 \ --iou-thres 0.5输出里会给出mAP@0.5、mAP@0.5:0.95、Precision、Recall这些指标。很多人只看mAP@0.5:0.95,但在工地场景里我更推荐打开runs/val目录下的confusion_matrix.png和PR_curve.png。混淆矩阵能直观看到类别之间的互相污染,比如helmet大量被预测成no-helmet,说明标注时对“是否戴正”的边界把握不一致。PR曲线能看阈值设置对精度与召回的影响:如果你做的是安全告警系统,漏报比误报更严重,就应该牺牲一部分precision把conf-thres降到0.1以下,把召回率拉高。这一点在后续部署时再具体调整。
4. 工地场景的5个避坑点:小目标、类别不平衡与数据泄露
4.1 小目标漏检:远处工人只有二三十像素,模型直接当背景
现象:训练时loss降得很漂亮,mAP@0.5超过0.9,但把模型部署到新工地后,离摄像头10米外的工人几乎全部漏检,尤其是no-helmet类几乎没有输出。
原因:工地监控拍摄区域大,人员目标在画面中占比很小。YOLOV5s的骨干网络经过5次下采样,最终特征图只有输入图像的1/32,一个20像素宽的目标在640x640输入下只占约1个特征点,信息被卷积层反复削弱后基本不可判别。训练集里如果正样本以大目标为主,模型就不会学到小目标的特征。
解决:优先把--img从640提高到1280,这时候同样20像素的小目标在输入图像中的占比翻倍,特征图上的响应从1个像素变成4个像素。如果显存不够用1280,可以先把原图切块,比如把一张1920x1080的监控图切成3块640x640的重叠区域,训练和推理都按切块做,检测完再把框映射回原图。另外开启hyp.scratch-low.yaml里的mosaic增强也能间接帮到小目标,因为拼图后目标在图中出现的尺寸更丰富,模型见过的尺度范围更广。推理侧建议用SAHI这类切片推理框架直接替换detect.py的推理逻辑,它能把大图适当地滑窗检测再合并,工程改动量最小。
4.2 类别失衡:person样本几千个,smoking和fire只有几十个
现象:训练结果是person类的recall有0.99,phone、smoking的recall只有0.3,但总mAP看起来还凑合,因为权重占比大的类别把整体分数拉上去了。
原因:工地现场安全管理人员出镜频率极高,而吸烟、看手机这些行为在合规工地上本来就是少数事件,样本数量天然悬殊。YOLO的损失函数按类别独立计算BCEWithLogitsLoss,少数类别的梯度贡献小,容易被多数类别淹没。
解决:先统计各类别数量,用脚本算一算每个类别的框数。如果比例超过1:10,两件事必须做:一是把smoking、fire这些少数类别的样本复制增强,不只是简单复制图像,而是复制图像并做随机的亮度、对比度、翻转变换,让同一帧图像产生多个变体;二是在hyp里调整类别权重,最低效的做法是直接修改CLS_LOSS的权重,更稳妥的办法是使用--weights里的类别再平衡选项,或者在损失函数层面给少数类别乘以一个大于1的系数。我的习惯是先补数据再调权重,数据增强解决不了时再动损失函数,否则模型会对少数类别过拟合,验证集上分数虚高,新工地上一测就原形毕露。
4.3 验证集泄露:同一段视频的连续帧被分进train和val
现象:训练时验证集的mAP一直很高,loss也很低,但模型换到另一个工地项目后性能骤降,像是换了一双眼睛。
原因:如果数据来源是工地摄像头连续视频抽帧,相邻帧之间背景高度相似,目标姿态也只有微小差别。全局随机切分时,第10帧进了训练集,第11帧可能就进了验证集,模型其实已经“见过”验证集里的背景和目标姿态,不是真正的泛化能力。
解决:按视频片段划分而不是按单帧随机划分。在2.3节的脚本里,先按视频源分组,每组内部顺序排列,再把整个组划进train或val。这样验证集的背景分布与训练集有本质差异,mAP才真实反映了模型在新工地的表现。如果原始数据是独立拍摄的照片,也要检查是否存在连续连拍的干扰,可以人工抽样看验证集的背景多样性。
4.4 标注框越界与坐标归一化错误:txt里的数字看起来都没问题,但训练就是报错或loss异常
现象:数据yaml配好后启动训练,程序报AssertionError: Label class 6 exceeds nc=10或者loss在一开始就巨大无比,训练损失不收敛。
原因:多半是标注文件里出现了两个问题:一是某些类别的ID超过了nc范围,比如类别表只有10类,但txt里出现了10或更大的数字,这通常来自标注工具导出时类名映射错位;二是坐标数值不在0~1之间,例如从VOC的绝对坐标转YOLO格式时忘了除以图像宽高,结果x_center写成了0.5的正数但width写成了大于1的数。YOLO训练脚本内部会跳过有问题的标注并打日志,但如果问题样本过多,训练集的有效样本就打了折扣,验证集上的表现会异常。
解决:训练前写一个校验脚本,逐行检查所有txt:类别ID必须小于nc,坐标与宽高必须在0到1之间,宽高不为0。发现异常行则打印所在文件名与具体行内容,手动修正后重新校验。这类问题属于“一回生二回熟”的坑,我在每次标注格式转换后都会强制跑一次校验,不通过不进训练流程,给后面省下的时间远超写脚本花掉的三十分钟。
4.5 光照与天气迁移:白天扬尘、傍晚逆光,色调一变模型就失灵
现象:训练数据集中在晴天上午拍摄,模型一到傍晚或阴天就频繁误检,把塔吊阴影当成工人,把反光衣漏成普通衣服。
原因:目标检测模型对颜色和纹理分布很敏感,反光衣在晴天高光场景下呈现鲜黄色,到阴天低照度场景下变成灰黄色,特征变化超出模型见过的分布范围。
解决:数据采集时要有意识地覆盖不同时段和天气,每批数据里让白天、傍晚、阴天、逆光各占一定比例。如果条件不允许补拍,在训练时把hyp.scratch-low.yaml里的hsv_h、hsv_s、hsv_v增强幅度调大,默认值分别是0.015、0.7、0.4,可以把色调扰动稍微提高到0.03左右,让模型对光照变化更鲁棒。更彻底的做法是手动对图像做曝光和色温增强再灌入训练集,但这属于离线数据增强,会成倍扩大数据集存储,一般只用来补少数类样本。
5. 让数据集的复用价值更高:难样本挖掘与增量标注循环
数据集建好并训完第一版模型后,工作并没有结束。一个只在静态数据集上训完就收工的项目,到实际工地大概率会被真实场景教做人。我更推荐的做法是把这份数据集当成“种子”,再配合难样本挖掘让它持续长大,这也是智慧工地项目里让模型越用越准的常见路线。
具体做法是:用当前best.pt对一批新采集的工地监控图像做批量推理,把置信度落在0.2到0.5之间的检测框视为“模型拿不准”的样本,手动筛选这些图优先补充到数据集里。置信度低说明目标外观与训练分布差距大,正是模型最需要“补课”的地方。在标注工具里可以先用模型的输出做预标注,人工只需修正框的位置和类别,一张图的标注时间能从2分钟压缩到20秒。每补一批数据,就重新跑一次第3章的训练流程,迭代三五轮后,模型在复杂背景下的表现会有肉眼可见的提升。
我还保留着一个习惯:每次训练结束,把runs/val下被漏检的样本按类别建立子目录,积累起来做成“困难样本图册”。部署到新工地前,先在困难样本图册上跑一遍推理,比对recall和每类的平均置信度,能提前暴露模型对那个工地的适应度问题,而不是等上了现场才发现漏报。这份建筑工地安全隐患检测数据集(YOLOV5目录格式)用好了就是项目里最核心的资产,不要指望一步到位,把它当成可以持续治理的数据基线,比花精力反复调参要值得多。上面这些做法我都是自己踩过坑换来的,希望帮到你。
本文还有配套的精品资源,点击获取