news 2026/9/2 8:20:47

基于YOLOv5与Deepsort的驾驶员行为检测:从算法原理到工程实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于YOLOv5与Deepsort的驾驶员行为检测:从算法原理到工程实战

简介:本资源是一套面向高校本科生的毕业设计级驾驶员行为分析系统,聚焦分心驾驶与疲劳驾驶两大交通安全核心问题,融合YOLOv5目标检测与DeepSORT多目标跟踪技术,实现端到端的实时行为识别与预警。资源共59个文件,涵盖20个Python主模块(如mydetect.py、myfatigue.py、ui_mainwindow.py)、18个配置与模型定义yaml文件(含yolov5s/x/l/m多版本架构)、13个编译缓存pyc及配套文档(手册.docx)、演示视频(.mp4)、人脸关键点模型(.dat)、预训练权重(.pt)和Docker部署脚本等,整体压缩包118.04MB,结构清晰、模块解耦,便于理解与二次开发。已有106人学习下载,项目为作者手打高分毕设,含完整中文注释、UI界面与实操GIF动图,导师认可度高,特别适合深度学习入门者开展课程设计、期末大作业或毕业课题实践。

1. 项目缘起:从“毕业设计”到“实用系统”的跨越

每年毕业季,计算机视觉方向的学生都会面临一个经典难题:如何选择一个既有技术深度、又能体现工程能力,同时还能做出实际效果的毕业设计选题。我当年也在这个十字路口徘徊了很久,直到在实习中亲眼目睹了几起因驾驶员分心或疲劳导致的险情,才最终下定决心,要把这个“纸上谈兵”的课题,变成一个真正能跑起来的、有模有样的检测系统。今天分享的这个“基于深度学习+YOLOv5+Deepsort的驾驶员分心驾驶行为疲劳+危险行为检测”项目,就是那次探索的成果。它不仅仅是一份代码和文档,更是一套从算法选型、模型训练、工程集成到效果优化的完整实战记录。

这个项目的核心目标很明确:利用车载摄像头或模拟视频流,实时分析驾驶员的行为,自动识别出如使用手机、抽烟、未系安全带、频繁打哈欠、闭眼、低头等危险状态,并及时发出预警。听起来像是高级辅助驾驶系统(ADAS)或车队管理中的功能,对吧?没错,其技术内核确实相通。但对于一个毕业设计而言,它的价值在于,你能够用相对成熟的开源工具(YOLOv5做目标检测,Deepsort做目标跟踪),串联起一个完整的视觉分析流水线,并亲手解决其中遇到的各种“坑”。这比单纯复现一篇顶会论文的算法,更能锻炼你的工程思维和解决问题的能力。

接下来,我会抛开那些华而不实的理论堆砌,直接切入实战。我会详细拆解为什么选YOLOv5而不是其他版本,Deepsort如何与它无缝衔接,数据标注有哪些“骚操作”能提升模型效果,以及最终部署时如何平衡精度与速度。无论你是正在为毕设发愁的学生,还是对智能驾驶感知模块感兴趣的开发者,相信这份“踩坑实录”都能给你带来直接的帮助。

2. 技术栈深度剖析:YOLOv5与Deepsort为何是“黄金搭档”

在做技术选型时,面对YOLO系列从v3到v8的众多版本,以及SORT、DeepSORT、ByteTrack等各种跟踪算法,很容易陷入选择困难。我最终敲定YOLOv5+Deepsort这个组合,是经过多方面权衡和实际测试的,绝非盲目跟风。

2.1 为什么是YOLOv5,而不是v4、v7或v8?

首先必须澄清一个误区:版本号越高并不绝对意味着越适合你的项目。YOLOv5在2020年由Ultralytics发布,虽然并非YOLO原作者作品,但其工程化程度极高,对于毕业设计或快速原型开发来说,是“友好度”最高的选择。

  • 工程化与易用性:YOLOv5的代码库结构清晰,配置文件(.yaml)管理模型结构和训练参数的方式非常直观。其提供的预训练模型(s, m, l, x)覆盖了从轻量到高精度的需求,且加载和微调(fine-tuning)极其方便。相比之下,YOLOv4的Darknet框架对新手不够友好,环境配置复杂;YOLOv7和v8虽然性能有提升,但在项目周期紧张的毕设中,其更复杂的结构和可能遇到的兼容性问题会成为时间杀手。
  • 训练效率与资源需求:YOLOv5的训练速度快,且对GPU内存的要求相对温和。在单张RTX 3060这样的消费级显卡上,用yolov5s.pt预训练模型在自己的数据集上微调,几小时内就能得到不错的效果。这对于计算资源有限的学生群体至关重要。
  • 丰富的社区生态:YOLOv5拥有庞大的用户社区,这意味着你在Github、知乎、CSDN上几乎能搜到所有你可能遇到的问题的解决方案。从数据标注格式(YOLO格式的txt文件)到模型导出(ONNX, TorchScript),都有成熟的工具链和大量教程。

