ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

智慧工地安全检测:YOLO数据集构建与模型训练实战

智慧工地安全检测:YOLO数据集构建与模型训练实战 工地上的安全说到底靠两样东西一是现场管理人员的责任心二就是能24小时盯着现场的技术手段。这两年智慧工地项目铺得很快但凡跟安全相关的系统最核心的算法基本都是同一套——工人有没有戴安全帽、有没有穿反光衣临边洞口有没有防护这些场景靠的就是目标检测模型在撑。我手里这套自建的“施工安全设施检测数据集”一共10600张图全部按YOLO格式标注专门用来训练智慧工地场景下的安全巡检模型。前后花了小半年时间采集、清洗、标注、迭代踩了不少坑也积累了一些实打实的经验。这篇就把它拆开揉碎了讲清楚从数据构成、标注规范到训练落地、问题排查给准备入局智慧工地算法方向的朋友做个参考。1. 内容整体设计与思路拆解1.1 为什么选择YOLO框架做施工安全检测智慧工地场景下的目标检测和通用物体检测最大的区别在于它对实时性和部署成本极其敏感。一个工地摄像头动辄几十上百路后端推理服务器不可能每路都配一块高端显卡。去工地上看一圈就知道绝大多数项目用的还是普通的IPC网络摄像头画面分辨率从1080p到4K不等帧率普遍在15到25帧。要在这种硬件条件下做到实时告警模型必须在保证精度的同时把推理时延压到最低。YOLO系列恰恰是这个场景下最务实的解法。从早期的YOLOv5到后来的YOLOv8再到最新的YOLO11这个系列的模型在工程落地上的优势非常明显推理速度快、显存占用低、部署生态成熟支持ONNX、TensorRT、OpenVINO多种导出方式。我们实测过用YOLOv8s的权重在TensorRT FP16精度下跑1080p视频流单路推理时间大约能控制在5毫秒以内配合多路批处理一张消费级显卡比如RTX 4060可以轻松承担十几路视频流的实时分析任务。1.2 数据集构建的核心思路这套数据集立项时的目标很明确不做全品类的大而全而是聚焦“安全设施”这个垂直细分。为什么这么定因为施工安全检测看起来场景单一实际上细分下来水很深。先说类别设计。我们最终锁定了7个类别分别覆盖了人员个体防护和现场安全设施两个维度helmet安全帽。这是工地安全的第一道防线也是所有智慧工地项目里出现频率最高、算法要求最严的类别。vest反光衣安全背心。夜间施工和交通疏导场景下尤其重要。guardrail临边防护栏。基坑边、楼层边缘、楼梯口的防护栏杆。safety_net安全网。外架搭设的水平兜网和立面密目网。warning_sign安全警示牌。包括“注意安全”“当心触电”“禁止烟火”等各类警示标识。fire_extinguisher灭火器。临时动火作业点、材料库房等消防重点区域。electrical_box配电箱柜。临时用电设施通常要求箱门关闭上锁、设置警示标识。从模型训练的角度看这个类别组合的合理性在于每个类别在视觉特征上有足够强的区分度同时各自又有比较明显的类内差异——比如安全帽有红黄蓝白不同颜色反光衣有荧光绿和荧光橙两种主流色这恰好能逼着模型学到“形状和位置关系”而不是简单记住颜色特征泛化能力会更好。1.3 场景采集的覆盖策略数据集最忌讳的就是“看着数量挺多实际拍来拍去都是同一个场景”。10600张图听着不少如果不加控制地随便采模型训练出来换个工地就废。我们当时做了三个维度的场景拆分场景类型涵盖房建主体结构施工、市政道路施工、桥梁高架作业、厂房钢结构安装、装饰装修阶段等主要工地形态。不同施工阶段的安全设施分布差异很大——主体阶段全是外架安全网装修阶段则遍地是配电箱和灭火器。时间段覆盖早班、午间、黄昏、夜间四种光线条件。夜间是重难点因为我们要求模型在补光灯不足、只有现场照明的情况下依然能精准识别反光衣的反光条和安全帽的轮廓。气候条件晴天、阴天、小雨、雨后天晴地面积水反光、大风扬尘。特别强调一点工地现场一般不让带三脚架慢慢拍绝大多数素材都是手持抓拍和现场固定机位录制视频后抽帧得到的这反而让数据集自带运动模糊和轻微离焦的真实噪声对模型鲁棒性反而是加分项。2. 数据采集与标注规范2.1 采集设备与标注工具的选择采集设备这块我们没有刻意追求高成本方案主力设备就是两部手机一主一备加一台GoPro运动相机。手机负责日常巡检时随手抓拍GoPro固定在安全帽上做视角记录这样能拍到很多人工巡检时容易忽略的高处视角画面。另外也协调了项目上的监控室导出了一部分历史监控录像作为补充素材这部分对提升模型在低分辨率场景下的表现帮助很大。标注工具我们对比过LabelImg、Labelme、X-AnyLabeling和Roboflow最终主力用的是X-AnyLabeling。理由是它支持YOLO格式直接导出、内置了自动标注辅助模型可以用已有的YOLO权重做预标注人工只需要修正边界框而且对批量处理大量图片时的卡顿控制比较好。LabelImg功能稳定但效率偏低适合几百张的小项目Roboflow云端能力强但要付费且数据出境有顾虑不适合企业项目。2.2 标注规范与质量控制标注规范是整个数据集质量的核心。我见过太多团队在标注阶段图省事结果训练时发现框的位置偏了半个身位、该框的没框、不该框的框了一堆背景模型效果自然一塌糊涂。我们当时定了几条硬性规则目标可见面积小于原图的2%时不标注。这种极小目标即使标了模型也很难学到有效特征反而容易引入噪声。目标被遮挡超过50%时不标注。反光衣被安全网挡住大半、安全帽只露出个帽檐这类样本不要。但如果遮得不多、语义仍然明确比如安全帽露出一半以上则正常标注。边界框必须紧贴目标轮廓允许有1-2像素的容差但不允许为了省事把框拉得过大。这里特别提醒做人工复核的人安全帽的框应该紧贴帽檐和帽顶而不是连头带脖子一起框进去。同一个人既戴安全帽又穿反光衣时两个类别分别独立标注互不影响。这个在多人密集场景下容易漏标需要复核人员特别注意。标注流程上我们分了三个角色标注员、复核员、抽检员。标注员只负责按规范画框复核员对每一张图做二次确认抽检员每天随机抽10%的结果做终审发现错误率超过2%就退回重标。三轮下来标注质量基本稳定在可控范围内。2.3 YOLO格式目录结构最终交付的数据集按YOLO标准格式组织目录结构如下├── images │ ├── train │ │ ├── img_0001.jpg │ │ ├── img_0002.jpg │ │ └── ... │ ├── val │ │ ├── img_0021.jpg │ │ └── ... │ └── test │ ├── img_0031.jpg │ └── ... ├── labels │ ├── train │ │ ├── img_0001.txt │ │ ├── img_0002.txt │ │ └── ... │ ├── val │ │ ├── img_0021.txt │ │ └── ... │ └── test │ ├── img_0031.txt │ └── ... └── dataset.yaml标签文件每行对应一个目标格式是五个数字类别ID 中心点x坐标 中心点y坐标 框宽度 框高度所有坐标值统一归一化到0-1之间。比如一行0 0.532 0.418 0.126 0.138表示的是类别0helmet的一个目标中心点位于图像横向53.2%、纵向41.8%的位置框宽占图像宽度12.6%高占图像高度13.8%。dataset.yaml按需配置7个类别依次列出即可path: /data/smart_construction_safety train: images/train val: images/val test: images/test names: 0: helmet 1: vest 2: guardrail 3: safety_net 4: warning_sign 5: fire_extinguisher 6: electrical_box这里要特别提一句很多新手习惯把数据按8:1:1的比例粗暴切分但我们实际采用的是按场景维度切分——即不同工地、不同施工阶段的数据先分桶再按桶比例采样到训练集、验证集和测试集。这样做的好处是能最大限度避免“同一工地同一光线条件下的相似图片同时出现在训练集和测试集”带来的虚高指标测试成绩更接近真实部署效果。3. 模型训练与核心环节实现3.1 基于YOLOv8的训练配置模型骨架我们最终选用的是YOLOv8s。为什么不选更高的m版本或者l版本因为在实际部署场景里算力资源是硬约束而安全帽、反光衣这类目标属于中大尺度目标s模型的能力边界已经足够覆盖。我们用n版本试过一轮小目标漏检率偏高换m版本精度提升有限但推理延迟增加了将近80%s版本是当时综合性价比最优的选择。训练前先做数据增强策略。智慧工地场景有一个特点摄像头视角相对固定不会出现像自动驾驶那样的大角度旋转但现场的光照变化非常剧烈——上午顺光、中午顶光、下午逆光、夜间补光。所以增强策略的重点放在光照扰动和尺度抖动上而不是90度旋转、翻转这类强几何变换。我们最终的增强管线是马赛克增强mosaic开启probability1.0前50个epoch生效后关闭随机上下翻转probability0.2工地目标不会倒置翻转概率不宜过高曝光扰动设定在-15%到25%区间重点增加曝光不足方向的增强比例模拟阴天和夜间效果随机HSV扰动只扰动亮度和饱和度不动色调工地上安全帽颜色有管理规范色调漂移会让模型学到错误特征。训练超参数方面我们基于实测结果整理了一份推荐配置超参数推荐值说明输入分辨率640x640YOLO系列默认兼顾精度与速度batch size32单卡显存不够就16配合梯度累积epochs200前100轮mosaic开后100轮关mosaic精调初始学习率0.01配合warmup 3 epochs权重衰减0.0005防止过拟合数据集不大时尤其关键优化器SGDAdam收敛快但最终精度略逊于SGD类别损失权重统一1.0各类别样本量均衡无需加权训练命令用标准的YOLO CLI入口yolo detect train \ data/data/smart_construction_safety/dataset.yaml \ modelyolov8s.pt \ epochs200 imgsz640 batch32 device0,1 \ project/output/smart_safety \ nameyolov8s_safety \ augmentTrue \ hsv_h0.0 hsv_s0.4 hsv_v0.5需要说明的是这里没有从零初始化训练而是在COCO预训练权重yolov8s.pt基础上做迁移学习。安全帽、护栏这类目标虽然不在COCO的80个类别里但COCO预训练权重学到的底层视觉特征边缘、纹理、颜色分布是通用的迁移学习可以让模型更快收敛最终精度也更高。3.2 训练过程监控与关键指标观察训练过程中不能只盯着loss曲线看。YOLO的loss通常由三部分组成box回归损失box_loss、类别分类损失cls_loss、目标存在性损失dfl_loss。这三个loss的收敛趋势要分开观察——box_loss和dfl_loss下降较慢是正常现象但如果cls_loss在训练后期出现震荡大概率是学习率设置偏高或者个类别之间存在特征混淆。我习惯在训练过程中重点关注几个指标的变化mAP0.5IoU阈值0.5下的全类平均精度这是衡量“模型能不能大致框对目标”的指标工地告警场景下更关注这个值因为告警不要求像素级精确框出大概区域触发联动即可。mAP0.5:0.95严格IoU阈值下的平均精度用于衡量边界框的精细程度这个值偏低通常说明大量目标的预测框定位不准确俗称“框偏了”。每一类的AP分布安全帽类AP很高、反光衣类AP偏低是常见现象因为反光衣在远距离小目标场景下特征不明显需要针对性补充该类别的近景样本。下表是训练结束后在验证集上的指标快照YOLOv8s640分辨率RTX 3090上训练约4.2小时类别样本数精度Precision召回率RecallmAP0.5helmet41800.9320.9010.953vest32600.9150.8570.934guardrail13500.8730.8120.891safety_net9800.8450.7980.872warning_sign15200.9010.8620.917fire_extinguisher7600.8290.7740.852electrical_box11800.8860.8450.904整体132300.8830.8360.9063.3 模型轻量化与TensorRT部署训练完成后的模型需要经过一个导出环节才能进入实时推理管线。我们实际部署时没有直接用PyTorch权重文件而是经过了两步转换第一步导出ONNX中间格式。这一步的目的是脱离PyTorch运行时依赖同时为下一步做铺垫yolo export model/output/smart_safety/yolov8s_safety/weights/best.pt \ formatonnx dynamicFalse imgsz640 simplifyTrue第二步将ONNX转为TensorRT engine。这里的重点是动态shape问题——工地的视频流分辨率不统一有1080p也有720p转engine时必须固定输入尺寸为640x640长边缩放、短边填充才能在推理时规避动态shape带来的额外延迟。转换命令trtexec --onnxyolov8s_safety.onnx \ --saveEngineyolov8s_safety.engine \ --fp16 --minShapesimages:1x3x640x640 \ --optShapesimages:4x3x640x640 \ --maxShapesimages:8x3x640x640用FP16精度跑下来的实测数据单张640x640输入在RTX 4060上的推理延迟约3.2毫秒在Jetson Orin Nano上约9.8毫秒。这个速度应对单路视频流的实时分析绰绰有余如果做多路并发需要通过批处理batched inference来均摊开销。关于后处理还有一点需要提醒YOLOv8的输出解码和NMS非极大值抑制直接在TensorRT推理之后用CUDA kernel实现不要放到Python端处理。Python端的NMS在目标数量多的时候会拖慢整个推理管线我们曾经因为这个问题在20路视频流并发时出现明显的告警延迟把NMS下沉到C层之后问题迎刃而解。4. 常见问题与排查技巧实录4.1 数据集层面的典型问题问题一类别不均衡导致个别类效果差。灭火器和警示牌在工地上的数量天然就比安全帽少得多如果按原始分布去训练模型对少样本类的召回率会明显偏低。我们的做法是采集时定向补拍这少数类硬把每个类别的样本量拉到至少600张以上。但如果你的数据集已经采完数量无法再补充则优先考虑复制粘贴增强Copy-Paste Augmentation——把少数类目标用分割掩码抠出来随机粘贴到其他训练图上。这个手段对灭火器这类边界清晰的目标效果显著。问题二误标注和漏标注。质量再高的标注流程也难免有漏网之鱼。我们在训练一轮之后做了个“清洗闭环”用训练好的模型对训练集重新预测一遍把置信度低于0.3的检测结果全部捞出来做人工复核。这一步能发现大量被漏标的目标还能揪出标签类别写错的样本比如把灭火器标成了配电箱。问题三不同场景切换导致掉点。训练集里全是晴天素材模型一出场就遇到阴雨天气表现断崖式下跌。这个问题的根源是数据没覆盖目标场景的分布。我们的对策有两个一是训练时开启更激进的色彩增强特别是把饱和度和亮度往低里调二是部署前在新场景现场快速采集50到100张图做一次增量微调用少量数据就能把“域适应”问题基本解决。4.2 训练与推理阶段的典型问题问题一训练loss不降或者NaN。loss一直不降通常原因有两个一是归一化坐标出错了检查labels文件夹里的txt文件坐标值是否都落在0到1范围内二是类别ID和yaml里配置对不上比如yaml里类别总数写7但txt里出现了编号7越界。NaN问题大多和学习率有关初始学习率超过0.01时容易触发梯度爆炸把学习率降到0.001或0.005重新训练即可。还有一种情况是batch size过大导致显存溢出虽然不会报NaN但loss会剧烈震荡这时候减小batch size配合梯度累积是更稳的选择。问题二密集人群下重复告警和误报。工人扎堆进出工地时模型可能在同一人头上同时输出三四个安全帽框触发多次告警。这属于NMS阈值没调好。把NMS的IoU阈值从默认的0.45适当提高到0.6重复框会明显减少。如果还想更狠一点可以加一层空间去重逻辑——同一目标在连续N帧内已经告警过就不重复触发这个能在业务层面把告警风暴压下去。问题三摄像头视角偏高导致小目标漏检。工地球机通常架设在立杆顶端俯视视角下远处地面上的安全帽在画面中非常小可能只有十几个像素。这种极端小目标即使提升输入分辨率到1280也未必能解决。我们的工程化解法是双模型策略一路模型用640分辨率跑全图检测中近处目标另一路模型用1280分辨率跑画面下1/3区域的裁剪切片专门负责远处小目标。代价是GPU负载有所上升但效果确实立竿见影——小目标召回率从63%直接提升到了82%。4.3 一份补充的避坑清单不要直接在视频流上逐帧做推理。实际部署时建议采用“视频抽帧间隔检测动态ROI”的方式固定机位画面中很多区域比如天空、围墙外永远不可能出现安全目标提前用ROI遮罩过滤掉能节省约20%的推理开销。模型热更时不要直接覆盖engine文件。TensorRT的engine绑定显卡架构不同型号的显卡生成的文件不通用跨机器部署必须重新转换。安全帽检测最容易出错的是“手里拿着安全帽”的场景。模型会把工人手里提着的帽子也检测出来业务上要求只告警“未佩戴”这个单靠目标检测解决不了需要加上追踪逻辑判断安全帽位置是否在头部区域。这是一个典型的算法加工程思维的落地问题。5. 后续扩展方向这套数据集目前覆盖的是静态安全设施的识别但工地的安全管理还有大量值得挖掘的方向。我自己在后续项目中重点在推两个方向一是行为识别——工人翻越护栏、高处攀爬、禁区闯入等动作类违规单帧图片解决不了需要结合时序模型比如SlowFast或者基于检测结果的轨迹分析做更上层的行为理解。二是在数据集层面把标注从检测框延伸到实例分割掩码这样对安全网破损检测、防护栏变形评估等更细粒度的问题会有更好的支持。另外有一点值得说——目前这套数据集的图片主要来自华东地区的工地现场如果要在西北或华南的项目上部署建议提前针对当地工地的脚手架形式、反光衣款式差异做个评估及时补充采集数据做增量训练能省去后续很多返工成本。做智慧工地算法这段时间最大的感受是模型架构本身反而不难真正花时间和精力的地方全在数据细节和工程落地上。一套质量过硬的数据集加上贴合场景的工程调优往往比盲目堆模型参数量管用得多。这套数据集的构建过程不算轻松但如果它能帮你在智慧工地这条路上少走一些弯路那就值了。
返回列表