ARTICLE DETAIL

资讯详情

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

YOLOv9头盔佩戴检测系统:从环境搭建到模型训练部署全流程指南

YOLOv9头盔佩戴检测系统:从环境搭建到模型训练部署全流程指南 简介这是一套面向智慧交通场景的基于YOLOv9头盔佩戴检测系统提供完整的Python源码、训练好的模型权重与评估曲线适合深度学习目标检测方向的毕业设计、课程实践及工程入门。压缩包共188个文件大小约69.32MB其中包含83个py脚本训练与检测主代码、30个yaml配置数据与模型参数、3个pt权重文件以及jpg/png图片样例、csv评估数据、ipynb示例和说明文档目录结构清晰便于按流程复现。项目附详细运行教程涵盖环境配置、数据集准备、配置修改、训练与测试的完整操作说明训练好的best.pt可直接用于图片或视频测试评估曲线可作为论文或答辩图表使用。项目代码经过运行验证功能完整且保留了便于替换自定义数据集的配置入口适合在此基础上进行二次开发或快速完成课程设计与毕业设计。目前已有238人学习下载适合计算机相关专业学生或企业员工快速上手实操。1. 头盔佩戴检测这个毕业设计从YOLOv9选型到跑通一条链路说清交警抽查电动车头盔佩戴率以前靠人蹲点数一辆一辆记现在摄像头一杆子架上去画面自动分帧检测模型直接出数。这套基于YOLOv9的头盔佩戴检测系统把源码、训练好的模型、评估曲线、运行教程一条龙打包拿下来能直接复现也能换成自己的数据继续训练。适合两类人做毕设、课设的在校生以及想低成本验证目标检测落地效果的前后端开发。模型用的是YOLOv9简化版yolov9-s对算力要求不高一张普通显卡就能跑通CPU也不是不能训只是时间会拉长。后面所有内容都按我实际拆这个包的顺序来讲参数怎么改、坑在哪一次说透。2. 环境搭建与YOLOv9复现anacondapycharm这套组合的真问题2.1 先决策conda环境建在哪、python版本怎么选教程第一步就写“建议下载anaconda和pycharm”很多人觉得多此一举其实这步直接决定了后面三天里你是在调代码还是在调环境。anaconda管python环境和包pycharm管编辑器两者通过解释器路径接起来。教程里写的顺序是先配好anaconda环境再导入pycharm这个顺序不要倒过来先装pycharm再建环境容易把解释器路径搞乱。我一般会先建一个独立的conda环境不直接用base因为base环境一旦装坏整个anaconda都要重装。打开anaconda prompt执行下面这组命令conda create -n yolov9 python3.9 -y conda activate yolov9 python --version参数说明-n yolov9是环境名可以自定义成helmet_detect之类的python3.9是我常用的版本YOLOv9的代码依赖较新的python语法3.8以上都能用但低于3.7大概率直接语法报错。-y表示自动确认安装不用中途再敲一次y。激活成功后命令行前面会带(yolov9)前缀这代表你已经进入独立环境后面所有pip安装都发生在这个环境里不会污染系统python。这时候还有个容易被忽略的点显卡驱动的CUDA版本。如果你用的是NVIDIA显卡先在命令行输入nvidia-smi看右上角的CUDA Version这决定你后面装什么版本的torch。如果是A卡或者没有独立显卡就直接走CPU路线后面训练时把--device填成cpu。2.2 requirements.txt安装清华源与torch版本环境建好后进入资源解压目录安装依赖包。教程原文写的是pip install -r requirements.txt或者改成清华源后再执行。我在实际装的时候会直接用清华源因为默认PyPI源在国内下载torch这种大包很容易卡在进度条上等了半天然后超时。pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple这里有个关键点requirements.txt里如果固定了torch版本和CUDA版本直接执行可能会跟你本机的显卡驱动不匹配。我的习惯是先把requirements.txt打开看一眼搜出torch那几行然后根据nvidia-smi显示的CUDA版本单独装。举个例子如果你本机是CUDA 12.x常见做法是执行pip install torch torchvision torchaudio -i https://pypi.tuna.tsinghua.edu.cn/simpleCPU用户则不需要指定CUDA直接装默认的CPU版torch即可。为什么单独强调这一步因为很多人在跑pip install -r requirements.txt时报错报错信息里带一串红字最后落在某个依赖包上其实根源是torch版本和你显卡驱动不匹配torch导入时就崩了后面全是连锁反应。装完包后在命令行输入python -c import torch; print(torch.__version__)验证一下能输出版本号说明torch这块过了。2.3 把conda环境导入pycharm以及最常见的连错包都装好后打开pycharmFile → Settings → Project → Python Interpreter点齿轮选Add Interpreter然后选Existing Environment解释器路径指向你anaconda目录下的envs/yolov9/python.exe。这里有个细节如果你忘了刚才建的yolov9环境在pycharm里选了base环境来解释那你在yolov9环境里装的所有包都白装了pycharm里运行train_dual.py会直接报No module named torch。我自己在这个环节翻过车。pycharm底部Terminal默认打开的是系统shell不是conda环境你在pycharm的Terminal里执行python train_dual.py用的可能是系统python而不是你配好解释器的conda环境。解决办法是在pycharm的Settings里找到Terminal把Shell path改成cmd.exe然后在运行脚本前先手动激活环境conda activate yolov9。或者更保险的做法是直接在pycharm右上角的Run按钮旁边确认解释器显示的是yolov9环境。提示判断解释器有没有选对最直接的办法是在pycharm里新建一个python文件输入import torch能跑通就说明环境串起来了。还有个常遇到的细节是requirements.txt里除了torch还有opencv-python、numpy、matplotlib这些包。opencv-python安装时如果版本冲突建议单独重装pip install opencv-python --no-cache-dir。这个问题在Windows上比较常见装的时候提示成功导入cv2时却报DLL load failed多数是numpy版本和opencv不兼容把numpy固定到和requirements.txt一致即可。3. 数据集与配置文件yolo格式、yaml改造与类别设计3.1 yolo数据集格式与labelimg标注教程里说“需要准备yolo格式的目标检测数据集”这句话对新手来说信息量不够。yolo格式是每张jpg图片对应一个同名txt文件txt里每一行代表一个目标框格式是class cx cy w h其中cx、cy是目标中心点的归一化坐标w、h是归一化宽高取值都在0到1之间。举个例子0 0.5 0.5 0.2 0.3这个txt文件的意思是类别0的目标中心点在图片的(0.5, 0.5)即正中央宽度占图片宽度的0.2高度占图片高度的0.3。文件夹结构也有约定常见的是images里面分train和vallabels里面也分train和val图片和标注txt的名字必须完全一致后缀不同。你如果是自己标注数据用labelimg工具标注前把保存格式选成YOLO画框后自然生成txt不用自己去算坐标。有些教程会让你用labelme但labelme默认输出是json还得再做一次转换多一步事我不推荐。这里有个坑很容易踩标注时框选的目标要贴合目标边缘不要留太多空白否则模型学到的特征是“框内环境”而不是“目标本身”。我见过有人把头盔框成包含头部的矩形训练出来模型把带帽子的人也当成戴头盔就是因为框里混了太多非头盔像素。头盔检测这种场景框的边界紧贴头盔外沿就行宁可紧一点不要松。3.2 banana_ripe.yaml照葫芦画瓢字段与路径改造教程里让你参考data文件夹下的banana_ripe.yaml这个yaml是官方示例里的香蕉成熟度检测配置里面结构很典型# 香蕉成熟度检测示例仅展示yaml结构 train: data/banana/train val: data/banana/val nc: 3 names: 0: very-ripe 1: immature 2: mid-ripetrain和val字段是告诉训练脚本去哪里读图片路径nc是类别总数names是类别名字。照着这个结构改不用太复杂头盔检测场景的yaml我一般会写成这样# 头盔佩戴检测数据集配置 train: D:/helmet_dataset/images/train val: D:/helmet_dataset/images/val nc: 2 names: 0: with_helmet 1: no_helmet这里有一个容易被忽视的点yaml里的路径用绝对路径更省心。因为训练脚本的工作目录不同相对路径很容易找不到数据集报错信息是AssertionError: train: data/helmet/images/train does not exist。我一般在Windows上把所有数据放在D盘某个纯英文目录下把train和val直接写成绝对路径一劳永逸。另外yaml文件里的names和你的标注文件里的class索引必须一一对应第0类是什么、第1类是什么标错了训练时不会报错但检测结果会张冠李戴。3.3 头盔类别设计与数据量建议类别设计这块教程的示例是三类香蕉成熟度但头盔检测场景我建议按实际需求定。最简单的方案是两类with_helmet和no_helmet。如果你的检测目标还包括区分骑行者和行人那可以加第三个类别。再复杂一点有人会把头盔细分成“正确佩戴”和“未正确佩戴”但那需要标注标准非常统一新手不建议一开始就上高难度。数据量方面每类至少500张以上目标实例数越多越好。这里说的500张指的是有效图片不是500个框一张图里多个骑行人员的场景算一张图但贡献了多个检测目标。如果你是纯新手手头没有真实数据可以考虑用资源里自带的那几张测试图1560.jpg、2089.jpg这几张当样本体验流程但不要指望这六张图训出能用的模型它们只是验证链路用的。如果自己做数据集注意类别平衡如果no_helmet样本远少于with_helmet模型会倾向于把所有目标都预测成戴头盔因为这样在训练集上损失更低。常见做法是两类样本量控制在3:1以内最好接近1:1。还有一个很多人忽略的点negative sample。你的验证集里要放一些完全没有骑行人员的场景图片比如空马路、停车场用来检验模型会不会乱报框。我一般会在val集里混入10%左右的背景图这类图片的txt文件是空的训练脚本也能正常处理。4. 训练与测试参数train_dual.py和detect_dual.py的边界4.1 方式一改train_dual.py参数直接开训教程给了两种训练方式第一种是直接修改train_dual.py里的配置参数。这个文件是YOLOv9仓库里的主训练脚本支持传参也支持改默认值。按教程逐项改下来实际是改这几个关键参数# train_dual.py 中修改启动参数 --weights yolov9-s.pt # 预训练权重路径 --cfg models/detect/yolov9-c.yaml # 网络结构配置 --data data/helmet.yaml # 换成自己的数据集yaml --hyp hyp.scratch-high.yaml # 超参数配置文件 --epochs 100 # 训练轮数 --batch-size 8 # 根据显存调整 --device 0 # 一张显卡填0CPU训练填cpu --close-mosaic 15 # 最后15个epoch关闭mosaic增强每个参数的含义我拆开讲。--weights填yolov9-s.pt这个文件是YOLOv9在COCO上预训练好的权重第一次运行时脚本会自动下载如果你下载不了可以去资源里找博主是否内置了该文件有的话直接把路径改成./yolov9-s.pt。--cfg对应模型的网络结构yolov9-c.yaml是官方带重参数化结构的配置数量和计算量都适中。--hyp是超参数文件里面的学习率、数据增强强度都在这里控制新手不需要动保持默认。--epochs设置100到200之间数据量大或者想追求精度就200数据量小就100再多意义不大。--batch-size是显存敏感项6GB显存建议810GB以上可以16。--device填0表示用0号显卡没显卡填cpu。--close-mosaic填15表示最后15个epoch关闭mosaic数据增强具体原理下一章细说。在pycharm里直接运行前先确认--weights路径下的yolov9-s.pt确实存在不然脚本卡在下载权重那一步下载超时又报错。我第一次跑就遇到这问题以为是代码坏了后来发现是网络下载不了权重手动下载放到项目根目录才通过。4.2 方式二命令行逐项拆解第二种方式是在pycharm终端里输入命令行教程给的官方示例是COCO的我们需要把参数换成自己的。整理出一条完整的头盔检测训练命令python train_dual.py --workers 8 --device 0 --batch 16 --data data/helmet.yaml --img 640 --cfg models/detect/yolov9-c.yaml --weights yolov9-s.pt --name helmet_run --hyp hyp.scratch-high.yaml --epochs 200 --close-mosaic 15参数说明--workers 8是数据加载线程数Windows下建议改成0或者4因为Windows的DataLoader默认多线程有时会报BrokenPipeError--img 640是输入图片尺寸头盔是小目标建议不要低于640--name helmet_run是这次训练的标识名所有输出会放在runs/train/helmet_run下方便你多组实验做对比。--min-items 0是每个类别最少实例数过滤保持默认即可。训练的时候观察终端输出每个epoch会打印一行指标box_loss、cls_loss、dfl_loss、mAP50、mAP50-95。新手最直接的经验是loss刚开始下降很快后面斜率变平是正常的mAP50在训练结束时如果能到0.5到0.7之间说明数据集难度下这个模型已经算有可用性了。训练结束后在runs/train/helmet_run/weights目录下会有两个文件best.pt验证集上最优和last.pt最后一个epoch。测试的时候一定用best.pt不是last.pt这俩差别有时候很大。4.3 detect_dual.py测试weights、source与阈值训练完成后进入测试环节修改detect_dual.py里的参数。测试脚本和训练脚本是一对detect_dual.py专门加载训练好的权重对图片或视频做推理# detect_dual.py 中修改推理参数 --weights runs/train/helmet_run/weights/best.pt # 换成训练得到的最优权重 --source test_imgs # 测试图片目录 --conf-thres 0.25 # 置信度阈值 --iou-thres 0.45 # NMS的IoU阈值 --device 0 # 推理设备--weights一定确认指向best.pt路径写错脚本会直接报找不到权重文件。--source是输入填文件夹路径会批量处理文件夹里所有图片填单个图片路径就处理一张填视频路径就处理视频。资源自带的那几张测试图1560.jpg、2089.jpg、2268.jpg、3420.jpg、3673.jpg、2669.jpg就是干这个用的。--conf-thres是置信度阈值含义是“模型有多确定这个框是头盔才输出”调低会召回更多目标但误检也变多调高则相反。--iou-thres是NMS合并重复框的阈值这个值调太高会把同一个目标的多个框合并掉但容易把两个靠得近的框也合掉调太低会出现同一个目标好几个框。头盔检测场景conf默认0.25可以iou保持0.45就行。运行后在runs/detect目录下能看到检测结果图。检查结果时重点看两个细节一是没戴头盔的骑行人员能不能被召回二是空的场景会不会误报。如果头盔都被检测出来了但很多误报就把conf-thres往0.4抬如果漏检严重先看是不是用了last.pt而不是best.pt再考虑降低conf-thres。5. 避坑记录训练头盔检测模型最容易翻车的五个场景5.1 loss曲线一路降mAP却上不去现象训练日志里box_loss和cls_loss每个epoch都在降看起来一切正常但mAP50始终在0.3以下徘徊。原因数据集里没有戴头盔的样本分布和验证集不一致或者mosaic增强在最后没关导致模型看到的合成图跟真实图差异太大。close-mosaic15写在参数里了但很多人用的是旧版本的yaml没生效。解决确认训练时用的是hyp.scratch-high.yaml这个文件的mosaic参数在最后15个epoch会被强制置0。另外一个常见原因是类别不平衡no_helmet样本太少模型根本没学会什么是“没戴头盔”优先补数据。5.2 batch-size调到16直接CUDA out of memory现象运行train_dual.py跑一两个迭代就报CUDA out of memory进程直接崩。原因img640加上batch16中间特征图全在显存里6GB显存根本扛不住。解决把batch-size调到4或8再不行把--img从640降到512。还有一个小技巧在训练命令里加--workers 0能省一点点显存。如果你要跑batch 16至少需要12GB以上显存笔记本8GB显存老老实实batch 8。报错是显存不够不是代码问题不要浪费时间去查逻辑。5.3 CPU训练一个epoch要四十分钟现象没有独立显卡用cpu跑一个epoch跑了四十多分钟200个epoch得到跑六天。原因yolov9-c结构里带重参数化的并行分支计算量比普通网络大不少CPU的算力扛不住。解决三条路。一是把epochs改小到30先把流程跑通验证代码没问题再上服务器二是用--device cpu的同时减小输入尺寸--img 512三是租云GPU把数据传到云上训练成本不高但效率提升几个数量级。我自己做实验时如果只是验证链路会先把数据量缩到20张图、epochs改成3确认代码能跑通再全量跑。5.4 检测结果全是框置信度全是0现象detect_dual.py跑完了输出图片上每个目标都标了个框但框上方显示no_helmet 0.00或with_helmet 0.00置信度全是0。原因加载的权重路径指向了训练中断时保存的损坏文件或者用的是last.pt但训练根本没收敛。解决先确认weights路径指向的是runs/train/helmet_run/weights/best.pt不是last.pt。然后看训练日志里最后的mAP50是不是有值如果训练中途被手动中断过last.pt可能根本没保存完整的权重状态。还有一个可能best.pt是空的因为验证集路径配置错了训练脚本在验证时保存了一个空模型。检查yaml里val路径下的图片是否存在。5.5 数据集路径带中文跑到一半报错现象训练启动正常跑了几个batch后突然报AssertionError: Image Not Found或者opencv读取图片返回None。原因Windows下OpenCV和python的路径解析对中文支持不好标注文件里的图片路径如果含“头盔”这样的中文字符读图时静默失败。解决把数据集和项目路径全部改成纯英文例如D:/helmet_dataset。这个问题在资源自带的代码里几乎一定会遇到因为不少人的用户名是中文桌面路径天然带中文。我现在的习惯是项目根目录、数据集目录、权重目录全部放在盘符根目录下一级避免深层路径和中文路径的叠加问题。6. reparameterization.ipynb与评估曲线最后两步验证6.1 重参数化训练权重转推理权重资源里那个reparameterization.ipynb不是装饰品。YOLOv9的训练网络和推理网络结构不同训练时有多分支的RepConv等模块参与计算保证梯度能更有效地流通推理时这些分支可以合并成单一路径同时省显存、提速度。教程里训练完直接用detect_dual.py测试走的其实还是训练结构要获得更贴合生产环境的推理模型需要执行重参数化。# 简化示意加载训练好的best.pt重参数化后导出推理权重 import torch from models.yolo import Model # 按训练配置初始化网络nc改成数据集类别数 net Model(cfgmodels/detect/yolov9-c.yaml, ch3, nc2) ckpt torch.load(runs/train/helmet_run/weights/best.pt, map_locationcpu) net.load_state_dict(ckpt[model].float().state_dict()) net.eval() # 合并RepConv等模块 torch.save({model: net}, runs/train/helmet_run/weights/best_reparam.pt)这段代码是示意实际执行以压缩包里的reparameterization.ipynb为准。nc2要跟你的数据集类别数保持一致不然加载权重时shape不匹配报错。重参数化后的模型后续直接拿来接摄像头实时推理帧率能提升不少。从那以后我每次跑完训练都强制走一遍重参数化流程再拿结果去测mAP和推理速度不然数字虚高上线才露馅。6.2 results.csv关键列与评估曲线怎么读训练日志除了终端输出还会生成results.csv这是最完整的训练记录。用pandas读一下import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/train/helmet_run/results.csv) # 训练日志常见列名 plt.plot(df[epoch], df[metrics/mAP50], labelmAP50) plt.plot(df[epoch], df[metrics/mAP50-95], labelmAP50-95) plt.xlabel(epoch) plt.ylabel(mAP) plt.legend()key列的含义大概是这样train/box_loss是训练集框回归损失持续下降说明模型在学习val/box_loss是验证集损失如果训练后期开始反弹说明过拟合了早停才是最优解metrics/mAP50是你最应关注的验收指标metrics/mAP50-95更严格低于mAP50但趋势一致。判定模型好坏mAP50是一道门槛mAP50-95是质量分水岭后者越高说明框回归越准。6.3 一张图验证模型与最后的习惯重参数化后把best_reparam.pt喂给detect_dual.py拿资源自带的那六张测试图跑一遍。先用conf-thres 0.25看整体效果再抬到0.5看误报数量。如果0.5下结果依然稳定这个模型至少能应对同分布场景。做毕设答辩时就把训练曲线和重参数化前后的对比图摆出来这比贴代码更能说明你理解了这个模型的血肉。希望帮到你。本文还有配套的精品资源点击获取
返回列表