当然,YOLOv5并非没有缺点,例如其创新性被认为不如后续版本。但对于一个以应用和工程实现为核心的毕设,稳定、易用、社区支持好这三点,足以让它成为首选。

2.2 Deepsort:为检测框注入“身份”的跟踪器

目标检测(YOLOv5)只能告诉你每一帧画面里有什么(如:一个人,一个手机),但它不知道上一帧的这个人和这一帧的这个人是不是同一个。这就是目标跟踪要解决的问题。Deepsort(Deep Simple Online and Realtime Tracking)是在经典SORT算法基础上的增强版,其核心贡献是引入了外观特征(Appearance Feature)关联。

  • SORT的局限:SORT算法仅使用卡尔曼滤波预测目标运动轨迹,并通过匈牙利算法基于IoU(交并比)进行关联。当目标发生快速运动、遮挡或检测器漏检时,很容易发生ID切换(ID Switch)。
  • Deepsort的改进:Deepsort在运动关联的基础上,增加了一个深度外观描述子(通常是一个预训练的ReID网络提取的特征向量)。即使目标被短暂遮挡后重现,只要外观特征足够相似,Deepsort也能将其正确关联回原来的ID。这对于驾驶员行为分析至关重要——我们需要持续跟踪同一个驾驶员,以分析其行为序列(如持续闭眼时长),而不是每帧都当成一个新的人。

在项目中,我们将YOLOv5实时输出的检测框(Bounding Box)和对应的类别置信度,送入Deepsort跟踪器。Deepsort会为每个被跟踪的目标分配一个唯一的ID,并输出该ID的连续轨迹。这样,我们就把“帧级别的检测”升级为了“目标级别的跟踪”。

2.3 工作流程串联

整个系统的Pipeline可以概括为以下几步:

  1. 视频流输入:读取摄像头或视频文件。
  2. 目标检测:每一帧图像送入YOLOv5模型,得到所有检测目标(人、手机、香烟等)的边界框(x1, y1, x2, y2)、置信度(conf)和类别(cls)
  3. 目标跟踪:将当前帧的检测结果(框、置信度)输入Deepsort。Deepsort内部完成:
    • 卡尔曼滤波预测已有跟踪目标在当前帧的位置。
    • 计算检测框与预测框之间的运动匹配代价(马氏距离)和外观匹配代价(余弦距离)。
    • 使用匈牙利算法完成最优匹配,更新已有跟踪器的状态,并为新目标创建跟踪器。
  4. 行为分析:基于跟踪器输出的带有唯一ID的连续目标序列,进行高层行为逻辑判断。例如:
    • 疲劳检测:跟踪驾驶员面部(ID=1),连续N帧检测到“闭眼”状态,且持续时间超过阈值T,则判定为疲劳。
    • 分心驾驶:跟踪驾驶员手部或身体区域(ID=1),同时跟踪到“手机”类别(ID=2)且其边界框与驾驶员边界框在空间上长时间接近,则判定为使用手机。
  5. 预警与输出:在视频帧上绘制检测框、跟踪ID及行为状态,并可触发声音或界面警告。

这个流程看似直接,但其中每一步都有大量细节和调优空间,这也是项目从“能跑通”到“效果好”的关键。

3. 从零到一:构建你自己的驾驶员行为数据集

公开的驾驶员行为数据集如StateFarm Distracted Driver Detection、DMD等,虽然质量高,但往往场景比较单一,或者不符合国内常见的驾驶舱环境。为了获得更好的模型效果,自制数据集几乎是必经之路。这个过程耗时耗力,但却是理解计算机视觉项目全流程的宝贵一课。

3.1 数据采集与场景设计

