☰
基于YOLOv11的电动车骑行规范识别系统:头盔检测与违规载人告警实战
2026/10/20 4:36:46 网站建设 项目流程

最近把毕业设计开源了,项目核心就一句话:用YOLOv11构建电动车骑行规范识别系统。完整做了头盔佩戴检测、违规载人识别、实时视频流告警,另外配套了毕业论文和整套源码。它不仅是一个能跑的demo,训练脚本、推理脚本、数据集标注格式、模型导出、界面展示全部整理好了,适合需要做毕设或者想入门目标检测实战的同学直接参考。

我做这个项目最大的感受是:网上很多YOLO教程只教怎么训练一个猫狗分类,但一到真正场景(比如室外复杂背景、小目标、多人重叠)就完全抓瞎。这个系统的价值就是完整走了一遍“数据标注—模型训练—规则融合—系统集成”的项目闭环,能让你少踩大量的坑。

1. 项目背景与需求拆解

1.1 这个系统到底解决什么问题

电动车骑行规范识别的典型场景是路口、小区出入口或者园区内部道路。以前主要靠人工盯着监控画面,发现没戴头盔、违规载人再截图记录。这个方式有两个硬伤:一是人眼长时间盯屏幕容易疲劳漏看,二是多路视频根本看不过来。所以我们需要一个自动视觉检测方案,能够从实时视频流中找出电动车、骑行者、头盔三类目标,再通过目标之间的空间位置关系判断是否违规。

系统的核心输出不只是“画个框”,而是产生明确的告警记录:某时某刻某帧,画面中有一名骑行者未佩戴头盔,或者存在违规载人行为。这类结果可以直接对接后续的短信提醒、大屏弹窗、日志存储。毕设论文里也很好写,因为它既有深度学习模型部分,又有规则逻辑部分,技术层次清楚,工作量也够。

1.2 适用场景与目标人群

这个项目适合三种人参考:

  • 正在准备计算机视觉方向毕业设计的同学,需要一个从数据集到论文的完整实例。
  • 想入门目标检测,但不想只停留在跑通官方示例的开发者。
  • 需要在园区或校园场景做安全巡检演示的团队。

不过也需要说明,这个开源项目不是一套商业级安防产品。它的定位更接近“教学级完整系统”:算法方案合理,工程代码清晰,论文材料齐全,但距离万人并发、多机分布式部署还有距离。理解这点后,你在参考时就不会产生不切实际的预期。

2. 技术选型:为什么选择YOLOv11

2.1 YOLOv5、YOLOv8与YOLOv11怎么选

做目标检测的毕设,技术选型直接决定了后面三个月的幸福程度。我对比过几个常用版本,整理成了下面的表格:

模型版本生态成熟度训练易用性创新点含金量部署难度
YOLOv5极高命令行工具完善较低低
YOLOv8很高Ultralytics统一API中低
YOLOv11较新Ultralytics统一API较高低

选择YOLOv11最重要的原因是论文创新点好讲。YOLOv11在主干网络和注意力模块上做了不少改进,比如引入了C3k2模块和C2PSA注意力机制。你可以在毕业论文的方法章节里专门画结构图、讲原理,比直接套用YOLOv5更有内容可写。Ultralytics框架把训练、验证、导出都封装得很干净,不需要自己写很多底层逻辑,对毕设来说能省下大量时间。

当然,YOLOv11并不是在所有场景下都一定碾压YOLOv8。如果你的数据量很少,或者你需要极端的低延迟部署,YOLOv8的成熟生态也非常够用。我选择YOLOv11更多是综合考虑“项目完成度”和“论文新颖度”的结果。

2.2 开发环境与依赖清单

我用的是Windows环境配合NVIDIA显卡训练,整个环境配置不算复杂。基础依赖如下:

  • Python 3.9 或 3.10
  • PyTorch 2.x
  • ultralytics
  • opencv-python
  • numpy、pandas
  • matplotlib、tqdm

建议使用conda创建独立环境,避免把系统Python搞乱。显卡显存最好不低于4G,如果只有集显,训练速度会非常痛苦。但也不用太担心,模型可以先在云端GPU平台跑通,本机只负责推理演示。这套项目里面train.py和detect.py是完全分离的,训练和推理可以放在不同机器上。

