简介这是一套面向计算机相关专业学生与项目实战学习者的疲劳驾驶检测识别毕业设计资源基于YOLOv5实现可直接用于毕设、课程设计或期末大作业。项目经导师指导并获97分评审认可代码经过严格调试确保可运行。压缩包共93个文件约136.48MB以31个Python源码、24个YAML配置、14个编译文件为主另含模型权重、数据集标注、说明文档、演示视频与依赖脚本覆盖训练、推理、评估全流程。资源包含完整项目源码、预训练模型、使用说明及配套资料目录中可见训练脚本、检测脚本、工具模块与模型配置便于读者理解YOLOv5在疲劳驾驶场景下的数据组织、模型训练与推理部署思路也能作为二次开发与算法对比的起点。目前已有974人学习下载适合需要完整项目方案、排错参考与实战练习的读者。1. 疲劳驾驶检测项目拆解从 YOLOv5 源码到可复现的落地路径高速上连续开三小时眼皮开始打架方向盘轻微跑偏的那零点几秒往往就是事故的起点。疲劳驾驶检测要解决的就是这个场景用摄像头实时判断驾驶员是否闭眼、打哈欠、低头然后触发告警。这个标题里的「基于 YOLOv5」说明检测核心用的是目标检测模型而不是传统的人脸关键点回归方案。YOLOv5 在这里负责框出眼睛、嘴巴、人脸等目标再配合状态判定逻辑输出疲劳结论。整套资料包含源码、模型权重、数据集和使用说明适合做毕业设计的学生也适合想快速跑通一个端到端视觉项目的工程师。它最大的价值在于不用从零标注数据、不用自己搭训练框架拿到就能跑跑通就能改。但「能跑」和「能用」之间隔着环境配置、数据格式、阈值调参三道坎下面按落地顺序拆开讲。2. 环境配置与 YOLOv5 源码跑通conda 建环境到第一帧推理2.1 为什么选 YOLOv5 而不是关键点方案疲劳检测有两条主流路线。一条是面部关键点回归比如用 Dlib 或 MediaPipe 定位眼睛轮廓再算 EAR眼睛纵横比判断睁闭。另一条是目标检测直接框出睁眼、闭眼、张嘴、打哈欠等类别。关键点方案轻量但对头部姿态敏感侧脸或戴眼镜时关键点容易漂。YOLOv5 走检测路线把「闭眼」「打哈欠」当成独立类别来学鲁棒性更好而且训练和部署工具链成熟社区资料多出问题好查。从工程角度看选 YOLOv5 还有一个现实理由这个项目的资料包里已经带了训练好的权重和标注好的数据集。如果换成关键点方案你得自己写 EAR 阈值逻辑还得处理不同人眼型差异调参成本反而更高。YOLOv5 的检测结果是一个个带类别和置信度的框后续逻辑只需要判断「闭眼框连续出现多少帧」就能出结论代码结构清晰也方便做可视化。需要提醒的是YOLOv5 官方仓库迭代过多个版本不同版本对 PyTorch 和 CUDA 的要求不一样。这个项目标题没有写明具体版本号所以下面给的是通用配置思路实际以你拿到的源码里 requirements.txt 为准。2.2 conda 环境搭建与依赖安装第一步永远是隔离环境。我一般用 conda 建一个 Python 3.8 的环境因为 YOLOv5 早期版本对 3.9 以上支持不够稳。# 创建并激活环境Python 版本按源码要求调整 conda create -n fatigue python3.8 -y conda activate fatigue # 安装 PyTorchCUDA 版本按自己显卡驱动选这里以 cu118 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 进入源码目录安装项目依赖 cd yolov5-fatigue pip install -r requirements.txt这段命令的逻辑是先隔离环境避免和系统里其他项目冲突再装 PyTorch 主框架最后装 YOLOv5 自己的依赖。参数说明python3.8是版本约束cu118对应 CUDA 11.8如果你没有 NVIDIA 显卡把 index-url 换成 CPU 版本即可。装完后用python -c import torch; print(torch.cuda.is_available())验证返回 True 说明 GPU 可用。常见翻车点requirements.txt 里可能锁定了某个旧版 numpy 或 opencv直接装会和 PyTorch 冲突。遇到报错先看是哪两个包版本打架手动降级或升级其中一个不要无脑pip install -U全升那样更容易崩。2.3 用自带权重跑通第一帧推理环境好了先别急着训练用项目自带的模型权重跑一张图确认推理链路通。# 对单张图片做推理--weights 指向自带权重文件 python detect.py --weights weights/best.pt --source data/samples/driver_01.jpg --conf 0.4 --device 0 # 对一段视频做推理结果默认保存在 runs/detect/exp 下 python detect.py --weights weights/best.pt --source data/samples/driver_fatigue.mp4 --conf 0.4 --device 0逻辑说明detect.py是 YOLOv5 的推理入口--weights指定模型文件--source可以是图片、视频或摄像头编号--conf是置信度阈值--device 0表示用第一块 GPU。跑完后去runs/detect/exp看输出如果框出了眼睛和嘴巴且类别正确说明权重和代码匹配。参数怎么调--conf默认 0.25疲劳检测场景建议提到 0.4 到 0.5因为误检一个「闭眼」比漏检更烦人会频繁误报。--iou控制重叠框合并一般保持默认 0.45。如果显存不够加--img-size 416降低输入分辨率速度会快但小目标精度下降。3. 数据集格式与训练自己的疲劳数据从标注到 best.pt3.1 疲劳检测数据集的类别设计与标注规范这个项目自带的数据集大概率已经标好了但你要用自己的数据时类别设计是第一个决策点。常见做法是分四类open_eye、closed_eye、open_mouth、yawn。也有人只分两类normal 和 fatigue把判断完全交给模型。两种都能用区别在于可解释性。四类方案的好处是中间结果可见你能看到模型到底框到了什么调阈值时有依据。两类方案标注工作量小但模型学的是一个抽象概念出问题时不好排查。我一般推荐四类因为疲劳检测的误报代价高可解释性比省事更重要。标注用 LabelImg 或 Roboflow 都行输出 YOLO 格式每张图对应一个 txt每行是类别id 中心x 中心y 宽 高坐标都归一化到 0 到 1。注意归一化是除以图片宽高不是除以最大边这个坑新手常踩标出来的框会整体偏移。3.2 把标注数据转成 YOLOv5 训练格式YOLOv5 要求特定的目录结构常见做法是建一个 datasets 文件夹里面分 images 和 labels各自再分 train 和 val。import os import random import shutil # 原始图片和标注文件目录 img_dir raw/images label_dir raw/labels # 输出目录 out_root datasets/fatigue for split in [train, val]: os.makedirs(f{out_root}/images/{split}, exist_okTrue) os.makedirs(f{out_root}/labels/{split}, exist_okTrue) # 收集所有图片名按 8:2 划分 names [f for f in os.listdir(img_dir) if f.endswith(.jpg)] random.shuffle(names) split_idx int(len(names) * 0.8) train_names names[:split_idx] val_names names[split_idx:] def copy_files(file_list, split): for name in file_list: stem os.path.splitext(name)[0] shutil.copy(f{img_dir}/{name}, f{out_root}/images/{split}/{name}) # 标注文件同名但后缀是 txt shutil.copy(f{label_dir}/{stem}.txt, f{out_root}/labels/{split}/{stem}.txt) copy_files(train_names, train) copy_files(val_names, val) print(ftrain: {len(train_names)}, val: {len(val_names)})逻辑说明先建好 YOLOv5 要求的目录树再打乱数据按 8:2 切分最后把图片和同名标注一起复制过去。参数说明0.8是训练集比例数据量少于 2000 张时可以调到 0.85 让模型多见点数据random.shuffle前建议设随机种子保证每次划分一致方便复现。划分完还要写一个 data.yaml告诉 YOLOv5 数据在哪、有几类、类名是什么。# datasets/fatigue/data.yaml path: ./datasets/fatigue train: images/train val: images/val nc: 4 names: [open_eye, closed_eye, open_mouth, yawn]nc是类别数必须和 names 长度一致否则训练启动就报错。path用相对路径时训练命令要在项目根目录执行。3.3 训练参数怎么设yolov5s 起步的实操配置训练命令本身不复杂关键是参数选择。# 从预训练权重开始训练避免从零学 python train.py \ --data datasets/fatigue/data.yaml \ --weights yolov5s.pt \ --epochs 100 \ --batch-size 16 \ --img-size 640 \ --device 0 \ --project runs/train \ --name fatigue_v1逻辑说明--weights yolov5s.pt加载官方预训练权重做迁移学习比随机初始化收敛快很多。--epochs 100是训练轮数疲劳检测数据量通常不大100 轮够用但要看验证集 loss 是否还在降。--batch-size 16受显存限制8G 显存跑 640 分辨率大概能到 16不够就降到 8。--img-size 640是输入分辨率眼睛是小目标不建议低于 416。参数怎么改如果训练集少于 1000 张把--epochs提到 150 到 200同时加--freeze 10冻结前 10 层防止过拟合。如果验证集 mAP 一直上不去先检查标注有没有漏标或错标数据问题比调参更常见。训练完 best.pt 在runs/train/fatigue_v1/weights/下拿它替换推理命令里的权重路径即可。4. 疲劳判定逻辑与实时推理从检测框到告警信号4.1 用帧计数做疲劳状态判定YOLOv5 只负责框目标疲劳结论要靠后处理逻辑。最常见的做法是滑动窗口计数连续 N 帧检测到闭眼或打哈欠就判定疲劳。from collections import deque # 用双端队列保存最近 30 帧的检测状态 window deque(maxlen30) EYE_CLOSED_ID 1 YAWN_ID 3 FATIGUE_RATIO 0.6 def update_fatigue(detections): # detections 是当前帧的类别 id 列表 has_closed EYE_CLOSED_ID in detections has_yawn YAWN_ID in detections window.append(1 if (has_closed or has_yawn) else 0) # 窗口内疲劳帧占比超过阈值就告警 ratio sum(window) / len(window) return ratio FATIGUE_RATIO逻辑说明deque(maxlen30)固定窗口长度新帧进来旧帧自动弹出。每帧只要出现闭眼或打哈欠就记 1否则记 0。窗口内 1 的占比超过 0.6 就触发告警。参数说明窗口 30 帧在 30fps 下约等于 1 秒FATIGUE_RATIO调到 0.6 是经验值调低更敏感但误报多调高更迟钝但漏报多。实际项目里我会把这个阈值做成可配置项方便不同场景调整。这个逻辑的边界在于它假设帧率稳定。如果视频卡顿导致帧率波动窗口对应的时间就不准。稳妥做法是用时间戳而不是帧数来算窗口但实现会复杂一些毕业设计场景用帧计数足够。4.2 实时摄像头推理与告警输出把推理和判定串起来接摄像头做实时检测。# source 设为 0 表示调用默认摄像头 python detect.py --weights runs/train/fatigue_v1/weights/best.pt --source 0 --conf 0.45 --device 0 --view-img--view-img会弹出实时窗口显示检测结果。如果要加声音告警需要在 detect.py 的绘图逻辑后插入判定代码检测到疲劳时调用播放音频的库。注意摄像头推理对帧率敏感YOLOv5s 在普通显卡上 640 分辨率大概能到 30fps 以上够用如果掉到 15fps 以下把--img-size降到 416 或换 yolov5n 轻量模型。提示实时推理时--conf不要设太低0.3 以下会框出大量误检后处理逻辑被噪声淹没告警会疯狂触发。5. 避坑与排查疲劳检测项目最常见的 5 个翻车点5.1 现象训练 loss 正常但验证 mAP 一直是 0原因通常是 data.yaml 里的路径写错或者 labels 目录下没有对应的 txt 文件。YOLOv5 找不到标注时不会报错而是当成背景图训练loss 会降但模型学不到东西。解决训练前用脚本检查每张图是否有同名 txt且 txt 里每行格式是 5 个值。路径统一用相对路径训练命令在项目根目录执行。5.2 现象推理时框的位置整体偏移原因是标注时归一化算错了。有人用坐标除以图片最大边而不是对应边导致宽高比例失真。YOLO 格式要求 x 和 w 除以图片宽y 和 h 除以图片高。解决写个校验脚本把标注框还原到图上画出来肉眼确认是否贴合目标。这个步骤花五分钟能省几小时排查。5.3 现象闭眼和睁眼频繁混淆原因是这两类视觉差异小尤其在小分辨率下。640 输入时眼睛区域可能只有几十像素模型分不清。解决把--img-size提到 800 或 1024代价是显存和速度。另一个办法是在数据增强里加马赛克和随机缩放让模型多见不同尺度的眼睛。如果还不行考虑先用人脸检测裁出眼部区域再对眼部区域做分类这是两阶段方案精度更高但工程更复杂。5.4 现象换个人测试就失效原因是训练数据里驾驶员太少模型过拟合到特定人脸。疲劳检测数据集常见问题是同一个人的多帧被分到训练和验证集导致验证指标虚高。解决按人划分数据集同一个人要么全在训练集要么全在验证集。标注时记录驾驶员 id划分时按 id 分组。这个坑在毕业设计里特别常见答辩时被问到泛化能力就露馅。5.5 现象部署到树莓派等边缘设备跑不动原因是 YOLOv5s 对边缘设备还是偏重CPU 推理一帧要几百毫秒。解决导出 ONNX 或 NCNN 格式用推理引擎加速。常见做法是python export.py --weights best.pt --include onnx再用 onnxruntime 加载。树莓派 5 上跑 yolov5n 加 416 分辨率优化后能到几帧每秒做低频检测够用。如果要求实时考虑换更轻量的模型或加加速棒。6. 把疲劳检测做成可演示的毕业设计三个提分技巧第一个技巧是加可视化面板。光弹个检测框太单薄用 OpenCV 在画面角落画一个状态条实时显示疲劳占比和告警状态再叠加帧率和推理耗时。答辩时老师看到的是一个完整系统不是一段脚本。实现上就是在 detect.py 的绘图函数里多画几个矩形和文字代码量不大但观感提升明显。第二个技巧是留一份对比实验记录。同一个测试视频分别用 yolov5n、yolov5s、yolov5m 跑一遍记录 mAP、帧率、模型大小做成表格放进论文。这能体现你做过选型思考而不是随便拿个模型就跑。表格里重点标出精度和速度的权衡点说明你为什么最终选某个模型。模型mAP0.5帧率(FPS)模型大小yolov5n待测待测待测yolov5s待测待测待测yolov5m待测待测待测表格里的数据必须自己跑出来填不要抄网上的因为你的数据集和硬件环境不同数字没有可比性。跑三组实验大概多花两小时但答辩时被问到「为什么不用更大的模型」你能直接答上来。第三个技巧是准备一个失败案例集。故意找几段模型表现差的视频比如夜间红外画面、戴墨镜、侧脸分析失败原因并给出改进方向。这比只展示成功案例更有说服力说明你清楚方案的边界在哪。我见过太多毕业设计只放一段完美演示老师一问边界就答不上来。最后一个习惯把训练日志和推理日志都存好用 tensorboard 看 loss 曲线和 mAP 曲线。答辩前回看这些曲线能快速回忆起哪次调参有效、哪次是玄学。这个习惯在以后做任何模型项目都用得上不只是疲劳检测。希望帮到你。本文还有配套的精品资源点击获取