采集数据的原则是尽可能贴近你的应用场景

  • 设备:使用普通的手机摄像头或USB摄像头即可。分辨率建议1080p,帧率30fps足够。
  • 场景:在确保安全的前提下(强烈建议在静止车辆或模拟驾驶舱中进行),模拟多种状态:
    • 正常驾驶:双手握方向盘,目视前方。
    • 分心行为:单手或双手离开方向盘接打电话、操作手机、抽烟、喝水、调整中控、与副驾交谈(转头)。
    • 疲劳行为:打哈欠(张大嘴)、频繁眨眼、闭眼2秒以上、点头(头部前倾)。
  • 多样性:邀请不同性别、发型、是否戴眼镜的“驾驶员”参与采集。在不同光照条件(白天、夜间、隧道明暗变化)下采集。这是提升模型泛化能力的关键。
  • 数量:每个类别至少收集300-500张有效图片。初期可以少一些,用于快速验证流程。

3.2 数据标注的“灵魂”:YOLO格式与类别定义

标注工具推荐使用labelImg或更高效的CVATRoboflow。标注的核心是生成YOLOv5所需的txt文件。

  • 类别定义:你需要预先定义好要检测的类别及其对应的ID。例如:

    # data.yaml 中的names部分 names: 0: person # 驾驶员 1: cellphone # 手机 2: cigarette # 香烟 3: eyes_closed # 闭眼 4: yawning # 打哈欠 5: no_belt # 未系安全带(这里简化了,实际可能需要检测安全带本身)

    注意:这里将“闭眼”、“打哈欠”作为直接检测的类别,是一种简化方案。更精细的做法是:先检测人脸,再在人脸区域检测关键点(如dlib或MediaPipe),通过关键点计算眼睛纵横比(EAR)和嘴巴纵横比(MAR)来判断状态。但直接检测行为状态对于毕设来说,更直观, pipeline更简单。

  • YOLO格式详解:每个txt文件与图片同名,每一行代表一个标注对象,格式为:<class_id> <x_center> <y_center> <width> <height>

    • <class_id>: 类别ID,从0开始。
    • <x_center> <y_center>: 边界框中心点的x, y坐标,已归一化(即除以图片宽度和高度,值在0-1之间)。
    • <width> <height>: 边界框的宽度和高度,同样已归一化。 例如,一张800x600的图片上,标注了一个位于(200, 300),宽高为100x150的“手机”,其标注行应为:
    1 0.3125 0.5 0.125 0.25 # x_center = (200 + 100/2) / 800 = 250 / 800 = 0.3125 # y_center = (300 + 150/2) / 600 = 375 / 600 = 0.5 # width = 100 / 800 = 0.125 # height = 150 / 600 = 0.25

3.3 数据增强与数据集划分

YOLOv5的训练脚本内置了强大的数据增强功能(Mosaic, Random affine, HSV调整等),你只需要在data.yaml中配置即可。但前期也可以手动增加一些多样性:

  • 数据集划分:按70%(训练集),20%(验证集),10%(测试集)的比例随机划分。测试集必须完全不参与训练和调参,用于最终评估。
  • 处理类别不平衡:如果“正常驾驶”的图片远多于“抽烟”的图片,模型会偏向于多数类。解决方法:1)过采样少数类图片;2)在YOLOv5的损失函数中设置类别权重;3)在数据增强时,对少数类图片应用更强的增强。

准备好images(图片)和labels(标注txt)文件夹,并编写好data.yaml配置文件,数据集部分就告一段落了。这个过程的严谨程度,直接决定了模型性能的天花板。

4. 模型训练与调优:让YOLOv5“认识”你的场景

有了数据集,下一步就是训练模型。这里我分享几个让训练效果立竿见影的关键步骤和参数调优经验。

4.1 环境搭建与预训练模型

# 克隆YOLOv5官方仓库(建议使用固定版本,如v6.0,兼容性最好) git clone -b v6.0 https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt # 安装依赖

安装过程如果遇到PyTorch或CUDA问题,去PyTorch官网根据你的CUDA版本选择正确的安装命令。

下载预训练模型。对于驾驶员检测(人、手机等物体),使用在COCO数据集上预训练的yolov5s.pt是一个非常好的起点。它已经学会了检测“人”这个通用概念,能极大加速我们特定场景的收敛。

# 在yolov5目录下 weights/yolov5s.pt # 通常克隆仓库时会自带,如果没有就手动下载

4.2 核心训练配置与启动