2.3 为什么没走纯分类路线

有人会问,头盔佩戴识别不是可以用一个二分类模型解决吗?直接拍一张照片,判断“戴了”还是“没戴”。这个思路在固定机位、单人入镜时确实可行,但真实场景中会出现多人、多车、目标重叠。分类模型只能告诉你“这张图里有人违规”,却无法告诉你是左边还是右边的那个人违规,也没法在画面上定位。所以最终方案选择了目标检测作为底座,把定位信息交给后处理规则去判断,这样可解释性更强,也便于扩展新的违规类型。

3. 数据集构建与标注规范

3.1 数据来源与类别设计

数据集是深度学习项目的命根子。很多同学一上来就找公开数据集,找不到就开始自闭。我的做法是“公开数据 + 自采数据”混合:头盔检测和人车检测的公开数据并不少,但角度、光线、地区风格差别很大,必须补充一部分自己拍摄的数据。如果你不方便拍摄,也可以从公开的视频中抽样截帧,但要控制好重复画面,避免模型过拟合。

在类别设计上我纠结过两种方案:

  • 方案A:检测person、helmet、electric_bicycle三个类别,由后处理判断“人是否戴盔”。
  • 方案B:直接检测rider_with_helmet、rider_without_helmet、electric_bicycle三个类别。

方案B看起来更直接,模型输出就已经带了语义,但有一个很大的坑:数据标注需要精确区分“戴盔骑手”和“未戴盔骑手”,但很多画面中头盔被车把遮挡,人眼都分不清,标注一致率极低。而方案A把头盔作为独立目标识别,模型特征更清晰。我最后选择了方案A,实际训练效果更稳,后处理也足够灵活。

3.2 标注工具与数据增强

标注工具我用的LabelImg。虽然界面朴素,但胜在简单稳定,支持YOLO格式直接导出。标注规范需要注意几点:

  • 电动车只标可见部分,被骑行人完全挡住时按遮挡情况决定是否标注。
  • 头盔包括安全帽、头盔类目标,但不包括工地安全帽?这里要看场景。我做的园区道路场景,电动车主带的是常见骑行头盔,工地安全帽和骑行头盔形状差异大,如果混在一起会让模型困惑,建议单独建类别。
  • 骑行人被树木、灯杆遮挡时,标出最大可见边界即可,不要强行脑补完整边界。

数据增强方面,Ultralytics内置了mosaic、平移、旋转、HSV扰动等策略,默认配置就能用。我额外增加了少量上下翻转,但一定要注意:对于头盔这种有明确上下方向的目标,过度翻转会导致语义奇怪。比如倒着的头盔本来不合理,强行增强反而干扰模型。我实际测试后发现,加强亮度对比度扰动比空间翻转更有用,因为室外监控的早晚光线差异实在太大了。

3.3 类别不平衡问题

公开数据里“戴头盔”和“不戴头盔”两类样本极不平衡,尤其是未戴头盔的数据很少。这种情况下模型会倾向把所有骑手都预测成“已戴头盔”。我的处理办法是:复制未戴头盔样本并配合随机裁剪、亮度变化,让这一类别的样本量至少达到头盔类别的四成以上。另外,单独增加了一些“头盔拿在手里”和“头盔挂在车上”的负样本,避免模型看到头盔轮廓就和人头强行绑定。

4. 核心模块设计与推理逻辑

4.1 系统整体流程

整个系统的检测流程可以概括为:视频帧读入、YOLOv11推理、目标筛选过滤、头盔佩戴判定、载人判定、告警输出。这里最容易被忽略的是“目标筛选过滤”。因为模型会输出大量置信度低的冗余框,直接做后处理会把画面搞得很乱。我用两个阈值过滤:置信度大于0.45的框才进入业务逻辑,NMS IoU阈值保持默认0.5。

筛选完目标后,我会先把所有person框和electric_bicycle框做一次关联,找出“和电动车有重叠区域的骑行人”。这一步很重要,因为画面里还有行人、外卖员等非骑行目标,如果不对应到电动车上,后面判定就会误报。关联逻辑采用中心点距离加权加IoU匹配,保证每个骑手只对应一辆车。

