
简介一套基于YOLOv5的智慧工地安全帽检测与危险区域识别系统毕业设计源码包面向计算机视觉、深度学习方向的本科毕业生、课程设计开发者及需要快速搭建目标检测项目的学习者。源码经本地编译验证可运行评审分98分内容经助教审定、难度适中覆盖模型训练、测试、危险区域检测、界面可视化等完整工程链路可直接作为毕业设计或期末大作业的参考实现。压缩包共60个文件、约22.3MB以Python脚本、YAML模型配置、界面UI文件、示例图片、JSON配置和Markdown说明文档为主PY文件对应训练、检测、可视化与工具模块YAML用于模型结构及数据配置图片展示检测效果GIF为操作演示整体目录清晰导入环境后可逐步复现YOLOv5的检测流程。已有101人学习下载资源内还附带可视化工具操作录屏、模型结构说明、目录树等资料便于对照理解网络结构与风险区域判定细节能有效节省环境搭建和代码阅读的时间适合深度学习项目入门及二次开发。1. 它到底解决了工地安全的什么问题工地安全帽佩戴监管靠人眼盯视频盯不住也盯不久。这个项目用 YOLOv5 同时做了两件事识别画面里有没有人戴安全帽以及人是否闯入划定的危险区域比如塔吊回转区、基坑边坡边缘。检测结果通过可视化界面直接展示也能输出报警。整套资源包含训练好的权重、标注数据、可运行的训练与检测脚本、PyQt 界面和文档说明对毕业设计或期末大作业来说最省事的地方在于可以跳过模型训练直接跑通推理但如果想改数据、调参数、加功能代码路径也是完整的。下面按“数据准备 → 模型训练 → 危险区域判定 → 界面集成 → 提交项目”这条线拆开讲重点说参数怎么设、坑在哪。2. 数据集与标注安全帽检测的第一步2.1 数据目录与 custom_data.yaml 的写法YOLOv5 的数据集结构很直接图片和标注文件放同一个目录或按 train/val 分好然后由一个 yaml 把路径和类别告诉训练脚本。项目里data/custom_data.yaml是核心入口整个训练流程都从它读取数据源。常见的数据目录长这样dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── custom_data.yamlcustom_data.yaml的典型写法path: ../dataset/ # 数据集根目录建议写绝对路径 train: images/train # 训练集图片目录 val: images/val # 验证集图片目录 nc: 3 # 类别数 names: [person, helmet, no_helmet] # 类别名顺序决定标注索引这个文件里的names顺序必须和每张图对应的 txt 标签索引一致。比如helmet排在第 1 位那么标注文件里戴安全帽的框就是1顺序一旦颠倒训练出的模型输出全是乱的。改自己的数据时一定要先改这里再检查标签。2.2 YOLO 标注格式与类别平衡每张图片对应一个同名 txt 文件每行内容是class center_x center_y width height坐标是归一化到 0~1 的小数。例如1 0.5 0.5 0.3 0.4表示一个安全帽框的中点位于图片中心附近。用 LabelImg 或 labelme 导出时记得切换成 YOLO 格式否则 train.py 加载阶段就会报格式错误。收集工地数据时最常见的问题是no_helmet样本太少因为“没戴安全帽”不是一个持续存在的静态特征。我一般会从两个方向补一是把戴帽正样本里的人物区域裁出来贴到没有帽子的背景上二是用几何变换生成难例。类别不平衡会直接影响召回率训练出的模型会对没戴帽子的工人视而不见所以宁可少一点总样本量也要保证每个类别都有足够的独立样本。2.3 数据增强与 gen_data项目里的gen_data模块可以生成带标注的合成样本这在手头没有真实工地监控数据时是能用的兜底方案。一个常见做法是拿公开 COCO 数据里 person 类裁剪出来贴到工地背景图上再按规则生成标注框。一个简单的色彩增强脚本import cv2 import numpy as np def color_aug(img, hsv_range(20, 40, 40)): hsv cv2.cvtColor(img, cv2.COLOR_BGR2HSV) hsv[:, :, 0] np.clip( hsv[:, :, 0] np.random.randint(-hsv_range[0], hsv_range[0]), 0, 179 ) hsv[:, :, 1] np.clip( hsv[:, :, 1] np.random.randint(-hsv_range[1], hsv_range[1]), 0, 255 ) hsv[:, :, 2] np.clip( hsv[:, :, 2] np.random.randint(-hsv_range[2], hsv_range[2]), 0, 255 ) return cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)这段代码在 HSV 空间对色相、饱和度、明度做随机扰动模拟不同天气和光线下的工地画面。做几何增强时要同步变换标注框坐标不能只动图不动框。提示生成合成数据后一定要用脚本扫一遍 txt 的坐标是否越界检查x w 1或y h 1的样本否则训练 loss 会异常。2.4 训练集与验证集划分训练前按 8:1:1 拆训练、验证、测试。需要注意的是同一监控点位拍的连续帧必须放在同一边否则验证集会混入帧间相似数据mAP 虚高部署到真实视频流时原形毕露。划分可以写一个简单脚本按文件名前缀分组而不是纯随机。3. YOLOv5 训练从预训练权重到自定义模型3.1 模型配置与选型models 目录里同时有yolov5s.yaml、yolov5m.yaml、yolov5l.yaml、custom_yolov5.yaml。s/m/l 是网络深度和宽度递增的版本。对工地上常见的 640x640 输入yolov5s 在 GTX 1080Ti 上能跑到 60 FPS 左右安全帽这种小目标够用yolov5m 适合需要更高精度的场景。custom_yolov5.yaml是在 yolov5s 基础上改过类别数的训练前确认nc: 3和数据集一致。yolov5 的网络结构主要由 BackboneCSP-Darknet、NeckPANet 特征金字塔和 Head三个尺度输出组成。三个输出层分别对应大、中、小目标安全帽属于小目标依赖浅层特征所以训练输入尺寸不要低于 640否则小目标特征提前丢失。不同版本对比如下配置depth_multiplewidth_multiple参数量适用场景yolov5s.yaml0.330.50约 7M实时性优先边缘设备yolov5m.yaml0.670.75约 21M精度优先服务端推理3.2 训练命令与参数说明训练入口是train.py推荐命令python train.py \ --data data/custom_data.yaml \ --cfg models/custom_yolov5.yaml \ --weights weights/yolov5s.pt \ --epochs 100 \ --batch-size 16 \ --img 640 \ --device 0--weights指定预训练权重能显著加快收敛--batch-size受显存限制8GB 以下用 8 或 16--img是训练分辨率直接决定小目标检出的下限--device 0表示用第一张 GPU没有 GPU 就改成cpu。训练阶段建议先冻结 backbone 再解冻。可以先用--freeze 10跑前 30 个 epoch后面再不加参数继续训练。这种方式能让模型先学会安全帽的通用特征再微调结构层降低灾难性遗忘风险。3.3 超参数与训练监控train.py里的--hyp可以指定超参数文件关键项包括lr0、lrf、warmup_epochs、mosaic、fliplr。对安全帽检测mosaic1.0能提升小目标性能因为四张图拼接后相当于增加了上下文label_smoothing设为0.05能减少过拟合。训练日志里重点看val mAP和val/obj_loss如果 mAP 连续 20 轮不涨就可以提前停掉不必等满 100 轮。训练完成后result 目录下会生成best.pt和last.pt。答辩演示只用best.ptlast.pt是中断恢复用的。3.4 训练跑飞的排查最常见的异常是 loss 变成 nan大概率是学习率太大或显存溢出先把lr0从 0.01 降到 0.001再检查 batch-size。另一个坑是数据集路径包含中文或空格YOLOv5 的 dataloader 对这类路径处理不友好全部改成英文路径。还有 labels 里 class id 超出nc-1会在加载时报错写个脚本遍历所有 txt 就能定位。4. 危险区域检测从目标框到区域判定4.1 区域判定的几何逻辑安全帽检测只解决“有没有戴”危险区域检测解决“人在哪、该不该靠近”。area_detect.py 的做法是在画面中标定一个多边形危险区域取每个 person 框底边中点作为落脚点判断该点是否落在多边形内。判断点是否在多边形内部最常用的是射线法def point_in_polygon(point, polygon): x, y point n len(polygon) inside False px, py polygon[0] for i in range(1, n 1): cx, cy polygon[i % n] if ((y py) ! (y cy)) and (x (cx - px) * (y - py) / (cy - py) px): inside not inside px, py cx, cy return inside这段代码遍历多边形每条边计算水平射线与边的交点数量奇数次则在内部偶数次在外部。注意输入坐标是像素坐标系x 向右、y 向下与数学坐标系相反代码里不需要额外翻转但标定时别搞混。4.2 检测框与区域联动当检测到 person 且其框底边中点进入危险区域时再判断这个人是否戴了安全帽。逻辑可以这样组织for *xyxy, conf, cls in detections: cx (xyxy[0] xyxy[2]) / 2 bottom_y xyxy[3] if point_in_polygon((cx, bottom_y), danger_zone) and cls 0: # cls 0 表示 person进一步判断该目标是否有 helmet if not has_helmet(person_crop): alert(fframe {frame_id}: 未戴安全帽进入危险区域)has_helmet可以复用当前模型对同一个 person 区域的局部预测也可以单独训练一个分类器。用底边中点而不是中心点是因为人站立时重心在脚底附近底边更接近实际地面位置误报会小很多这个细节对工程落地很关键。4.3 输出与报警项目里的area_output_1.jpg、area_output_2.jpg就是这种联动的可视化结果危险区域被画成半透明多边形违规目标框标红正常目标框标绿。对视频流可以直接往VideoWriter里写帧out.write(frame)需要真正报警时把 area_detect.py 的返回结果转成开关量接声光报警器或者走企业微信 webhook。随附源码到图片标注这一步是完整的接硬件只是把输出端替换掉。4.4 性能取舍area_detect.py 在检测循环里做多边形判断计算量几乎为零真正的瓶颈是模型推理。如果视频源是 30 FPS可以每 2 帧检测一次中间帧沿用上一帧结果这样危险区域报警的实时性不会明显下降GPU 占用能省一半。5. 可视化界面把检测结果变成可操作系统5.1 界面组成与文件结构UI目录下是 PyQt5 写的界面main_window.py负责主窗口逻辑main_window.ui是 Qt Designer 设计好的界面文件icon里放图标资源。visual_interface.py和detect_visual.py把模型推理封装成界面可调用的接口避免界面代码里堆一堆 torch 操作。界面主要功能包括打开图片/视频、实时显示检测结果、调整置信度和 IOU 阈值、选择模型文件。对毕设演示来说这几个功能足够支撑答辩时的操作展示。5.2 界面与推理线程的衔接PyQt 界面如果直接把推理放在主线程画面会卡死。常见做法是用 QThread 跑检测循环通过 signal 把结果传回主线程更新画面class InferThread(QThread): result_ready pyqtSignal(object) def run(self): while True: frame, dets model.detect_next() self.result_ready.emit((frame, dets))连接信号后主界面拿到的是带标注的帧和检测列表。不要在槽函数里再执行一次模型推理否则信号队列堵住界面一样卡。5.3 参数面板与联动界面里的滑块修改的是detect.py层的conf_thres和iou_thres。conf直接影响误报率工地上宁可多报也不能漏报一般调到 0.25 左右iou用于 NMS 去重保持 0.45 即可。调参后需要让线程重新读取新值否则滑块改了没反应这个连接关系要在 main_window.py 里核对清楚。5.4 源码集成方式requirements.txt列了 torch、opencv-python、PyQt5 等依赖。跑起来前先按文档建虚拟环境安装依赖再执行visual_interface.py启动界面。如果想把项目扩展成多路摄像头记得把视频 capture 的打开逻辑从构造函数里挪出来每路一个线程界面线程只做显示。6. 进阶从毕设到可提交项目的一些具体技巧6.1 用 detect_visual.py 做批量验证改完数据重新训练后不要只看 mAP拿一批现场视频逐帧跑观察漏检集中在哪些镜头角度。执行python detect_visual.py \ --source ../videos/test1.mp4 \ --weights runs/train/exp/weights/best.pt \ --conf 0.25输出目录里直接看到按帧画好框的结果图比盯着终端日志直观得多。批量验证时把视频切成 1 分钟一段方便定位问题帧。6.2 权重文件与代码版本匹配weights目录下的download_weights.sh用来拉取预训练权重。YOLOv5 不同 release 对权重文件的兼容性有细微差别anchor 计算方式也不完全一样用错版本会莫名掉点。答辩前把best.pt复制到本地演示现场不要去下载现场网络不可控这个坑值得提前堵住。6.3 几个常见报错的边界显存不够时把--batch-size调小到 8 或 4或者用--device cpu先验证代码逻辑。AttributeError多半是权重文件和模型配置不匹配检查 models 下的 yaml 是否被改过。OpenCV 打不开视频时先确认安装了 ffmpeg再重新安装 opencv-python。这些在答辩前都要跑通现场折腾非常浪费时间。6.4 让检测结果更可信的小改动在输出帧上同时画出置信度和报警原因比如“未戴安全帽 危险区域”不要只画一个框。保存结果图时把帧号和 conf 写进文件名答辩时翻文件就能讲清楚哪一帧触发了报警。另外在界面底部放一个实时统计区显示当前总人数、未戴帽人数、区域入侵次数三个数字比单张图更有说服力。演示时把 conf 显示出来比单纯画框更能证明系统在真实工作。本文还有配套的精品资源点击获取