主要的配置都在data.yaml和模型配置文件(如models/yolov5s.yaml)中,但训练命令的参数才是灵魂。

一个基础的训练命令如下:

python train.py \ --img 640 \ # 训练图像尺寸,保持640平衡速度与精度 --batch 16 \ # 批次大小,根据你的GPU内存调整,8, 16, 32等 --epochs 100 \ # 训练轮数,通常100-300轮 --data ./data/my_driver_data.yaml \ # 你的数据集配置文件路径 --cfg ./models/yolov5s.yaml \ # 模型结构配置文件 --weights ./weights/yolov5s.pt \ # 预训练权重 --name driver_detection_v1 \ # 本次实验的名称,用于保存结果 --cache \ # 使用缓存加速训练(需要足够RAM) --device 0 # 使用第0块GPU,CPU则用 --device cpu
  • --img 640: 这是YOLOv5的默认输入尺寸。增大(如1280)会提升对小目标的检测能力,但会显著增加显存消耗和训练时间。对于车内场景,640通常足够。
  • --batch 16:批次大小是影响训练稳定性和效果的关键。在显存允许的情况下,尽量设大。如果出现“CUDA out of memory”错误,就减小batchimg尺寸。
  • --epochs: 100轮是个不错的起点。可以通过观察验证集损失val_loss不再下降,或指标mAP@0.5趋于平缓来判断是否早停(early stopping)。

4.3 监控训练过程与关键指标解读

训练开始后,YOLOv5会在runs/train/driver_detection_v1目录下生成大量可视化结果。最重要的两个文件是results.png训练过程日志

  • 损失曲线(results.png): 关注train/box_loss,train/obj_loss,train/cls_loss以及对应的val损失。理想情况是所有损失曲线平稳下降,最后趋于平缓。如果训练损失下降但验证损失上升,可能是过拟合了。
  • 性能指标:
    • mAP@0.5: 这是最核心的指标。表示在IoU阈值为0.5时的平均精度(mean Average Precision)。值越高越好,达到0.8以上说明模型很不错。
    • mAP@0.5:0.95: 在IoU阈值从0.5到0.95(步长0.05)上的平均mAP,是更严格的指标。
    • precisionrecall: 精确率和召回率。高精确率意味着“说是A的,基本真是A”(误报少);高召回率意味着“是A的,基本都被找出来了”(漏报少)。两者往往需要权衡。

4.4 调优实战技巧

  1. 学习率调整--lr0参数默认是0.01。如果训练初期损失震荡剧烈,可以尝试调小到0.001。YOLOv5内置了余弦退火等学习率调度器,通常不用手动调整。
  2. 数据增强强度:在data.yaml中或通过--hyp参数指定超参数文件。可以调整hsv_h,hsv_s,hsv_v(色彩抖动)、degrees(旋转)、translate(平移)等。对于车内相对稳定的场景,增强不宜过强,否则会引入不现实的噪声。
  3. 解决“手机”等小目标检测差的问题
    • 数据层面:确保数据集中有足够多、标注精准的小目标样本。可以特意采集一些手机在画面边缘或较远的图片。
    • 模型层面:YOLOv5的P5模型(默认)有三个检测头(大、中、小目标)。可以尝试使用更大的模型(如yolov5m.ptyolov5l.pt),它们有更强大的特征提取能力。
    • 训练层面:尝试减小--img尺寸(如416),有时反而能提升小目标召回,因为特征图相对变“大”了。这是一个需要实验的权衡。
  4. 过拟合应对:如果验证集指标远低于训练集,增加数据增强、使用--weights的预训练模型、减少模型复杂度(用s而不是l)、或增加正则化(如--dropout)都可能有效。

训练完成后,最好的模型权重会保存在runs/train/driver_detection_v1/weights/best.pt。这个best.pt就是我们后续与Deepsort集成的核心。

5. 集成Deepsort与行为逻辑判断

模型训练好了,接下来就是让检测框“动起来”,并赋予它们行为含义。这部分是项目的“大脑”,将原始的视觉感知转化为高层语义信息。

5.1 Deepsort集成详解

网上有很多YOLOv5+Deepsort的集成代码,但很多只是简单拼接,不稳定。我基于一个稳定的开源实现进行了深度改造,核心在于匹配阈值的管理跟踪器生命周期管理