4.2 头盔佩戴判定与载人识别

头盔匹配的具体做法是这样的:对于一个已判定为骑行人的person框,取框体上方20%到40%的区域作为“头部候选区”。然后计算所有头盔框与该候选区的IoU。如果最大IoU大于0.25,就认为该骑手佩戴了头盔;如果头盔框中心点落在候选区内但IoU较低,则继续用电瓶车与骑手的相对位置修正,避免推车步行的场景误判。

载人判定更依赖空间关系。正常单人骑行时,电瓶车框内只会有一个person框与车辆位置高度重合;如果第二个person框也落在电瓶车框范围内,并且两个person框有显著垂直错位,就判定为违规载人。边界情况也不少,比如后座放了一个大纸箱,模型可能会误识别成person。我的补救办法是加入“目标面积比”,如果第二个目标框长宽比明显不符合人体比例,就过滤掉。

4.3 告警输出与日志保存

每次触发违规,系统会保存当前帧的截图,并把识别结果写入CSV日志,字段包括时间、违规类型、置信度、截图文件名。如果接入的是摄像头,还可以通过本地播放一段蜂鸣音提示现场人员。这部分没什么高深技术,但对系统完整性帮助很大。我建议在论文里把告警模块画成时序图,导师会觉得很规范。

5. 模型训练与调优过程

5.1 训练配置与参数说明

数据准备完成后,数据集目录结构如下:

datasets/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/

数据配置文件data.yaml:

train: datasets/images/train val: datasets/images/val nc: 3 names: 0: person 1: helmet 2: electric_bicycle

训练命令:

yolo train model=yolo11n.pt data=data.yaml epochs=120 imgsz=640 batch=16 project=runs name=ebike_exp

我选yolo11n作为初始权重,因为笔者的显卡不算强,nano版本训练速度快,后面再根据结果升级到small版本。imgsz=640是通用选择,如果发现头盔这类小目标漏检严重,可以改成960甚至1280,但训练时间和显存都会增加。batch要取显卡能承受的最大值,显存不足时优先降低batch,不要动imgsz。

5.2 训练结果与常见瓶颈

训练完成后,重点看三张图:PR曲线、混淆矩阵、验证集预测样例。理论上mAP50能达到85以上,这个项目才算能用。我首批模型头盔类别的mAP50只有71左右,主要原因是小目标多、夜间样本不足。

调优思路有两个方向:一是把输入尺寸从640提到960,小目标检测率明显提升;二是用YOLOv11m替换nano模型,虽然速度慢一些,但精度更高。最终我用的是yolo11m权重 + imgsz=960,类别mAP50分别达到person 0.893、helmet 0.827、electric_bicycle 0.916。对毕设来说已经足够了。

5.3 模型导出与加速部署

训练好的best.pt权重可以直接用于推理,但我建议导出成ONNX格式,这样脱离PyTorch环境也能跑。导出命令很简单:

yolo export model=runs/ebike_exp/weights/best.pt format=onnx dynamic=True

我实测ONNX Runtime在CPU上的推理速度明显优于原版PyTorch,尤其对输入尺寸固定的场景更明显。如果后续要接到边缘设备,还可以转成TensorRT,但这就依赖具体的显卡型号和CUDA版本,不建议在论文主线中花太多篇幅。

6. 系统集成与论文写作

6.1 源码模块说明

开源仓库的结构我设计得很直白,几乎不需要额外文档就能看懂:

E-BikeSafetySystem/ ├── train.py # 训练入口 ├── detect.py # 单张图片和视频推理入口 ├── app.py # 实时视频流界面与告警 ├── config.yaml # 系统配置参数 ├── data.yaml # 数据集配置 ├── datasets/ # 数据集目录 ├── runs/ # 训练输出 ├── utils/ # 后处理工具函数 ├── requirements.txt └── docs/ # 论文与答辩材料

utils里最核心的是postprocess.py,里面实现了头盔是否佩戴的匹配逻辑和载人判定逻辑。我建议拿到源码的同学先看这个文件,其他都是标准YOLO流程。

6.2 实时视频流与界面实现

