拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于YOLOv8与PERCLOS的驾驶者行为监测预警系统实战

简介基于深度学习的驾驶者行为监测预警系统毕业设计项目压缩包由中南大学信息科学与工程学院与交通学院合作完成面向计算机/人工智能方向毕业设计学生与研究人员针对疲劳驾驶、分心行为实时监测预警问题提供从数据预处理到模型训练、测试与推理的完整工程实现覆盖语音识别、面部状态识别、肢体动作识别三条技术路线。压缩包共43个文件约21.75MB包含21个Python源码如twoStream_CNN、VGGNet等模型实现、4个Markdown说明文档、2个PDF技术文档以及配置文件等既可看到深度学习模型定义与训练脚本也能找到摄像头调用、语音转文本、数据集加载等辅助代码。目前已有172人学习浏览适合正在准备毕业设计或想了解多模态行为分析系统的读者参考。从中可系统学习CNN、双流网络、VGGNet等经典模型的实际应用理解多源数据视觉、语音、肢体动作的处理流程并借鉴其模块划分快速搭建预警系统原型。1. 深度学习驾驶者行为监测预警系统的两级问题深度学习驾驶者行为监测预警系统这类题目每年毕设季都扎堆。多数第一版方案从闭眼检测起步但现场验证会发现单帧检出闭眼只是第一级问题真正决定系统能用与否的是第二级——闭眼持续多久、频率是否异常、要不要报警。两级不打通模型再准也落不了地。标题里的跨院合作不是锦上添花。信息类学院负责感知模型与推理管线就是看得到交通类学院负责行为定义与风险等级就是看得懂。系统能否通过评审往往卡在后者。下文按完整链路展开任务拆解与选型YOLOv8 训练单帧行为检测PERCLOS 疲劳判定与分级告警模型导出与现场验证。按顺序跑完可得到能演示的最小系统。2. 驾驶者行为监测的技术拆解与模型选型2.1 三类检测任务目标检测、关键点回归与时序动作识别驾驶舱内部署深度学习方案最容易犯的错误是把所有行为塞进同一个模型。实际上驾驶者行为可以拆成三类性质完全不同的任务。第一类是拿没拿、碰没碰——手拿手机、递烟、喝水、伸手够东西本质是目标检测问题而不是通用图像识别问题模型需要输出行为物品或手部的位置框和类别。第二类是睁没睁、打没打——闭眼、打哈欠、点头需要回归眼睛轮廓、嘴部轮廓和头部姿态关键点再用几何指标判断状态。第三类是持续了多久——连续转头离开前方超过 3 秒、分心事件累计时长这是时序任务可以用 TSM 这类动作识别模型也可以用状态统计加阈值规则处理。从工程落地角度看三类任务的性价比差异非常大任务代表模型输出实时性实现成本行为物品检测YOLOv8、RT-DETR类别 位置框30 FPS 以上中面部关键点MediaPipe FaceMesh、dlib 68 点468/68 个关键点单帧毫秒级低时序动作识别TSM、SlowFast片段动作类别需缓存 16~64 帧高常见做法是单帧行为检测用 YOLO 系列疲劳判定用关键点加规则不做端到端动作识别。理由很直接——动作识别需要的数据量按视频片段计标注成本远高于静态帧车舱内多数行为靠单帧就能判别时序信息交给 PERCLOS 这类统计指标处理解释性强答辩时也更容易讲清楚推理依据。也有方案直接对整帧分类输出安全驾驶/打电话/抽烟演示视频上看着准确但无法定位行为发生的区域换场景后鲁棒性差错误样本没法归因调试阶段会很痛苦。理论基础不够的话补《动手学深度学习》的目标检测和循环网络章节即可不必整本啃完花书。2.2 公开数据集与自建数据的差异训练单帧行为检测公开数据集选择不多。State Farm Distracted Driver Detection 是目前最常用的约 2.2 万张驾驶舱视角图像覆盖正常驾驶、打电话、发短信、喝水等类别3MDAD 和 AUC 数据集侧重头部姿态与视觉注意力。但这些数据全部来自左侧驾驶、仪表台上方固定机位的采集直接迁移到右侧驾驶或不同摄像头位置的场景精度下降会非常明显。自建数据最需要控制的不是数量而是标注一致性。以手机类别为例人手举着手机放在方向盘上方、耳边、大腿上时边界框大小差异极大标注员在是否框入手掌上的分歧会直接污染模型。常见做法是先定标注规范例如框需要包含手机完整轮廓手掌可以不完整打电话场景下手机与手部合并为一个框双手离开方向盘但没有任何物品时不标注。规范确定后再用 labelme 或 X-AnyLabeling 标注统一转成 YOLO 格式。# labelme 多边形标注批量转 YOLO txt 的核心逻辑 import json import numpy as np from pathlib import Path import cv2 CLASS_ID {safe: 0, phone: 1, smoke: 2, drink: 3, look_away: 4} def convert(json_path: Path, img_dir: Path, out_dir: Path): ann json.loads(json_path.read_text(encodingutf-8)) img cv2.imread(str(img_dir / ann[imagePath])) h, w img.shape[:2] lines [] for shape in ann[shapes]: label shape[label] if label not in CLASS_ID: continue # 未定义类别直接跳过 pts np.array(shape[points], dtypenp.float32) x_min, y_min pts.min(axis0) x_max, y_max pts.max(axis0) x_min, x_max max(0, x_min), min(w, x_max) y_min, y_max max(0, y_min), min(h, y_max) if (x_max - x_min) 2 or (y_max - y_min) 2: continue # 过滤退化成点或线的无效框 cx (x_min x_max) / 2 / w cy (y_min y_max) / 2 / h bw (x_max - x_min) / w bh (y_max - y_min) / h lines.append(f{CLASS_ID[label]} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) out_dir.mkdir(parentsTrue, exist_okTrue) (out_dir / (json_path.stem .txt)).write_text( \n.join(lines), encodingutf-8)脚本把 labelme 的多边形坐标取外接矩形归一化后写入 YOLO txt。两个细节要注意类别 ID 必须与后续训练 yaml 的 names 顺序严格一致多边形退化成点或线时外接矩形宽高接近零训练阶段会出现空标注告警转换时用面积阈值过滤掉。2.3 为什么选 YOLOv8 作为主体模型单帧检测的选型通常在 Ultralytics YOLOv8 和 RT-DETR 之间讨论。RT-DETR 精度上限更高但 transformer 解码器在嵌入式设备上的算子支持不如 YOLO 成熟YOLOv8 采用 anchor-free 头部不存在预设锚框匹配问题训练时的收敛过程更可控模型体积从 nano 到 x 梯度完整便于先在办公显卡上跑通再压缩到 Jetson 或 RK3588 上部署。网络层数在这个任务里的作用比想象中小。车舱内目标尺度和景深变化都不大yolov8n 与 yolov8s 的精度差距通常在 3~5 个 mAP 点以内但推理延迟差距接近一倍。如果演示机是普通办公笔记本直接用 yolov8s如果目标平台是边缘盒子从 8n 开始把省下的算力留给关键点检测和跟踪。提示选型只看 mAP 不够务必拿自己摄像头实拍的帧做一次脏数据测试。公开数据集里几乎全是光线均匀、驾驶员居中的理想画面真实车舱的逆光和抖动才是决定成败的地方。3. 用 YOLOv8 训练驾驶者行为监测模型的完整流程3.1 深度学习环境配置与依赖安装深度学习环境配置是第一个卡点推荐用 conda 建独立环境避免污染系统 Python。conda create -n driver_monitor python3.9 -y conda activate driver_monitor pip install ultralytics8.2.100 torch2.1.2 torchvision0.16.2 pip install opencv-python onnxruntime把 ultralytics 固定到 8.2 大版本是有意的这一系列对 YOLOv8 的训练默认值做过收敛性调整日志和报错在网络上可查的信息最全后续版本改了不少默认行为对不上教程时排查成本很高。torch 2.1.2 与 torchvision 0.16.2 是配套版本CUDA 11.8 环境下即可正常训练RTX 3060 及以上显卡够跑完整个流程。3.2 数据目录与训练配置YOLOv8 要求图片和标签目录分离data/ └── driver/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/train 与 val 的分割建议按视频片段切而不是按帧随机切。同一段视频的相邻帧高度相似按帧随机切分会让验证集被训练集剧透评估指标虚高换到新场景马上现原形。训练配置文件 driver_detection.yamlpath: /home/user/data/driver train: images/train val: images/val nc: 5 names: 0: safe 1: phone 2: smoke 3: drink 4: look_away启动训练yolo detect train \ datadriver_detection.yaml \ modelyolov8s.pt \ epochs60 \ imgsz640 \ batch16 \ lr00.01 \ patience15 \ workers4 \ projectruns/driver_detection \ nameexp01关键参数的调整方向参数本次取值何时修改imgsz640目标占比大时可降到 544训练和推理同步提速batch168GB 显存用 824GB 显存可加到 32batch 直接影响 BN 统计量的估计可靠性epochs60自建数据量小时 50~80 足够收敛后由 patience 提前截断lr00.01使用预训练权重迁移时可尝试 0.001避免破坏底层特征patience15验证集 mAP 连续 15 个 epoch 不提升即停止节省时间除了 epochs 和 lr0Ultralytics 训练脚本默认开启 hsv_h、hsv_s、hsv_v 色彩增强以及 translate、scale、fliplr 空间增强。车内场景不建议关掉色彩增强因为车窗进光和不同时段的色温差异大fliplr 要谨慎——如果类别与手部左右语义相关开启水平翻转会产生语义矛盾的样本。mosaic 增强在车内目标尺度不大的场景下容易出现目标被拼接裁碎的问题训练后期发现小目标召回率异常时把 mosaic 从 1.0 降到 0.3~0.5 再续训即可。3.3 从训练日志里看真实水平训练结束后先看混淆矩阵而不是只盯着 mAP。驾驶行为数据里类别不均衡几乎是必然的normal 帧占一半以上smoke、drink 可能只有几百框。整体 mAP 可以很高逐类看 recall 却发现 smoke 不足 0.5这种情况在答辩现场拿真实视频一跑就露馅。另一个常见问题是损失函数被大目标主导。YOLOv8 默认用 CIoU 做边界框回归一张图里手机框很小、肩部框很大时大框的误差会主导梯度。缓解做法有两种把 imgsz 提到 1280让小目标占更多像素或者直接按驾驶位区域裁剪后再训练。两种方案都有效第二种对算力要求更低适合自建数据量有限的场景。4. 驾驶者疲劳预警PERCLOS 时序判定与分级告警4.1 用关键点计算 EAR 闭眼指标行为检测解决分心类问题疲劳需要另一条线。行业通用的疲劳指标是闭眼百分率 PERCLOS它的前端是眼部关键点回归。使用 dlib 68 点模型时左眼取索引 36~41 六个点右眼取 42~47。EAREye Aspect Ratio的计算公式为EAR (||P2 − P6|| ||P3 − P5||) / (2 × ||P1 − P4||)P1、P4 是内外眼角P2/P3 是上眼睑两点P5/P6 是下眼睑两点。睁眼时 EAR 约 0.28~0.35完全闭眼时降到 0.15 以下。import numpy as np def eye_aspect_ratio(landmarks, eye_idx(36, 37, 38, 39, 40, 41)): # dlib 68 点索引左眼 36-41右眼 42-47 p1, p2, p3, p4, p5, p6 (landmarks[i] for i in eye_idx) vertical_a np.linalg.norm(p2 - p6) # 左垂直距离 vertical_b np.linalg.norm(p3 - p5) # 右垂直距离 horizontal np.linalg.norm(p1 - p4) # 眼裂宽度 return (vertical_a vertical_b) / (2.0 * horizontal 1e-6)加 1e-6 是为了防止水平距离为零时除零。EAR 是纯几何比例不依赖关键点输出的绝对坐标值所以对摄像头安装高度和不同脸型有一定鲁棒性但它对面部光照变化敏感侧光造成某侧眼睑关键点漂移时EAR 瞬时值会异常跳变需要在时序层做滤波。若改用 MediaPipe FaceMesh计算方法不变把 68 点索引替换成 468 点中对应的眼角与上下眼睑索引即可。实测中 EAR 阈值取 0.21~0.23 比盲目取 0.2 更贴合实际因为车规摄像头距人约半米时眼睑在像素上的波动明显阈值必须在真机画面的录像上标定不能照抄论文数值。4.2 PERCLOS 滑动窗口与疲劳阈值单帧 EAR 只说明当前是否闭眼疲劳本身是统计概念。PERCLOS 定义为固定时间窗口内眼睛闭合时间所占比例。按 30 FPS 的视频流、60 秒窗口计算PERCLOS 等于窗口内 EAR 低于阈值的帧数除以窗口总帧数再乘 100%。窗口长度是精度与响应速度的折中30 秒窗口判定快但受单次闭眼影响大3 分钟窗口更平缓演示等待太久60 秒是论文和实车方案里最常见的取值。from collections import deque class PerclosCounter: def __init__(self, window_seconds60, fps30, ear_threshold0.22): self.events deque(maxlenwindow_seconds * fps) self.threshold ear_threshold def update(self, ear_value) - float: self.events.append(int(ear_value self.threshold)) return sum(self.events) / len(self.events) * 100.0deque 的 maxlen 天然实现滑动窗口淘汰不需要手工管理队列长度。窗口未填满时 len(self.events) 是实际帧数前几秒的 PERCLOS 数值会自然过渡不会出现初始化跳变。阈值配置参考指标阈值含义单帧 EAR0.22低于该值视为闭眼PERCLOS / 60s大于 20%判定为疲劳状态单次闭合时长大于 1.5 秒判定为微睡眠前兆哈欠 MAR大于 0.6 持续 1 秒与闭眼联合确认疲劳满足单次闭合 1.5 秒或 PERCLOS 超过 20% 时触发一级预警两者同时满足时升级为二级触发声光告警并截存前 30 秒视频片段。4.3 分级告警的状态机设计预警系统最忌讳抖动EAR 在阈值附近波动会让告警灯闪烁不停。常见做法是引入滞后比较和持续帧数确认。class FatigueAlarm: def __init__(self, fps30): self.closed_frames 0 self.fps fps def evaluate(self, ear_value, perclos) - int: # 返回 0 无告警1 一级提示2 二级强告警 if ear_value 0.22: self.closed_frames 1 else: self.closed_frames max(0, self.closed_frames - 2) if self.closed_frames int(1.5 * self.fps): return 2 if perclos 20.0: return 1 return 0闭眼帧计数在连续闭眼时累加睁眼后按每帧减 2 的速率衰减形成一个轻微的滞后带避免状态在告警边界来回跳动。如果现场误报仍多把衰减速率改为减 1让告警状态维持更久。一级提示是仪表台闪烁指示灯二级告警要求蜂鸣加语音播报加事件片段落盘。落盘需回溯 30 秒最简单的实现是在内存里维护一个 30 秒的环形帧缓冲触发时才写入磁盘避免全程录像撑爆存储。5. 监测预警系统的工程落地模型导出、推理提速与三个现场验证技巧5.1 用 ONNX 导出摆脱 PyTorch 运行时依赖演示机装完整 PyTorch 没问题但换机器部署时 ONNX 是更可靠的载体。from ultralytics import YOLO model YOLO(runs/driver_detection/exp01/weights/best.pt) model.export(formatonnx, dynamicTrue, simplifyTrue, imgsz640)dynamicTrue 让 batch 和宽高维度保持动态simplifyTrue 会调用 onnx-simplifier 做算子折叠与融合。导出后必须对比 ONNX 与 PyTorch 的输出差异容差低于 1e-3 才算有效超出说明算子替换引入了精度损失需要考虑降低 simplify 等级。5.2 双线程管线与跳帧策略单线程里摄像头采集和模型推理串行笔记本上通常只有 15 FPS。拆成采集、推理两个线程并用队列解耦后推理线程能跑满模型自身的速度。这个改造代码量很小是性价比最高的第一步优化。跳帧策略留给算力受限的边缘板卡。行为检测模型每 3~5 帧跑一次约 9~15 FPS 的事件采样率对驾驶行为完全够用中间帧只做 EAR 计算因为关键点几何量在 CPU 上单帧也就一两毫秒。5.3 三个现场验证技巧第一固定机位再标定阈值。摄像头固定后录制 3 分钟包含遮挡面部、戴墨镜、侧头打电话的视频把每帧的 EAR 和模型置信度导出成 CSV 后离线回放所有阈值调整都基于 CSV 而不是现场肉眼判断。第二防误报只信时序不信单帧。把单帧告警改成连续 3 帧同一类别且置信度超过阈值才计入事件误报能降一半以上。这一点在答辩视频演示里尤其重要现场观众不会记得模型识别对了几次但会记得警报乱响了几次。第三留一条人工兜底通道。演示机上保留一个快捷键手动触发告警和落盘用来验证告警链路后端没有断。真正开车测试时语音播报和视频落盘是否同步发生比盯着推理画面更容易判断系统状态。注意现场演示跑通只是第一步EAR 阈值标定流程和 PERCLOS 统计窗口的设计依据要写进毕业设计说明书评审老师大概率会针对这两处追问。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门