
简介面向计算机专业毕业设计与课程实践的YOLOv5安全帽检测项目整合了完整Python源码、训练好的模型权重、标注数据集与使用教程适合作为毕业设计、期末大作业或深度学习实战练习。压缩包共164个文件整体约44.74MB主要文件类型包括Python脚本、C/CUDA源文件、YAML/CMake配置、PyTorch权重(pt)、Markdown说明文档以及测试图片等覆盖从数据配置到模型部署的多个环节。项目经过严格调试解压后按说明即可完成环境搭建与检测演示目前已有240人学习下载。除直接加载权重进行推理外还提供TensorRT等相关C工程文件便于在服务器端加速推理配套数据集支持二次训练与验证教程清晰讲解训练流程和参数调整方法对正在做毕设或准备大作业的学生来说能够节省大量从零实现的时间快速获得可运行、可展示的完整方案。1. YOLOv5 安全帽检测一套能直接跑通的毕设级完整项目YOLOv5 安全帽检测是毕业设计和期末大作业里出现频率最高的深度学习题目之一工地场景真实、任务目标明确、模型可解释性也强。这套资源把训练代码、训练好的权重、标注后的数据集和图文教程打包在一起拿到手不需要再去 GitHub 东拼西凑照着走就能复现一条完整的「数据 → 训练 → 推理」链路。它适合两类人一类是做本科毕设、需要完整项目支撑论文和答辩的学生另一类是工作中要快速验证安全帽检测效果、想把模型接进图片或摄像头流程的工程师。我会按数据、环境、训练、避坑、推理的顺序把这份资源落地时真正会碰到的细节和坑全部拆开讲结尾给出可以直接照抄的验证步骤。2. 先搞懂数据安全帽数据集的目录结构与标注格式很多同学拿到资源第一件事就是敲 train.py结果训了两天才发现标注格式不对白白烧掉一个周末。深度学习项目里数据是地基安全帽检测尤其吃数据质量工地光线差、人员遮挡多、帽子相对画面占比小。这份资源里的数据集按 YOLO 格式组织和 VOC 那种 XML 标注完全不同动手训练之前必须先搞清楚目录组织和标签文件里每一行数字的含义。2.1 从 images 到 labelsYOLO 的 txt 标注到底长什么样解压数据集后典型目录结构是这样的safety-helmet/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 ├── labels/ │ ├── train/ # 与训练图片一一对应的标注 │ └── val/ └── classes.txt # 类别清单一行一个类images 和 labels 下同一张图的文件名完全一致图片是 0001.jpg标注就是 0001.txt只有扩展名不同。这个同名规则是 YOLO 系列读取数据时寻找对应关系的依据改错前缀、改了大小写或者把标签放错目录都会导致训练时报一堆 warning然后告诉你某张图没有标注。打开一个 txt 标注内容长这样0 0.512 0.467 0.213 0.318 1 0.130 0.802 0.138 0.094每行对应一个目标框共五个字段第一个是类别 id从 0 开始计数后面四个分别是目标框中心点 x、中心点 y、框宽 w、框高 h。关键点在于这四个坐标全都是相对图片宽高的比例值范围在 0 到 1 之间而不是像素值。举个例子一张 1920×1080 的图某行写的是0 0.500 0.500 0.100 0.200表示框中心在 (960, 540)宽 192 像素、高 216 像素。这个「归一化」约定是 YOLO 和 VOC 系标注最大的区别——VOC 的 XML 里写的是像素坐标从 VOC 转到 YOLO 时漏除以宽高是最常见的低级错误。classes.txt 里是类别名。市面流传最广的安全帽数据集普遍采用二类划分helmet戴了安全帽的头部和head没戴安全帽的头部模型输出就是一个二分类检测结果。想自定义多类别也可以改 names 列表和 nc 数量就行。资源里提供的是整理好的成品标注我一般会先写个十几行的脚本把标注画回原图抽查确认类别和框位置都对得上再进训练import cv2 img cv2.imread(images/train/0001.jpg) h, w img.shape[:2] with open(labels/train/0001.txt, r) as f: for line in f: cls, cx, cy, bw, bh map(float, line.split()) x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, str(int(cls)), (x1, y1 - 6), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite(check.jpg, img)这段脚本的核心是把归一化坐标乘以图片宽高还原成像素框再画回原图。注意 cx 是比例值而不是像素值换算时先减半再加宽高得到左上角和右下角如果直接拿 cx 当像素坐标用画出来的框会全部挤在图片左上角这也是新手第一次可视化翻车的高发点。画框抽查我建议至少看二十张图覆盖不同光线、不同人数、不同拍摄角度的样本确认没有错位再继续。2.2 训练前强制做一次数据体检先别急着训练。我在多个安全帽数据集上实际跑下来的经验是标注里多多少少会有空标签、越界坐标、类别 id 超出范围、同名图片缺失这类问题torch 训练时不会直接报错但模型会默默地学坏指标卡在半路还查不出原因。所以每次训练前我强制自己先跑一遍体检脚本import os import glob img_dir images/train lab_dir labels/train bad [] for txt in glob.glob(os.path.join(lab_dir, *.txt)): name os.path.splitext(os.path.basename(txt))[0] img_path os.path.join(img_dir, name .jpg) if not os.path.exists(img_path): bad.append((txt, 图片缺失)) with open(txt) as f: lines f.read().strip().splitlines() if not lines: bad.append((txt, 空标注)) continue for i, line in enumerate(lines): parts line.split() if len(parts) ! 5: bad.append((txt, f第{i}行字段数{len(parts)})) continue cls, cx, cy, bw, bh map(float, parts) if not (0 cx 1 and 0 cy 1): bad.append((txt, f第{i}行中心坐标越界)) if not (0 bw 1 and 0 bh 1): bad.append((txt, f第{i}行宽高越界)) print(问题文件数:, len(bad)) for item in bad: print(item)脚本逻辑很直接遍历 labels 下的每个 txt检查同名图片是否存在、文件是否为空、每行是不是五个字段、坐标有没有超出 [0,1]。任何一个条件不满足就记录下来。正常情况下跑完问题文件数应该为 0有问题的文件要么删掉、要么用标注工具重新修千万别带病训练。这个脚本可以顺手也跑一遍 val 目录验证集和训练集同样重要。除了脚本自动检查还要人工确认两件事。第一是类别平衡统计 helmet 和 head 两类目标框的数量占比如果悬殊比如 head 是 helmet 的三倍训练出来的模型对少样本那一类召回率会明显变差常见做法是给少样本类做复制增强或者后期把阈值单独调低来补偿from collections import Counter counter Counter() for txt in glob.glob(os.path.join(labels/train, *.txt)): with open(txt) as f: for line in f: cls line.split()[0] counter[cls] 1 print(counter) # 输出示例: Counter({0: 8230, 1: 2561})Class 0 对应 classes.txt 里第一行的 helmetClass 1 对应 head。看到这种明显不平衡时先想数据层面怎么补而不是一上来就调 anchor、调训练超参数——模型结构层面的折腾属于玄学数据分布才是确定性问题。第二是数据划分确认训练集和验证集不是在同一个工地、同一批人上取的否则验证集指标虚高答辩或真实场景一换就露馅。安全帽这种小目标密集的场景验证集不干净造成的误差比调参的影响大得多。提示数据体检脚本和画框脚本我在每个项目里都会保留成固定工具训练前强制跑一遍能省掉后面两三天排错的成本。3. 环境配置与模型训练从零跑通 YOLOv5环境配置是安全帽检测项目里拦住最多人的第一道坎。常见翻车姿势包括Python 版本对不上、torch 装成 CPU 版、CUDA 版本不匹配导致显卡识别不了。这套资源里的代码基于 YOLOv5 官方仓库环境搭建有标准路径按顺序走一般一次通过。3.1 conda 环境与依赖安装版本要对齐我一般会为每个深度学习项目单独建 conda 环境避免不同项目之间的包版本互相打架。安全帽检测依赖 torch、torchvision、opencv、numpy 这一套集中装进独立环境里最省心conda create -n yolov5 python3.9 -y conda activate yolov5 cd yolov5 # 进入资源里的代码目录 pip install -r requirements.txtPython 选 3.9 是经过验证的稳妥选择官方 release 对 3.7 到 3.10 都能跑但 3.9 踩到的依赖冲突最少。requirements.txt 会拉取 torch 和 torchvision这里有个关键坑如果机器有 NVIDIA 显卡默认 pip 源很可能装到 CPU 版 torch训练速度慢到怀疑人生。装完第一件事就是验证 GPU 是否可用python -c import torch; print(torch.__version__, torch.cuda.is_available())输出里 torch.cuda.is_available() 为 True 说明 GPU 可用为 False 时先跑nvidia-smi确认显卡驱动正常再按 CUDA 版本重新安装 GPU 版 torch。常见做法是走 PyTorch 官网给出的对应命令比如 CUDA 11.8 就装torch2.0.1cu118这一档用 conda 装也可以但下载源可能慢。没有 NVIDIA 显卡、只有 Apple Silicon 或者纯 CPU 的机器也能跑通训练和推理只是速度差一两个数量级新手验证流程用小数据集训练几十个 epoch 完全可以接受。显存方面4GB 这种低显存显卡上不要直接上大 batch 大模型后面的参数表里我会给出具体建议。3.2 data.yaml 与 train.py 参数说明训练前先在代码目录 data 文件夹下建一个 yaml 配置文件描述数据集路径和类别信息这是 YOLOv5 读取数据的唯一入口# data/safety-helmet.yaml train: dataset/images/train val: dataset/images/val nc: 2 names: [helmet, head]train 和 val 写的是相对代码目录的图片路径注意是图片路径不是标签路径训练时程序自动把 images 换成 labels 去找同名 txt。nc 是类别数量必须和 names 列表长度一致二类就写 2。如果扩展成按颜色细分安全帽的五类版本把 nc 改成 5、names 换成对应列表即可模型输出头会自动调整。数据配置没问题后训练命令长这样python train.py \ --weights yolov5s.pt \ --data data/safety-helmet.yaml \ --epochs 100 \ --batch-size 16 \ --imgsz 640 \ --device 0 \ --cache ram参数含义和对这个项目场景的取值建议列成表更直观参数含义本项目建议值--weights预训练权重yolov5s.pt--data数据集 yaml 路径data/safety-helmet.yaml--epochs训练轮数100收敛后可早停--batch-size每批图片数8164GB 显存用 4--imgsz训练输入分辨率640mAP 不够可试 960--cache图片缓存策略ram内存不足就别加--device显卡编号0--workers数据加载线程数24别用默认 8逐个说关键参数。--weights 是预训练权重yolov5s.pt 是官方在 COCO 上训好的骨架第一次运行自动下载到代码目录用它的原因是迁移学习——安全帽模型从头训要三百个 epoch 才能到合格线用预训练权重初始化一百个 epoch 就够了。--epochs 设 100 是安全帽这类中等任务的经验值验证集 mAP 通常在五六十个 epoch 后进入平台期。--batch-size 受显存约束最明显16 在 8GB 显存配 640 输入比较稳4GB 显存降到 8 甚至 4训练时间变长但能跑完。--imgsz 是训练分辨率640 是速度和精度平衡点安全帽目标偏小验证集 mAP 上不去时可以试 960显存占用会明显上涨。--cache ram 把图片缓存进内存加速读取内存小于 16GB 不建议开。YOLOv5 训练默认开启自动锚框聚类autoanchor会根据你的数据集重新计算 anchor 尺寸这是它比 YOLOv3 省心的地方不需要手工调。如果多次训练发现 mAP 波动大可以在命令里加--noautoanchor固定使用官方默认 anchor 再对比一次。官方还提供 yolov5s/m/l/x 四个尺度l 和 x 精度更高但更吃显存低显存机器老老实实从 s 起步毕设场景 s 的精度已经够用。训练开始后日志按实验名写进 runs/train/exp 目录最佳权重保存在 exp*/weights/best.ptlast.pt 是最后一个 epoch 的中间产物两者都要留好。判断训练好坏不要只盯 loss 曲线打开 results.png 看 mAP_0.5 和 mAP_0.5:0.95 两条曲线安全帽二类任务 mAP_0.5 到 0.85 以上算合格。如果训练时 loss 反复震荡不收敛先回第 2 章做数据体检九成是数据问题而不是超参数问题。4. 训练与部署避坑五次翻车记录和对应解法这一章写的是我在安全帽检测项目里真实踩过的坑按「现象 → 原因 → 解决」记录每一条都花过完整的一到两天排查。提前把这些雷避开你省下来的时间足够再训两轮模型。下面的排查顺序也重要先查数据、再看显存、最后才怀疑模型结构顺序反了容易把时间花在和玄学较劲上。4.1 训练 Loss 不降、mAP 卡在 0.2 附近现象训练了五六十个 epochbox_loss 和 obj_loss 几乎不下降验证集 mAP_0.5 一直在 0.2 上下晃换更大的模型也一样。原因最普遍的是数据没清洗标签坐标越界、类别 id 错位让模型学到大量噪声其次是 train 和 val 划分不当两边图片内容高度重合模型其实没学到泛化能力。解决先跑第 2.2 节的体检脚本清理标签再用画框脚本抽查关键样本随后重新按「同一个工地场景只进一边」的原则划分数据最后才考虑调 --epochs 和 --batch-size。按这个顺序处理mAP 基本都能救回来我见过最夸张的一次是标签里混进了 VOC 像素坐标修完后 mAP 从 0.2 直接跳到 0.7。4.2 CUDA out of memory现象训练启动后跑到一半报 RuntimeError: CUDA out of memory或者一开 --cache 直接闪退进程被杀。原因batch-size 和输入分辨率组合超过显存容量--cache ram 实际是把图片缓存进内存内存不足时会反过来拖垮系统--workers 默认 8 在显存本来就不够的机器上也会加剧峰值占用。解决把 --batch-size 降到 8 或 4--imgsz 保持 640 或降到 512低显存机器直接去掉 --cache 参数--workers 设为 2。这组配置在 4GB 显存上能跑通代价是每个 epoch 时间变长但对毕设规模的数据集来说完全可以接受。4.3 普通帽子被识别成安全帽现象明黄色安全帽检测很准但鸭舌帽、草帽、工地上的布帽子大量误报精度指标虚高一放到真实视频流里告警满天飞。原因数据集里几乎没有「普通帽子」这类负样本模型没见过的东西会就近归到视觉相似的类别里这是目标检测里典型的开集误检。解决收集几百张含普通帽子的工地照片不带任何标注直接放进 images/train 参与训练让模型学会区分同时把推理时的 --conf-thres 从默认 0.25 提到 0.45 以上过滤低置信度误报。注意负样本图片不能和正样本完全重复最好来自不同工地不同时间段。4.4 检测框整体偏移、和头部错位现象模型能检出目标但画出来的框比头部大一圈或者偏到肩膀位置置信度还挺高看起来像「模型没对准」。原因这类问题九成出在标注转换环节——有人把 VOC 的像素坐标转 YOLO 时忘了除以图片宽高导致框中心点和宽高比例被整体放大或缩小。解决用第 2.1 节的画框脚本抽查二十张图把框可视化出来如果全部偏移检查转换脚本的归一化除以的是不是原始图片宽高而不是缩放后的宽高。还有一种隐蔽情况是图片被统一 resize 后才保存标注但推理时用的是原图两套尺寸不一致也会出现系统性偏移。4.5 摄像头推理掉帧严重现象detect.py 跑 USB 摄像头视频流只有两三帧画面卡顿严重完全没法实际使用。原因默认 640 分辨率推理、未开启半精度、每一帧都做全量检测CPU 或低端显卡扛不住这个计算量。解决推理命令改成--imgsz 320 --halfGPU 支持下半精度能省近一半显存和计算量还卡就加--vid-stride 2每两帧检测一次或者调高 --conf-thres 减少后处理开销。部署到树莓派这类 ARM 设备时优先把模型导出为 ONNX 再做 NCNN 量化这一步往往能把帧率拉回可用水平。5. 推理验证与进阶把权重用起来训练结束拿到 best.pt 只是第一步把权重部署到真实场景才是安全帽检测的最终目的。这一章给出可以直接照抄的验证流程以及一个实用的部署习惯。5.1 detect.py 推理参数与阈值选择单张图片验证用这条命令python detect.py --weights runs/train/exp1/weights/best.pt \ --source test.jpg \ --conf-thres 0.45 \ --iou-thres 0.5 \ --save-txt --save-conf--conf-thres 是置信度阈值低于它的结果被丢弃安全帽场景建议在 0.40.6 之间误报多就往高调--iou-thres 是 NMS 的 IoU 阈值控制重叠框合并默认 0.5 够用。--save-txt 输出每个目标的坐标 txt--save-conf 把置信度写进 txt 最后一位方便后续接告警逻辑——比如置信度超过 0.8 才触发未戴安全帽告警。检测结果图在 runs/detect/exp 目录先肉眼检查再谈指标。5.2 验证指标与导出 ONNX客观指标用 val.py 出python val.py --weights runs/train/exp1/weights/best.pt \ --data data/safety-helmet.yaml --task val重点看 mAP_0.5 和 mAP_0.5:0.95 两个数再打开混淆矩阵图确认两类有没有互相混淆。指标达标后用 export.py 导出 ONNX 通用格式让模型脱离 PyTorch 环境也能跑python export.py --weights runs/train/exp1/weights/best.pt --include onnxONNX 可以被 ONNX Runtime、TensorRT、NCNN 加载是模型接进生产流程最通用的中转站。从那以后我每次接手安全帽检测项目都会强制把数据体检、画框抽查、val.py 指标验证这三步走完再决定要不要动超参数——顺序反了都是在跟模型玄学较劲。希望帮到你。本文还有配套的精品资源点击获取