# 伪代码逻辑展示核心集成步骤 import torch from yolov5.models.experimental import attempt_load from deep_sort_realtime.deepsort_tracker import DeepSort # 1. 加载训练好的YOLOv5模型 device = torch.device('cuda:0') model = attempt_load('./runs/train/driver_detection_v1/weights/best.pt', device=device) model.eval() # 2. 初始化Deepsort跟踪器 # max_age: 一个跟踪器连续多少帧未匹配到检测框则删除。设置太小容易丢失目标,太大会维持过多“僵尸”跟踪器。车内场景建议30-50。 # n_init: 一个检测需要被连续关联多少帧才被确认为一个新的跟踪目标。防止噪声误检,建议3-5。 tracker = DeepSort(max_age=45, n_init=3) # 3. 视频流循环 while True: frame = get_frame() # 获取一帧 # YOLOv5推理 results = model(frame, augment=False) # augment=False关闭推理时增强 detections = results.xyxy[0].cpu().numpy() # 获取检测结果 [x1, y1, x2, y2, conf, cls] # 4. 过滤低置信度检测框,并准备Deepsort输入格式 conf_threshold = 0.5 dets_for_tracking = [] for det in detections: x1, y1, x2, y2, conf, cls_id = det if conf > conf_threshold: # Deepsort需要 [x1, y1, w, h, conf, cls_id] 格式 dets_for_tracking.append([x1, y1, x2-x1, y2-y1, conf, int(cls_id)]) # 5. 更新跟踪器 tracks = tracker.update_tracks(dets_for_tracking, frame=frame) # 6. 处理跟踪结果 for track in tracks: if not track.is_confirmed(): # 跳过未确认的跟踪 continue track_id = track.track_id ltrb = track.to_ltrb() # 获取边界框 [x1, y1, x2, y2] class_id = track.get_det_class() # 获取检测类别 # 在帧上绘制跟踪框和ID cv2.rectangle(frame, (int(ltrb[0]), int(ltrb[1])), (int(ltrb[2]), int(ltrb[3])), color, 2) cv2.putText(frame, f'ID:{track_id} {class_names[class_id]}', ...)

关键参数调优经验

  • max_age:在驾驶员行为分析中,驾驶员目标基本持续存在。但当驾驶员大幅转头或被遮挡时,检测框可能短暂丢失。max_age设置过短(如10帧),会导致ID频繁切换;设置过长(如100帧),会残留大量无效跟踪器。经过实测,45是一个在稳定性和及时清理之间较好的平衡点。
  • n_init:防止因单帧误检而创建虚假跟踪器。设为3意味着需要连续3帧都检测到同一个目标,才为其创建跟踪ID。这大大提升了跟踪的稳定性。
  • 检测置信度阈值:在推理时(conf_threshold)可以设得比训练时评估的阈值(默认0.001)高,比如0.5或0.6,以减少送入跟踪器的噪声检测框,让跟踪更稳定。

5.2 基于跟踪ID的行为状态机

这是项目的业务逻辑核心。我们需要为每个被跟踪的驾驶员(track_id)维护一个状态机,而不是基于单帧判断。

# 一个简化的疲劳检测状态机示例 class DriverState: def __init__(self, track_id): self.track_id = track_id self.eyes_closed_counter = 0 # 连续闭眼帧数计数器 self.is_fatigued = False self.fatigue_threshold = 30 # 连续闭眼30帧(假设1秒=30帧,即1秒)判定疲劳 def update(self, current_frame_detections): # current_frame_detections 是当前帧所有检测到的‘闭眼’框 # 假设我们已经通过空间关系(如框的中心位置)将‘闭眼’框匹配到了这个驾驶员跟踪框上 if matched_eyes_closed_detection: self.eyes_closed_counter += 1 if self.eyes_closed_counter >= self.fatigue_threshold and not self.is_fatigued: self.is_fatigued = True trigger_alarm(f"驾驶员 {self.track_id} 疲劳驾驶!") else: # 当前帧没有检测到闭眼,重置计数器 self.eyes_closed_counter = 0 if self.is_fatigued: self.is_fatigued = False # 可以添加一个“疲劳状态恢复”的逻辑 # 在主循环中管理所有驾驶员状态 driver_states = {} # track_id -> DriverState object for track in tracks: track_id = track.track_id if track_id not in driver_states: driver_states[track_id] = DriverState(track_id) # 更新该驾驶员的状态 driver_states[track_id].update(current_detections)

