资讯动态

YOLOv5安全帽检测实战:数据集、训练与部署全解析

发布时间:2026/9/14 2:07:46 来源:尧图企业网站定制
简介基于深度学习的头盔佩戴检测识别系统毕业设计完整项目包面向计算机视觉方向学生及企业安防场景开发者解决电动自行车头盔佩戴自动检测与识别问题。资源内共77个文件压缩包仅23.73MB包含PyTorch训练与推理脚本、YOLO配置文件、VOC格式数据集及转换工具、已训练权重下载脚本、环境配置文档和演示视频等涵盖从数据标注到模型部署的完整链路。项目基于YOLOv5框架提供train.py/detect.py等核心代码附带yaml配置文件与Dockerfile便于快速搭建运行环境。已有195人学习适合用于课程设计、毕业设计或实际场景的算法验证。通过教程文档和ipynb示例可掌握数据集制作、模型训练、测试评估与权重复用方法节省从头调试的时间。1. 头盔佩戴检测为什么值得用 YOLOV5 重做一遍在工地门口、厂区走廊或者塔吊下方戴没戴安全帽看起来只是一个二分类问题实际落到视频流里就变成了目标检测问题人站在几米外头部只有几十个像素正午逆光时帽檐和脸完全分不开工人低头作业时头部的姿态又让标注框随时变化。基于 YOLOV5 的头盔佩戴检测识别系统通常以源码、数据集、训练好的权重和教程打包成 zip 分发给使用者它的核心价值不是“模型能跑通”而是让拿到包的人能快速复制出完整的训练、推理和调优流程。对刚接触目标检测的工程师来说这套结构正好演示了数据集格式、训练命令、权重文件三者怎么串起来对要做现场交付的人来说更重要的是理解训练好的模型是用什么数据拟合出来的出问题时从哪个环节开始排查。接下来我从数据准备、环境配置、训练调参、推理评估到最后的部署技巧把这套系统自己动手落地时会踩的坑逐一说清楚。2. 数据集准备与 YOLOV5 环境配置把可复现闭环先跑起来大多数头盔检测项目包解压后数据部分都是 images 和 labels 两个目录权重部分则是一个 best.pt。我拿到这类包的第一件事不是跑 detect.py而是先看三样东西目录结构、标签内容和环境依赖。数据和代码如果不在同一个约定下后面所有训练都是白做。2.1 看数据集目录结构训练集、验证集与标签文件YOLOv5 对数据集的组织方式有硬性要求images 和 labels 必须同级目录存在train、val 子目录的名字也最好固定。头盔检测常见两个类别helmet 和 head分别表示戴了安全帽的头部和未戴安全帽的头部。目录结构大致长这样helmet_dataset/ ├── images/ │ ├── train/ │ │ ├── 0001.jpg │ │ └── 0002.jpg │ ├── val/ │ │ └── 0301.jpg │ └── test/ │ └── 0501.jpg └── labels/ ├── train/ │ ├── 0001.txt │ └── 0002.txt ├── val/ │ └── 0301.txt └── test/ └── 0501.txt每个 txt 文件对应一张图片每一行是一个目标框格式固定为class_id x_center y_center width height四格坐标全部归一化到 01。比如1 0.5 0.3 0.2 0.4表示这个框的中心在图像横向一半、纵向三成的位置框宽占整图 20%框高占 40%。这里最容易出错的是把坐标当成像素值直接用YOLOv5 训练器读取时会直接拿这个值去乘图片宽高所以一旦混入绝对像素坐标框就会偏到画面外。如果项目给的是 COCO JSON 或 VOC XML需要先把标注转成 YOLO 格式。项目包里如果提供的是 JSON 标注我一般直接用下面这段脚本转import os import json def coco_to_yolo(coco_path, label_dir): os.makedirs(label_dir, exist_okTrue) with open(coco_path, r, encodingutf-8) as f: data json.load(f) images {img[id]: img for img in data[images]} for ann in data[annotations]: img images[ann[image_id]] w, h img[width], img[height] x, y, bw, bh ann[bbox] x_center (x bw / 2) / w y_center (y bh / 2) / h width bw / w height bh / h label_path os.path.join(label_dir, img[file_name].replace(.jpg, .txt)) with open(label_path, a, encodingutf-8) as out: out.write(f{ann[category_id]} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n)转换逻辑看起来简单但有两个地方最容易翻车一是 COCO 的 bbox 给的是左上角坐标加宽高YOLO 需要的是中心点加归一化宽高所以x和y要先加上bw / 2、bh / 2再除图片宽高二是类别 id 不能直接用 COCO 原始编号必须再建一张映射表把person映射成 0、helmet映射成 1不然模型会把类别顺序学反。标签检查完以后可以用一段简单代码统计每个标注文件里有没有越界坐标以及类别 id 是否都小于nc。YOLOv5 训练时如果发现标签和图片对不上日志里会报image 1/xxx (label file x.txt not found)不需要自己写特别复杂的校验但最好提前跑一次。2.2 安装 YOLOV5 环境Python 版本、PyTorch 与依赖环境配置是使用 YOLOv5 时最常卡住的一步。通常做法是先把项目源码解压到一个固定路径然后用 conda 建独立环境避免污染系统自带 Python。我习惯这样装conda create -n yolov5 python3.8 -y conda activate yolov5 conda install pytorch torchvision torchaudio cudatoolkit11.3 -c pytorch -y cd yolov5-project pip install -r requirements.txtrequirements.txt 里包含 numpy、opencv-python、matplotlib、tensorboard 等 YOLOv5 的运行依赖。cudatoolkit11.3这个版本号要跟你机器上的 NVIDIA 驱动匹配驱动太旧就换低一档的 CUDA 版本不用死守同一个值。如果没有 N 卡可以装 CPU 版 PyTorch但训练速度会慢到让你怀疑人生所以训练阶段还是建议找一台带 GPU 的机器。装完之后先跑一个最小验证确认 torch 能正常使用 GPU再下载一张测试图执行自带检测命令python detect.py --weights yolov5s.pt --source data/images --img 640如果这条命令能输出带框的图片说明 OpenCV、PyTorch、YOLOv5 基础链路都没问题。下面这几条检查命令足够定位大部分环境故障验证命令通过条件nvidia-smi能看到显卡型号和显存python -c import torch; print(torch.cuda.is_available())输出Truepython detect.py --help正常打印参数帮助python detect.py --weights yolov5s.pt --source data/images在runs/detect里生成标注图环境问题最典型的表现是AttributeError: Upsample object has no attribute recompute_scale_factor这基本是 PyTorch 版本和 YOLOv5 源码不匹配优先回退 PyTorch 版本不要自己改 upsampling 代码。2.3 创建 helmet.yaml类别、路径和数据集描述YOLOv5 的train.py不会直接在命令行里接收类别名而是读取一个 yaml 文件。头盔检测项目里我把这个文件命名为helmet.yaml# helmet.yaml train: ../helmet_dataset/images/train val: ../helmet_dataset/images/val nc: 2 names: 0: helmet 1: headyaml 里的train和val必须指向 images 目录YOLOv5 会自动把路径中的images替换成labels所以上面写的是images/train标签目录必须真实存在于helmet_dataset/labels/train。nc表示类别总数names的顺序必须与标注 txt 里的class_id一一对应。顺序写反是最冤的错误模型会把戴帽子的人学到类别 0没戴帽子的人学到类别 1训练指标看着正常实际推理结果完全相反。如果项目数据集里已经有训练集、验证集和测试集我会在 yaml 里多留一个test项因为最后评估模型时测试集不应该参与训练否则 mAP 会有虚高。写完 yaml 后跑一次一个 epoch 的训练来验证数据链路python train.py --data helmet.yaml --weights yolov5s.pt --epochs 1 --batch-size 8这一步不是为了训练出模型而是触发 YOLOv5 的数据集解析逻辑任何一个标签文件路径错误或图片坐标系异常都会在这里直接暴露。3. 用 YOLOV5 源码训练头盔模型超参数、日志与权重挑选环境就绪、数据集结构正确之后接下来进入训练阶段。YOLOv5 源码里的train.py已经封装好了训练循环、数据加载和评估逻辑不需要改网络结构只需要把数据集、超参数和显存资源匹配好。下面是头盔检测的典型训练流程。3.1 最小可用的训练命令以及每个参数为什么这么设在单张 8GB16GB 显存的 GPU 上我常用的训练命令是这样的python train.py \ --data helmet.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --cache \ --name helmet_exp--weights yolov5s.pt表示从 YOLOv5s 的 COCO 预训练权重开始继续训练。安全管理帽的形态和 COCO 数据里 person 类别有一定相似性迁移学习能明显加速收敛比从头训练少用一半 epoch。--img 640是输入分辨率头盔属于中小目标如果图片里人的头部只占很小的区域640 可能不够可以考虑 1280但显存占用会大幅上升。--batch 16在 16GB 显存下配合 640 分辨率是可以跑起来的如果显存只有 8GB就降到 8。--cache会把图片一次性缓存进内存训练速度提升非常明显代价是占用大约等于数据集大小的内存。参数表如下方便你根据自己的机器调整参数常见取值说明weightsyolov5s.pt/last.pt预训练权重或断点续训权重img512 / 640 / 1280输入分辨率小目标多则调大batch8 / 16 / 32受显存限制batch 过小时 BN 层不稳定epochs100 / 200看 val mAP 是否变平不是越大越好cache无 /ram开启后训练更快占用内存name自定义字符串决定结果输出到runs/name训练中途断掉不需要从头开始直接用 last.pt 续训python train.py --data helmet.yaml --weights runs/helmet_exp/weights/last.pt --resume--resume会自动读取上次的 epoch、优化器状态和超参数断点续训后之前的曲线也会保留在 tensorboard 里。3.2 头盔场景真正值得调的 YOLOV5 超参数YOLOv5 把超参数放在独立的 yaml 文件里项目默认用的是hyp.scratch-low.yaml。数据集不同最优超参数也不一样头盔检测最值得关注的是下面这几个配置项默认值头盔场景的影响lr00.01初始学习率。数据量小或标注噪声大时设为 0.005warmup_epochs3.0前 3 轮小学习率热身小数据集建议保留mosaic1.0马赛克增强。头盔目标小且密集mosaic 过强会把目标截断mixup0.0混合增强。类别间相似度高时调大会增加误检fliplr0.5水平翻转。摄像头部署位置固定时可以降到 0.0修改超参数时单独复制一个文件不要改原始配置python train.py --data helmet.yaml --hyp hyp.scratch-low.yaml --epochs 200我一般不会一上来就动超参数。头盔项目最常见的失败不是训练不收敛而是“没戴安全帽的人”被检测成“戴了安全帽”。这种情况先补数据再调超参数。把大量“不戴帽的人头”、“手扶帽”的负样本加入训练集比调整数据增强参数有效得多。网格搜索超参数可以使用项目自带的utils/torch_utils.py里的遗传算法脚本但头盔检测场景数据集通常在几千张以内网格搜索性价比不高手动训练两三轮一般就够。3.3 训练日志里哪些信息决定模型质量训练过程中每一轮结束会输出一组指标越到后面越值得盯着看Epoch gpu_mem box obj cls labels img_size 99/199 8.67G 0.0184 0.0152 0.0102 9 640 Class Images Instances P R mAP50 mAP50-95 helmet 201 389 0.881 0.844 0.911 0.623 head 201 175 0.745 0.712 0.768 0.492box、obj、cls 分别是边框回归损失、目标置信度损失和分类损失。如果某个 loss 一直不降比如 cls loss 波动很大往往说明两类样本数量极度不均衡或者标注框把上半身都标了进去导致模型学到“有人就有头”的错误特征。更关键的是 P、R、mAP50 三个指标。P 是精确率检测出来的框里真正正确的比例R 是召回率所有真实目标里被检出的比例。在头盔安全检测场景下漏检的代价远大于误检所以我更看重召回率。如果 helmet 类 mAP50 一直在 0.9 以上而 head 类只有 0.7 左右说明模型对“没戴头盔”的头部识别不稳定优先检查 head 类标注框是不是太小、边界是不是太贴近头发边缘。训练结束后模型会自动保存两个权重best.pt和last.pt。best.pt 是根据验证集 mAP 最优时保存的last.pt 是最后一个 epoch 的权重。不要默认 last.pt 就是更好的对大部分场景直接用 best.pt 即可。4. 加载训练好的权重从 detect.py 到 Python API 推理训练完成后项目包里的 best.pt 就是“训练好的数据”里最核心的部分。接下来要做的不是把它当一个黑盒点两下而是清楚它支持哪些输入源、推理参数怎么调、以及如何在自研系统里调用。4.1 detect.py 推理参数source、conf、iou 和 classesYOLOv5 自带的 detect.py 支持图片、视频、摄像头和 RTSP 流。头盔检测项目落地时最常见的是接本地摄像头python detect.py \ --weights runs/helmet_exp/weights/best.pt \ --source 0 \ --conf 0.35 \ --iou 0.45 \ --img 640 \ --save-txt \ --project output--source 0表示读取系统默认摄像头数字换成 RTSP 地址就是视频流转检测。--conf 0.35是置信度阈值低于这个值的预测框会被丢掉。头盔检测场景不建议把阈值拉到 0.5 以上因为远距离目标置信度天然偏低太高会出现大量漏检。--iou 0.45是 NMS 的 IoU 阈值两个框重叠超过这个比例时只保留置信度更高的那一个。--save-txt会额外把检测结果写成 txt 文件格式为frame class_id x1 y1 x2 y2 conf方便和门禁系统对接。detect.py 还有两个参数在日常调试里很有用参数作用--classes 0 1只检测特定类别比如只检测 head 类用来排查误检--hide-conf不在画面上显示置信度数字适合做演示视频--line-thickness调整框线宽度1080p 画面上建议设 2 或 3摄像头推理时不要把--img直接改成现场分辨率。1920×1080 的画面如果直接 1080 输入显存爆炸而且速度很慢。标准做法是保持 640 或 1280 推理画面缩放交给 YOLOv5 预处理完成。4.2 在 Python 中加载 best.pt 做自定义检测逻辑如果要把头盔检测嵌入到自己的后台服务里不能每次调用都整条命令启动 detect.py。更实际的方式是在 Python 环境里加载模型权重自己控制帧读取和结果处理。项目包里如果有 YOLOv5 源码目录我使用下面的方式import torch model torch.hub.load(ultralytics/yolov5, custom, pathruns/helmet_exp/weights/best.pt, force_reloadFalse) model.conf 0.35 model.iou 0.45这样加载的对象输入一个 BGR 图像数组调用一次就返回所有检测结果。写成带摄像头的循环就是import cv2 cap cv2.VideoCapture(0) while cap.isOpened(): ret, frame cap.read() if not ret: break results model(frame, size640) df results.pandas().xyxy[0] for _, row in df.iterrows(): x1, y1, x2, y2 int(row[xmin]), int(row[ymin]), int(row[xmax]), int(row[ymax]) label f{row[name]} {row[confidence]:.2f} color (0, 255, 0) if row[name] helmet else (0, 0, 255) cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2) cv2.putText(frame, label, (x1, max(0, y1 - 6)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) cv2.imshow(helmet, frame) if cv2.waitKey(1) 0xFF ord(q): breakpandas() 返回的 DataFrame 里每一行分别是 xmin、ymin、xmax、ymax、confidence、class、name。判断class字段比判断 name 更可靠因为 name 是根据 yaml 里的 names 生成的如果别人把 names 顺序调乱了字符串判断就会出问题。如果是离线环境且 torch.hub 下载失败可以从本地导入models.experimental.attempt_load代替detect.py 内部也走的是这条路。4.3 用 val.py 验证模型效果而不是只看一帧检测图只看一张图片的检测效果很容易被高估。模型可能在这张图上表现很好但换了角度、换了光线就崩。YOLOv5 提供 val.py会在整个验证集上算平均精度python val.py \ --data helmet.yaml \ --weights runs/helmet_exp/weights/best.pt \ --img 640 \ --conf 0.35 \ --iou 0.45输出结果中 mAP50 是最直观的参考对应 IoU 阈值为 0.5 时所有类别的平均精度。不同场景可以按下表做初步判断mAP50是否可用0.90 以上基本可用可进入实地小规模测试0.750.90可用但漏检较多建议补充难例0.75 以下不建议上线优先检查标注和数据分布val.py 结束后会在runs/val/exp里生成混淆矩阵图和 PR 曲线图。混淆矩阵横轴是真实类别纵轴是预测类别对角线越亮越好。重点看 head 那一列有没有大量跑到 helmet 行这是“无帽误报成有帽”的典型信号。5. 从“能出框”到“敢上线”头盔检测的小目标切图与部署导出模型在验证集上 mAP 达标不代表现场视频流能用。施工现场的摄像头分辨率高、视野大一个站在画面角落的人可能只占几十个像素。这一章讲两个最有效但常被忽略的做法。5.1 小目标场景用滑窗切图而不是把整帧缩到 640许多工地摄像头输出 1920×1080 甚至 2560×1440 的画面直接整帧缩放成 640 后一个人头可能只有 5×5 像素再强的检测器也认不出来。常见的做法是先在原图上做滑窗裁剪对每个子图分别推理再把框坐标映射回原图后做全局 NMS。def tiled_detect(model, frame, crop640, overlap0.2): h, w frame.shape[:2] stride int(crop * (1 - overlap)) detections [] for y in range(0, max(h - crop 1, 1), stride): for x in range(0, max(w - crop 1, 1), stride): patch frame[y:y crop, x:x crop] result model(patch, size640).xyxy[0].cpu().numpy() for box in result: detections.append([ box[0] x, box[1] y, box[2] x, box[3] y, box[4], box[5] ]) return detectionsoverlap 取 0.2 能避免目标正好被切在子图边缘。这里的返回值只是候选框还需要再做一次全局非极大值抑制否则同一个目标可能被多个滑窗的重复框输出多次。切图推理的耗时等于子图数量乘以单次推理耗时所以生产环境里不要对每一帧全画面切图我一般会先用一个 640 全景模型判断画面里是否存在人只有判断出有人时才触发滑窗细检。5.2 导出 ONNX部署到没有 YOLO 源码的机器工控机或者边缘盒子往往不会手动安装 YOLOv5 全套依赖最省事的部署方式是把 best.pt 导出成 ONNXpython export.py \ --weights runs/helmet_exp/weights/best.pt \ --img 640 \ --include onnx导出完成后会生成best.onnx文件比 .pt 小很多推理时只需要 onnxruntimeimport cv2 import onnxruntime sess onnxruntime.InferenceSession(best.onnx) input_name sess.get_inputs()[0].name # 读取图像后执行 letterbox 归一化再喂给 sessionONNX 导出需要注意两点一是输入尺寸必须固定尽量和训练时一致二是检测模型的 NMS 节点在导出时可能不包含不同版本的 YOLOv5 对这个问题的处理方式不同。导出后先用同一张原图分别跑一次 detect.py 和 onnxruntime对比两个结果里的坐标如果差距超过 23 个像素就要检查预处理里的 letterbox 参数是否一致。确认这一步没有偏差后再把头盔检测接到门禁闸机或者现场抓拍的平台上模型才能算真正落到项目里。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价