基于YOLOv5的工地安全帽与危险区域识别系统实战 简介这是一套面向计算机视觉初学者与工程开发者的工地安全检测实战源码包围绕YOLOv5目标检测框架解决安全帽佩戴识别与禁入危险区域预警两类实际场景问题适合具备Python基础、希望从零跑通检测项目并迁移到自有数据集的读者。压缩包共61个文件、约22.32MB以22个py脚本为核心配合9个yaml模型与数据配置、11张jpg与5张png效果图、3个gif演示动图以及json标注、ui界面文件、md说明和权重下载脚本覆盖模型定义、数据配置、训练验证与可视化界面等模块。目前已有806人学习下载。资源不仅提供可运行的训练、验证与检测脚本还包含自定义数据集配置、可视化工具教程与界面程序读者可据此完成数据标注转换、模型训练调参、精度评估到实时检测的完整链路并理解工程目录组织方式为安全监控类项目落地提供可复用的参考。1. 工地安全帽与危险区域识别为什么 YOLOv5 仍是性价比最高的落地方案工地出入口的摄像头每天都在产生海量画面但真正需要安全员盯住的无非两件事谁没戴安全帽谁走进了塔吊回转半径、深基坑边缘这类禁入危险区域。靠人盯屏十分钟就走神靠传统图像处理光照一变、扬尘一起就集体翻车。基于 YOLOv5 目标检测做工地安全帽和禁入危险区域识别系统本质是把这两类目标交给一个模型同时检测再用简单的几何逻辑判断人员是否越界。它解决的是「实时、低成本、可私有化部署」的问题适合有 Python 基础、手头有几张工地现场图、想在一周内跑出可用 demo 的工程师。YOLOv5 源码结构清晰、训练脚本开箱即用配合自定义数据集从标注到推理的链路非常短这也是它在工地场景里被反复选用的原因。下面按「先跑通、再训练、后避坑」的顺序把整套方案拆开讲。2. 环境配置与 YOLOv5 源码跑通从零到第一张检测图2.1 选 YOLOv5 而不是 v8/v13 的现实理由工地安全帽检测属于典型的小目标、密集遮挡场景。YOLOv5 的 P3 小目标检测层在 640 输入下对 20×20 像素左右的安全帽响应稳定而 YOLOv8 虽然精度略高但依赖 ultralytics 新接口很多老工控机上的 CUDA 版本对不上。YOLOv13 训练成本更高对数据集规模要求也大工地项目往往只有几千张标注图用 v5s 或 v5m 反而更容易收敛。另一个现实因素是源码可读性YOLOv5 的models/yolo.py、utils/datasets.py结构直白改检测头、加注意力、换损失函数都方便遇到问题能直接定位。我一般建议先用 v5s 跑通全流程精度不够再换 v5m不要一上来就上大模型。2.2 环境配置的版本组合与验证命令环境配置是第一个玄学重灾区。CUDA、PyTorch、torchvision 三者版本必须对齐否则训练到一半报CUDA error: no kernel image is available。下面这套组合在 RTX 3060 和 树莓派5 上分别验证过工控机 Ubuntu 20.04 也稳定。# 创建独立环境避免污染系统 Python conda create -n yolov5_helmet python3.9 -y conda activate yolov5_helmet # PyTorch 与 CUDA 11.8 对齐这是目前兼容性最好的组合 pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cu118 # 克隆 YOLOv5 源码并安装依赖 git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt # 验证 GPU 是否可用输出 True 才算配置成功 python -c import torch; print(torch.cuda.is_available())逻辑说明先建 conda 环境隔离依赖再装与 CUDA 11.8 匹配的 PyTorch最后装 YOLOv5 依赖。参数上torch2.0.1对应torchvision0.15.2这是官方验证过的配对不要随意升级。验证命令必须返回True如果返回False先查nvidia-smi驱动版本再查 CUDA toolkit 是否装全。树莓派5 上则用 CPU 版 PyTorch推理速度约 2-3 FPS适合做边缘端轻量验证。2.3 用官方权重跑通第一张工地图在训练自己的数据集之前先用 COCO 预训练权重确认推理链路通畅。这一步能排除 80% 的环境问题。import torch # 加载 YOLOv5s 官方权重首次运行会自动下载 model torch.hub.load(ultralytics/yolov5, yolov5s, pretrainedTrue) # 设置置信度和 IoU 阈值工地场景建议置信度略低 model.conf 0.25 model.iou 0.45 # 对工地现场图推理图片路径换成你自己的 results model(site_test.jpg) results.save() # 结果保存在 runs/detect/exp 下逻辑说明torch.hub.load会拉取 YOLOv5 仓库并加载权重conf控制检出框的最低置信度iou控制 NMS 合并阈值。工地场景目标密集iou设 0.45 能减少重叠框被误删。如果这一步能正常输出带框图片说明环境、权重、推理链路全部打通可以进入数据准备阶段。若报Downloading卡住手动下载权重放到~/.cache/torch/hub/checkpoints/下即可。3. 工地数据集制作安全帽与危险区域标注的完整流程3.1 类别设计与标注规范数据集质量直接决定模型上限。工地安全帽检测常见类别是helmet戴帽、head未戴帽、person人员整体危险区域则单独标danger_zone。这里有个血泪经验不要把「未戴帽」标成no_helmet然后指望模型区分因为未戴帽的头部和戴帽的头部在低分辨率下差异极小模型容易把两者混为一谈。更稳的做法是标head表示裸露头部标helmet表示安全帽推理时用「检测到 head 且该 head 与 person 的 IoU 高」来判定未戴帽。危险区域用多边形标注训练时转成外接矩形推理时再用多边形做精确越界判断。标注工具用 labelImg 或 X-AnyLabeling 都行导出 YOLO 格式。每张图对应一个.txt每行格式为class_id x_center y_center width height全部归一化到 0-1。标注时注意安全帽被遮挡超过 50% 的不要标否则模型学到的是遮挡特征而非安全帽特征危险区域边界要贴着实际物理边界不要留太多余量。3.2 数据集目录结构与 data.yaml 配置YOLOv5 要求固定的目录结构配错路径是训练启动失败的头号原因。helmet_dataset/ ├── images/ │ ├── train/ # 训练图约 80% │ ├── val/ # 验证图约 20% │ └── test/ # 测试图可选 ├── labels/ │ ├── train/ # 与训练图同名的 txt │ ├── val/ │ └── test/ └── data.yamldata.yaml内容如下路径建议写绝对路径避免相对路径在不同工作目录下解析错误。# 工地安全帽与危险区域数据集配置 path: /home/user/helmet_dataset # 数据集根目录 train: images/train # 训练图相对路径 val: images/val # 验证图相对路径 # 类别数安全帽场景通常 3-4 类 nc: 4 names: [helmet, head, person, danger_zone]逻辑说明path是根目录train和val是相对path的子路径。nc必须等于names长度否则训练时报维度不匹配。类别顺序要和标注时的class_id一致改顺序等于让模型重新学。如果验证集 loss 一直不降先检查val路径下图片和标签是否一一对应缺标签的图会被跳过但不报错导致实际验证集比预期小。3.3 数据增强参数怎么设才不翻车YOLOv5 默认开启 mosaic、HSV、翻转等增强。工地场景要针对性调整HSV 增强可以调大因为工地光照从清晨到黄昏变化剧烈上下翻转要关掉因为安全帽永远在人的上方翻转后模型会学到错误的空间关系mosaic 保留能提升小目标检测。# 在 data.yaml 同级或训练命令中覆盖增强参数 hsv_h: 0.015 # 色调增强默认值工地场景可保持 hsv_s: 0.7 # 饱和度增强调大应对扬尘导致的褪色 hsv_v: 0.4 # 亮度增强调大应对逆光和阴影 flipud: 0.0 # 关闭上下翻转安全帽有固定空间位置 fliplr: 0.5 # 保留左右翻转 mosaic: 1.0 # 保留 mosaic提升小目标 scale: 0.5 # 缩放增强模拟不同距离逻辑说明hsv_s和hsv_v调大是为了让模型对工地常见的灰蒙、逆光鲁棒。flipud0.0是关键安全帽检测依赖「帽在人头上方」这一先验上下翻转会破坏它。mosaic1.0让四张图拼接小目标出现频率提升对安全帽这种小目标很有效。如果数据集本身已经很大超过 1 万张可以把mosaic降到 0.5 加快收敛。4. 训练自己的数据集命令、参数与收敛判断4.1 训练命令与关键参数逐项说明YOLOv5 训练入口是train.py下面这条命令是我在工地项目里反复用的基线配置。python train.py \ --data helmet_dataset/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 150 \ --device 0 \ --workers 8 \ --project runs/train \ --name helmet_v5s \ --patience 30 \ --save-period 10逻辑说明--data指向数据集配置--weights用官方预训练权重做迁移学习比从头训练收敛快 3-5 倍--img 640是输入分辨率工地小目标多可以试 800 但显存翻倍--batch 16在 8G 显存下安全显存大可加到 32--epochs 150配合--patience 3030 轮验证集无提升就早停避免过拟合--workers 8是数据加载线程CPU 核少就降到 4--save-period 10每 10 轮存一次权重防止训练中断丢进度。如果报CUDA out of memory优先降batch再降img。4.2 训练过程看什么指标训练日志里重点看三列box_loss、obj_loss、mAP0.5。box_loss下降说明定位在变准obj_loss下降说明目标存在性判断在变好mAP0.5是综合指标。正常情况前 10 轮 loss 快速下降30 轮后趋于平缓。如果box_loss震荡不降检查标注框是否有大量越界或宽高为 0如果mAP卡在 0.3 以下大概率是类别不平衡安全帽样本远多于危险区域样本需要给危险区域类别加权或补充样本。# 训练结束后用验证集跑一次评估输出各类别 AP import torch model torch.hub.load(ultralytics/yolov5, custom, pathruns/train/helmet_v5s/weights/best.pt) model.val(datahelmet_dataset/data.yaml, img640, batch16)逻辑说明best.pt是验证集最优权重val会输出每个类别的 Precision、Recall、mAP。重点看danger_zone的 AP如果明显低于helmet说明危险区域样本太少或标注不一致。这时不要盲目加轮数先补 200-300 张危险区域图再训。4.3 危险区域越界判断的逻辑实现检测出person和danger_zone后需要判断人员是否进入危险区域。简单用矩形 IoU 会误判因为人站在区域边缘但没进去也会重叠。更稳的做法是用检测框底部中心点是否落在危险区域多边形内。import cv2 import numpy as np def is_intrusion(person_box, zone_polygon): 判断人员是否越界取检测框底部中心点判断是否在多边形内 x1, y1, x2, y2 person_box # 底部中心点比框中心更贴近脚部实际位置 foot_point ((x1 x2) / 2, y2) # cv2.pointPolygonTest 返回正数表示在多边形内 result cv2.pointPolygonTest(zone_polygon, foot_point, False) return result 0 # zone_polygon 是 numpy 数组形如 [[x1,y1],[x2,y2],...] zone np.array([[100, 200], [400, 200], [400, 500], [100, 500]], np.int32) person [150, 300, 250, 480] print(is_intrusion(person, zone)) # True 表示越界逻辑说明foot_point取检测框底边中点因为人的脚部位置才代表实际站立点用框中心会把「人站在区域外但身体前倾」误判为越界。cv2.pointPolygonTest的第三个参数False表示只判断内外不返回距离速度快。危险区域多边形在标定时就存好推理时直接读取不要每帧重新计算。如果现场摄像头有俯仰角多边形要做透视校正否则近处区域会被低估。5. 避坑与排查工地场景里最容易翻车的五件事5.1 现象模型把白色安全帽识别成 head漏检率高原因训练集里白色安全帽样本少且白色在强光下过曝特征被削弱。解决补充不同颜色安全帽样本训练时把hsv_v调到 0.5 以上模拟过曝推理时对helmet类别置信度阈值单独降到 0.2宁可多检不可漏检。5.2 现象危险区域误报频繁人明明没进去却报警原因用矩形框做越界判断人在区域外但检测框与区域框重叠。解决改用底部中心点加多边形判断如 4.3 节代码。同时把危险区域多边形向内收缩 10-20 像素留出安全余量。5.3 现象训练 loss 正常下降但验证集 mAP 始终低于 0.4原因训练集和验证集分布不一致比如训练集全是白天图验证集混入夜间图。解决按光照条件分层抽样确保训练集和验证集都覆盖白天、黄昏、夜间。如果夜间样本太少用 HSV 增强模拟夜间或单独训一个夜间模型做模型集成。5.4 现象树莓派5 上推理只有 1-2 FPS达不到实时原因CPU 推理 YOLOv5s 本身慢且未做模型量化。解决用export.py导出 ONNX 或 NCNN 格式NCNN 在 ARM 上优化最好能到 5-8 FPS。命令为python export.py --weights best.pt --include ncnn再用 ncnn 的 Python 接口推理。如果还慢换 YOLOv5n 轻量模型精度降 3-5 个点但速度翻倍。5.5 现象训练到一半报DataLoader worker exited unexpectedly原因--workers设太大内存不足被系统 kill。解决把--workers降到 2 或 00 表示主进程加载数据慢但不崩。同时检查数据集图片是否有损坏文件用cv2.imread批量验证一遍损坏图直接删掉。6. 进阶技巧用测试时增强和类别加权把 mAP 再提 5 个点训练收敛后还有两个不重新训练就能提点的技巧。第一个是测试时增强TTA推理时对同一张图做翻转、缩放把多次结果融合。YOLOv5 内置了 TTA 接口一行代码开启。import torch model torch.hub.load(ultralytics/yolov5, custom, pathbest.pt) # 开启 TTA推理速度降为 1/3但 mAP 通常提升 2-4 个点 results model(site_test.jpg, augmentTrue) results.save()逻辑说明augmentTrue会对输入做多尺度、翻转增强再对预测框做 NMS 融合。代价是推理时间增加约 3 倍适合对实时性要求不高的离线巡检场景。如果现场要求 25 FPS不要开 TTA改用模型集成训一个 v5s 和一个 v5m推理时两个模型结果做加权框融合WBF精度提升更明显但显存占用翻倍。第二个技巧是类别加权损失。工地数据里danger_zone样本通常只有helmet的十分之一导致该类 AP 偏低。可以在data.yaml里给类别加权重或在train.py中修改compute_loss的类别损失系数。我一般用简单办法把danger_zone样本复制 3-5 份混入训练集配合mosaic增强效果立竿见影。注意不要复制验证集否则 mAP 虚高。最后一个习惯每次训练完把best.pt、data.yaml、训练命令、mAP 曲线截图存到一个带日期的文件夹里。工地项目经常要回溯「上一版为什么效果好」没有记录就只能重训浪费的是自己的时间。希望帮到你。本文还有配套的精品资源点击获取