对于“使用手机”的检测,逻辑类似但更复杂一些:需要判断“手机”这个检测框与“驾驶员”这个跟踪框的空间关系(如IoU或中心点距离)在连续多帧内是否保持亲密,并且驾驶员的手部或视线方向可能也有变化(这部分可以通过额外添加“手部”检测或头部姿态估计来增强)。

5.3 多线程与性能优化

实时视频处理是计算密集型的。YOLOv5推理和Deepsort跟踪都比较耗时。为了达到实时(如25-30 FPS),必须进行优化:

  • 异步处理:使用生产者-消费者模型。一个线程专门负责从摄像头抓取帧(生产者),另一个线程负责进行YOLOv5推理和跟踪(消费者)。这样可以避免因处理速度慢而掉帧。
  • 推理优化
    • 使用torch.jit.tracetorch.jit.script将模型转换为TorchScript,能获得一定的加速。
    • 使用半精度(FP16)推理:在支持Tensor Core的GPU上,能大幅提升速度且精度损失很小。在YOLOv5推理时设置--half参数。
    • 考虑使用TensorRT或ONNX Runtime进行更极致的部署优化,这对毕设来说属于加分项。
  • 跟踪器优化:Deepsort的外观特征提取网络(如Mars-small128.pb)是计算瓶颈之一。如果对精度要求不是极端高,可以尝试使用更轻量的ReID模型,或者在检测置信度很高时,跳过外观特征匹配,仅用运动信息(退化到SORT)。

6. 效果评估、常见问题与部署思考

项目做完了,怎么知道它好不好?除了肉眼观察运行视频,还需要一些定量的评估和面对实际问题的思考。

6.1 如何评估你的系统?

对于这样一个多模块系统,需要分层评估:

  1. 目标检测模块:使用保留的测试集,运行python val.py --data ./data/my_driver_data.yaml --weights ./weights/best.pt,查看mAP@0.5等指标。这是基础。
  2. 跟踪模块:评估跟踪性能更复杂。可以手动标注一小段视频(比如1000帧)中所有目标的真实ID和位置,然后计算:
    • 多目标跟踪精度(MOTA):综合考量误检、漏检和ID切换的指标。
    • ID切换次数(ID Switches):越少越好。 有工具如py-motmetrics可以辅助计算。对于毕设,可以定性分析:在测试视频中,驾驶员的ID是否稳定?当被副驾乘客短暂遮挡后,ID是否还能保持一致?
  3. 行为识别模块:这是最需要定性评估的。录制包含各种分心和疲劳行为的测试视频,统计系统的:
    • 检出率:发生了多少次危险行为,系统正确报警了多少次?
    • 误报率:系统报警了多少次,其中有多少次是误报(如抬手调整空调被误认为使用手机)?
    • 报警延迟:从行为发生到系统报警,间隔了多少帧?这对于疲劳检测(闭眼持续时间)尤为重要。

6.2 踩坑实录与解决方案

  • 问题一:YOLOv5检测框抖动严重,导致跟踪器ID频繁切换。

    • 原因:可能是数据集中类似场景少,模型置信度不稳定;也可能是视频编码质量差、光照闪烁。
    • 解决:1) 在数据增强中加入轻微的模糊和噪声,提升模型鲁棒性。2) 对YOLOv5输出的检测框进行时域平滑滤波,如使用卡尔曼滤波或简单的移动平均,预测当前帧框的位置,与检测结果加权融合,能有效减少抖动。3) 适当降低Deepsort的匹配阈值(max_cosine_distance),让外观特征在关联中权重更高。
  • 问题二:“闭眼”和“打哈欠”这类状态检测不准。

    • 原因:直接检测状态类别难度大,因为姿态、角度变化大。
    • 解决(进阶方案):采用“检测+关键点”的两级方案。第一步,用YOLOv5检测人脸。第二步,裁剪出人脸区域,使用轻量级关键点模型(如MediaPipe Face Mesh)检测468个面部关键点。第三步,根据关键点计算:
      • 眼睛纵横比(EAR):当EAR低于阈值并持续一段时间,判定为闭眼。
      • 嘴巴纵横比(MAR):当MAR高于阈值,判定为打哈欠。 这种方法比直接检测“闭眼”类别更稳定、更符合生理定义。
  • 问题三:在树荫、隧道口等明暗快速变化场景下,检测失效。

    • 原因:模型训练数据光照条件单一,泛化能力不足。
    • 解决:1) 在数据采集中必须包含高动态光照场景。2) 在图像预处理时,可以加入自动白平衡(AWB)直方图均衡化,减轻光照影响。3) 在模型输入前,对图像进行CLAHE(限制对比度自适应直方图均衡化)处理,效果显著。