实时检测部分我用了OpenCV读取本地视频或RTSP流,然后开启一个独立线程做模型推理,主线程负责显示画面和响应按键,这样不会因为推理耗时导致画面卡死。界面没有使用重框架,就是OpenCV原生窗口加控制台输出,足够演示用。如果想要浏览器界面,可以用Flask搭一个简单的HTTP服务,把检测结果通过JSON返回,前端用Video标签播放。

这个环节的核心要点是“不要在主线程做推理”。视频流每秒25帧,模型处理一帧可能需要50到100毫秒,如果不加缓冲队列,实时画面会演PPT。

6.3 论文结构与我踩过的写作坑

论文我按五章结构写:绪论、相关技术、系统需求分析与设计、实验与分析、总结。其中“相关技术”只用两节讲深度学习基础和YOLOv11结构,不要从神经网络发展史开始凑字数,老师一眼就能看出来。

真正的得分点在第四章的“规则判定设计”和第五章的“对比实验”。你要把头部候选区的计算方法画出示意图,把IoU阈值的影响用表格列出数据,再拿YOLOv8和YOLOv11在你的数据集上各跑一遍对比mAP。这些内容全是干货,比大段抄网络资料靠谱得多。论文里不要出现“精度高达99%”这种没有依据的说法,只写你自己的验证集结果。

7. 常见问题与避坑实录

7.1 训练时loss变成NaN

这个坑我刚开始也踩过。如果你的数据集里存在空的标注文件,或者标注坐标出现负数、超界,训练过程中非常容易产生NaN。解决方法是写一个数据清洗脚本,把标注文件逐行检查一遍,过滤掉所有边界外的坐标。学习率设太大也会导致数值不稳定,建议初始学习率不要超过0.01。

7.2 CPU推理速度太慢

用CPU跑yolo11m,在一张1080P图上推理可能要一两秒,做实时检测很吃力。我的建议是:如果必须用CPU,把输入尺寸降到640,模型换成yolo11n,阈值适当地提高,这样勉强可以达到实时。更推荐的方式是导出ONNX后用ONNX Runtime的CPU模式,实测比原版PyTorch快不少。

7.3 头盔误检率偏高

一开始我的模型经常把浅色书包、后视镜、水桶认成头盔。后来我仔细核查标注数据,发现标注时有一些头盔框其实只框到了局部,比如只框到了帽檐或者反光条。这个细节直接导致模型学到错误特征。修正标注并增加负样本后,误检率下降非常明显。所以遇到误检,先别急着换模型,回头检查标注比调整网络结构更有效。

7.4 Ultralytics版本更新导致代码报错

YOLO的API在不同版本间有细微差异。我写的代码锁定在某个具体版本,如果你的环境版本更新,可能会出现一些属性名称变化。建议严格按照requirements.txt安装依赖,不要随意升级ultralytics。这是开源项目最常见的使用问题,提前说明能帮使用者省很多时间。

7.5 判定规则的阈值怎么调

头盔匹配IoU阈值我最终定在0.25,这个值不是随便拍的。我分别测试了0.1到0.5五个档位,发现阈值太低会把远处无关的头盔误匹配给骑手,阈值太高则会让真正戴头盔但因为角度问题IoU偏低的情况被误判为未戴。建议你在自己的数据上跑一遍验证集,做一个简单的阈值扫描,把结果画成曲线选最佳点。这个实验写进论文也特别加分。

8. 一些个人经验

最后说点个人体会。这个项目最大的难点不是训练模型,而是后处理和数据集。开源社区已经提供了大量成熟权重,但真正落到“头盔是否佩戴”这种业务判断时,拼的是你对场景的理解和数据的约束能力。比如骑手戴了帽子,模型把帽子判定成头盔,这不是模型错了,而是你的类别定义没写清楚。我在第一版里只定义了“头盔”一类,导致棉帽、鸭舌帽大量误检;后来单独采集了“帽子”负样本,并在规则里限制头盔框面积必须与头部候选区面积在一定比例内,问题才解决。

另一个小技巧是,论文里不要只展示最优结果,多做几组消融实验。比如“有规则判定”和“没有规则判定”的对比,“输入640”和“输入960”的对比,这些数据能够体现你对问题的分析能力,答辩时也会更有底气。如果你正在做类似项目,希望这篇记录能帮你少走一点弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询