6.3 从毕设到部署的思考

完成一个在开发机上运行的Demo只是第一步。如果要将其部署到真实的车载边缘设备(如Jetson Nano、RK3568等),还需要考虑:

  • 模型轻量化:将YOLOv5s模型通过剪枝、量化等技术进一步压缩,以适应边缘设备的算力和内存。
  • 工程化封装:将整个Pipeline封装成独立的服务,提供gRPC或HTTP API接口,方便与车载中控或其他系统集成。
  • 误报处理:真实的驾驶场景噪声极大。需要设计更复杂的后处理逻辑,例如,只有“使用手机”行为持续超过5秒才报警,或者结合车辆状态(如车速为0时,不进行疲劳报警)来降低误报。

这个项目就像一把钥匙,为你打开了智能驾驶感知领域的大门。它涉及了从数据准备、模型训练、多目标跟踪到行为理解的完整链条。过程中遇到的每一个问题,都是宝贵的经验。希望这份超详细的拆解,能帮你少走弯路,做出一个让导师眼前一亮的毕业设计,也为未来的深入探索打下坚实的基础。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 8:19:32

STM32+BQ76920工程级BMS固件设计与实现

简介&#xff1a;本资源是一套完整的锂电池管理系统&#xff08;BMS&#xff09;工程实现&#xff0c;基于STM32F103主控与TI BQ76920电池监控芯片&#xff0c;面向高校电子信息、自动化、人工智能等专业师生及嵌入式开发工程师&#xff0c;解决多节锂电的电压/温度采集、均衡控…

作者头像 李华
网站建设 2026/9/2 8:19:16

声卡恢复出厂设置全攻略:解决杂音、无声、蓝牙连接故障

最近在调试音频设备时&#xff0c;你是否也遇到过这些令人抓狂的场景&#xff1a;直播时声卡突然传出刺耳杂音&#xff0c;蓝牙耳机死活连不上&#xff0c;或者干脆一点声音都没有&#xff1f;重启、重装驱动、网上搜遍偏方都无济于事。别急&#xff0c;很多时候问题并非硬件损…

作者头像 李华
网站建设 2026/9/2 8:18:58

如何建立CANoe工程以及CANoe中的一些应用

一、选择new 然后选择CAN500kBaud1ch&#xff08;这个可以根据项目的需求&#xff09;二、就是关于串口如何调出的问题&#xff0c;如果不小心删除Write可以通过底下的小笔&#xff0c;复现出Write窗口如果不小小删除&#xff0c;见图1 如果不下心删除Network,可以通过右键&am…

作者头像 李华
网站建设 2026/9/2 8:17:57

LangGraph工作流:能跑通Demo很容易,为什么团队接入第一天就崩?

聊《同样是LangGraph&#xff0c;为什么有的能上线、有的只能演示&#xff1f;》之前&#xff0c;先说一句实在的&#xff1a;别急着背概念&#xff0c;先看它在真实项目里到底解决什么问题。摘要前阵子帮朋友看了他的Agent项目&#xff0c;代码写得挺漂亮&#xff0c;工具调用…

作者头像 李华
网站建设 2026/9/2 8:12:59

零基础入门python46:FastAPI 配置、环境变量与依赖注入

零基础入门python46&#xff1a;FastAPI 配置、环境变量与依赖注入一、上一篇课后练习讲解 上一篇练习围绕“ASGI、应用对象与自动文档”。参考做法是先运行上一篇的测试&#xff0c;再用一个成功请求和一个失败请求验证边界&#xff1b;本篇在同一项目上增加新能力。 上一篇课…

作者头像 李华
网站建设 2026/9/2 8:12:21

斯凯MRP编辑器源码深度解析:从编译打包到模拟器调试

简介&#xff1a;斯凯MRP编辑器源码是一套面向斯凯平台开发者的MRP软件工程&#xff0c;采用SGL模板开发&#xff0c;内含SGL文件浏览器、本地界面浏览文件模块与基本文件操作函数&#xff0c;可实现MRP格式文件的解包、打包&#xff0c;以及对MRP加密BMP图片的浏览。资源包共1…

作者头像 李华