尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于YOLO的疲劳检测数据集构建与模型训练实战指南

基于YOLO的疲劳检测数据集构建与模型训练实战指南 简介目标检测是计算机视觉的核心任务之一旨在从图像或视频中定位并识别出感兴趣的目标物体。其原理是通过深度神经网络学习图像特征并回归出目标的位置和类别。这项技术具有极高的实用价值是实现智能化应用的关键。在工程实践中YOLO系列算法因其出色的速度与精度平衡而广受欢迎尤其适合部署在资源受限的边缘设备上。其应用场景广泛从安防监控到自动驾驶再到工业质检无处不在。本文聚焦于一个具体且重要的应用——驾驶员疲劳检测并围绕此主题详细介绍了一个包含5163张图像、针对眼睛和嘴巴状态如闭眼、张嘴的专用YOLO数据集的构建过程。该数据集旨在解决通用数据集标注粒度不足的问题通过提供高质量的“眼睛嘴巴”状态标注为基于YOLO的疲劳检测模型训练提供了坚实基础并分享了从数据准备、模型训练到最终疲劳判定逻辑设计的完整实战经验。1. 项目概述一个专为疲劳检测打造的YOLO数据集最近在做一个关于驾驶员状态监测的项目核心需求是检测闭眼、打哈欠张嘴这些典型的疲劳特征。找了一圈公开数据集要么是通用的人脸关键点标注粒度不够细要么是纯学术研究用的数据量小且场景单一离实际应用差得远。最后我决定自己动手丰衣足食整理并标注了这份包含5163张图像的数据集涵盖了“张开嘴”、“闭上眼睛”、“闭着嘴”、“睁开眼睛”这四类关键状态。今天就把这个数据集的构建思路、标注细节、以及在YOLO框架下的应用心得完整分享出来希望能给同样在做类似疲劳检测、行为分析的朋友们提供一个高质量的起点。这个数据集的核心价值在于它的“场景针对性”和“标注实用性”。它不是简单的人脸检测而是精准定位了与疲劳强相关的局部器官状态眼睛和嘴巴。对于想用YOLO这类单阶段目标检测算法快速落地疲劳检测应用的朋友来说拿到这个数据集几乎就完成了项目中最耗时、最考验耐心的数据准备工作。你可以直接用它来训练一个能够同时识别“闭眼”和“打哈欠”的模型为后续的疲劳判定逻辑提供可靠的输入。2. 数据集构建的核心思路与设计考量2.1 为何选择“眼睛嘴巴”状态作为检测目标在疲劳检测领域基于计算机视觉的方法主流有两种一种是基于人脸关键点如Dlib 68点、MediaPipe Face Mesh通过计算眼睛纵横比EAR和嘴巴纵横比MAR来判断状态另一种就是像我们这样直接使用目标检测框出眼睛和嘴巴的开放/闭合状态。我选择后者的原因很直接追求更高的鲁棒性和更低的部署成本。基于关键点的方法对头部姿态、遮挡、图像质量非常敏感EAR/MAR的阈值需要精心调校且容易受个体差异影响。而基于YOLO的目标检测本质上是让模型自己去学习“闭着的眼睛”和“张开的嘴”在像素层面的特征模式。一旦训练好模型对光线变化、部分遮挡、不同人种的适应性通常更强。更重要的是YOLO模型可以非常方便地部署到边缘设备如Jetson系列、树莓派配合加速棒甚至手机端无需依赖复杂的关键点检测库整个流水线更简洁。2.2 数据采集与类别定义数据集总共5163张图像这个规模对于训练一个稳健的YOLO模型来说是足够的。图像来源主要是公开的行车记录仪数据集、模拟驾驶舱录像截图以及部分网络合规图片确保了场景的多样性包括白天、夜晚、隧道、强光、侧脸等多种情况。我们定义了四个互斥的类别mouth_open张开嘴通常指打哈欠或大声说话时的状态。标注框需要完整覆盖张开的嘴唇区域包括露出的牙齿如果可见。mouth_closed闭着嘴嘴唇自然闭合的状态。这是基准状态对于判断是否从闭合变为张开至关重要。eyes_closed闭上眼睛上下眼睑接触看不见瞳孔。这是疲劳的最直接指标之一。eyes_open睁开眼睛眼睛自然睁开瞳孔清晰可见。同样是重要的基准状态。注意这里没有标注整张人脸而是直接标注目标状态区域。这样做的好处是模型更专注不会被人脸的其他特征如发型、眼镜干扰检测框也更紧凑有利于后续的状态逻辑判断。2.3 标注格式与质量把控数据集采用YOLO格式的标注.txt文件与图像同名。每个标注文件包含多行每行代表一个目标物体格式为class_id x_center y_center width height。坐标和尺寸都是相对于图像宽度和高度的归一化值0到1之间。例如一张图片中有一个张开的嘴和一个闭着的眼睛其标注文件可能包含两行0 0.45 0.60 0.15 0.10 # mouth_open, class_id0 2 0.50 0.35 0.20 0.08 # eyes_closed, class_id2在标注过程中我们制定了严格的规范边界框紧密度框体必须紧贴目标边缘特别是对于mouth_open要包含嘴角最外侧。遮挡处理对于被手、方向盘、口罩等部分遮挡的眼睛或嘴巴只要可见部分超过50%且能明确判断状态仍予以标注但框体仅覆盖可见部分。这能增强模型在真实场景下的鲁棒性。多目标处理同一个人同时打哈欠和闭眼极度疲劳的情况虽然少但存在我们会分别标注mouth_open和eyes_closed两个框。类别模糊处理对于微微张开或似闭非闭的状态由三名标注员交叉审核遵循“宁可漏标不可错标”的原则确保标注一致性。3. 基于YOLOv8的模型训练实战有了高质量的数据集下一步就是把它用起来。这里我以目前生态非常完善的Ultralytics YOLOv8为例展示完整的训练流程。你完全可以根据需要替换成YOLOv5, YOLOv9等其他版本核心步骤是相通的。3.1 环境准备与数据组织首先你需要一个Python环境建议3.8以上然后安装Ultralytics包pip install ultralytics接下来按照YOLO要求组织你的数据集目录结构。假设你的项目根目录为fatigue_detection/结构应如下fatigue_detection/ ├── datasets/ │ └── fatigue/ │ ├── images/ │ │ ├── train/ # 放置训练图片如 001.jpg, 002.jpg... │ │ └── val/ # 放置验证图片 │ └── labels/ │ ├── train/ # 放置对应的训练标签txt文件 │ └── val/ # 放置对应的验证标签txt文件 ├── fatigue.yaml # 数据集配置文件 └── train.py # 训练脚本你需要将我们提供的5163张图像和标签按照大约8:2的比例或其他你习惯的比例分割到train和val文件夹中。确保images/train/里的001.jpg对应labels/train/里的001.txt。然后创建关键的fatigue.yaml配置文件# fatigue.yaml path: ./datasets/fatigue # 数据集根目录 train: images/train # 训练集相对路径 val: images/val # 验证集相对路径 # 类别列表顺序必须与标注时的class_id严格对应 names: 0: mouth_open 1: mouth_closed 2: eyes_closed 3: eyes_open3.2 模型训练与关键参数解析创建一个简单的Python脚本train.py来启动训练from ultralytics import YOLO # 加载一个预训练模型这里使用中等大小的YOLOv8m在精度和速度间取得平衡 model YOLO(yolov8m.pt) # 开始训练 results model.train( datafatigue.yaml, # 数据集配置文件路径 epochs100, # 训练轮数根据数据集大小调整 imgsz640, # 输入图像尺寸YOLOv8常用640 batch16, # 批次大小取决于你的GPU内存 device0, # 使用GPU 0如果是CPU则设为cpu workers4, # 数据加载线程数 optimizerAdamW, # 优化器AdamW通常表现不错 lr00.001, # 初始学习率 namefatigue_v8m # 本次训练的实验名称 )执行python train.py训练就开始了。控制台会输出损失曲线、精度指标等信息。这里有几个参数值得深入聊聊imgsz640YOLO会将所有图像缩放到这个尺寸进行训练。更大的尺寸如1280可能带来精度提升但会显著增加显存消耗和训练时间。对于我们的局部器官检测任务640x640的分辨率已经足够捕捉眼睛和嘴巴的细节。batch16批次大小直接影响训练稳定性和速度。如果遇到“CUDA out of memory”错误首先尝试减小batch如8或4或者减小imgsz。epochs100对于5000多张图的数据集100轮通常是一个合理的起点。你可以观察验证集精度mAP50-95曲线如果早早在某个轮数后不再上升甚至下降就可以考虑提前停止或降低学习率。预训练权重yolov8m.pt使用在COCO等大型数据集上预训练的权重进行迁移学习是快速收敛的关键。不要从零开始训练。3.3 训练过程监控与评估训练过程中Ultralytics会默认在runs/detect/fatigue_v8m/目录下保存所有结果其中weights/best.pt保存验证集上表现最好的模型权重。weights/last.pt保存最后一轮的模型权重。各种可视化图表如损失曲线、精度-召回率曲线、混淆矩阵等。最重要的评估指标是mAPMean Average PrecisionmAP50在IoU交并比阈值为0.5时的平均精度。这是最常用的指标可以粗略理解为检测框的“找对且框得不太差”的能力。mAP50-95在IoU阈值从0.5到0.95步长0.05区间内的平均mAP。这是一个更严格的指标要求检测框的定位非常精准。对于我们这个数据集因为目标眼睛、嘴巴相对较小且固定更应关注mAP50-95。一个训练良好的模型mAP50通常能达到0.95以上mAP50-95能达到0.7以上。你可以使用训练好的模型在验证集上跑一下评估yolo val modelruns/detect/fatigue_v8m/weights/best.pt datafatigue.yaml4. 从检测到疲劳判定的逻辑设计模型训练好能输出检测框和类别了但这还不是疲劳检测的终点。我们需要一套逻辑将连续的检测结果转化为“疲劳”或“清醒”的状态判断。这里分享一个经过实测有效的简单策略。4.1 基于时间窗口的状态平滑与判定单帧的检测结果是不稳定的可能偶尔有误检或漏检。因此必须引入时间维度进行平滑。我常用的是一个基于队列的滑动时间窗口方法。import collections from typing import Deque class FatigueDetector: def __init__(self, eye_close_thresh0.5, mouth_open_thresh0.5, time_window2.0, fps30): :param eye_close_thresh: 时间窗口内闭眼帧占比阈值超过则判定为疲劳闭眼 :param mouth_open_thresh: 时间窗口内张嘴帧占比阈值超过则判定为持续哈欠 :param time_window: 滑动时间窗口长度秒 :param fps: 视频帧率 self.eye_close_thresh eye_close_thresh self.mouth_open_thresh mouth_open_thresh self.window_size int(time_window * fps) # 使用双端队列保存最近N帧的状态 self.eye_state_queue: Deque[bool] collections.deque(maxlenself.window_size) # True表示闭眼 self.mouth_state_queue: Deque[bool] collections.deque(maxlenself.window_size) # True表示张嘴 def update(self, detections): 更新状态队列。detections是当前帧YOLO模型的检测结果列表。 假设每个检测对象是一个字典包含‘cls’类别id和‘conf’置信度。 current_eye_closed False current_mouth_open False for det in detections: if det[cls] 2 and det[conf] 0.6: # eyes_closed, 置信度阈值 current_eye_closed True if det[cls] 0 and det[conf] 0.6: # mouth_open, 置信度阈值 current_mouth_open True self.eye_state_queue.append(current_eye_closed) self.mouth_state_queue.append(current_mouth_open) def is_fatigue(self): 根据当前时间窗口内的历史状态判断是否疲劳 if len(self.eye_state_queue) self.window_size: return False # 窗口未填满不进行判断 eye_close_ratio sum(self.eye_state_queue) / self.window_size mouth_open_ratio sum(self.mouth_state_queue) / self.window_size # 疲劳判定逻辑闭眼比例过高或长时间张嘴打哈欠 is_eye_fatigue eye_close_ratio self.eye_close_thresh is_yawn_fatigue mouth_open_ratio self.mouth_open_thresh return is_eye_fatigue or is_yawn_fatigue这个FatigueDetector类的工作原理是每来一帧它根据YOLO的检测结果经过置信度过滤判断当前帧是否“闭眼”或“张嘴”并将这个布尔值存入固定长度的队列。当队列被填满即积累了2秒的数据后它计算队列中“闭眼”和“张嘴”各自的比例。如果闭眼比例超过50%eye_close_thresh0.5就认为驾驶员在持续闭眼如果张嘴比例超过50%就认为在持续打哈欠。任何一种情况触发则输出“疲劳”警报。4.2 逻辑调优与参数经验置信度阈值上面代码中的det[‘conf’] 0.6很重要。它过滤掉模型不确定的、低置信度的检测能有效减少误报。这个值可以通过在验证集上绘制“精度-置信度”曲线来选取最优值。时间窗口与阈值time_window2.0秒和eye_close_thresh0.5是核心参数。它们共同定义了“持续闭眼1秒以上”即报警的规则。你可以根据实际应用场景调整对于要求极其严格的场景如高速货运可以缩短时间窗口或提高阈值如闭眼0.8秒就报警对于容忍度稍高的场景可以放宽。多特征融合更高级的策略可以结合PERCLOS单位时间内眼睛闭合的比例标准或者将闭眼和打哈欠两个特征加权融合而不是简单的“或”逻辑。5. 模型优化与部署中的避坑指南5.1 提升小目标检测精度我们的目标眼睛、嘴巴在整张图中属于小目标。YOLO虽然擅长检测但小目标仍是挑战。如果你的模型在验证集上mAP50不错但mAP50-95偏低说明框的位置不够准可以尝试以下优化数据增强在fatigue.yaml或训练命令中启用更强的针对小目标的增强。YOLOv8支持丰富的增强参数model.train( ... hsv_h0.015, # 色调增强 hsv_s0.7, # 饱和度增强 hsv_v0.4, # 明度增强 degrees10.0, # 旋转角度 translate0.1, # 平移 scale0.5, # 缩放 shear2.0, # 剪切 perspective0.0005, # 透视变换对小目标有益 mosaic1.0, # Mosaic增强默认开启对丰富背景很有效 )注意增强不是越强越好过度增强可能破坏小目标的特征。建议从默认值开始逐步微调。调整锚框Anchor或使用Anchor-FreeYOLOv8默认是Anchor-Free的这简化了流程。但如果你用的是YOLOv5可能需要根据数据集聚类生成自适应的锚框。可以使用utils/autoanchor.py工具重新计算。关注损失函数确保box_loss定位损失在稳步下降。如果box_loss很高可能是定位不准。可以尝试使用CIoU、DIoU等更先进的边界框回归损失YOLOv8已集成。5.2 模型轻量化与加速部署实际落地时模型速度往往和精度一样重要。如果你的部署平台算力有限如嵌入式设备可以考虑选择更小的模型从yolov8m换成yolov8s甚至yolov8n。速度会大幅提升精度会有一定损失需要通过量化等手段弥补。模型剪枝与量化剪枝移除网络中冗余的通道或层。可以使用一些第三方库如Torch-Pruning对训练好的模型进行剪枝然后微调fine-tune。量化将模型权重从FP32转换为INT8可以大幅减少模型体积和加速推理。Ultralytics YOLOv8支持导出时量化yolo export modelbest.pt formatonnx int8导出的INT8 ONNX模型在支持INT8推理的硬件如TensorRT, OpenVINO上会有显著加速。选择高效推理后端ONNX Runtime跨平台部署简单支持CPU/GPU。TensorRTNVIDIA GPU上的极致优化需要将模型转换为TensorRT引擎。OpenVINOIntel CPU/GPU上的优化对x86架构非常友好。CoreML苹果设备iOS/macOS原生支持。5.3 常见问题与排查技巧训练Loss不下降或NaN检查数据标注首先用YOLO自带的工具可视化一下标注框是否正确yolo train datafatigue.yaml ...命令会在开始前自动验证。常见问题是标注文件格式错误、类别ID超出范围、坐标值未归一化或大于1。降低学习率过高的学习率可能导致震荡甚至发散。尝试将lr0从0.001降到0.0005或0.0001。检查图像尺寸确保所有图像都能正常读取没有损坏的图片文件。验证集mAP很低但训练集Loss正常过拟合这是最可能的原因。表现为训练集精度很高验证集精度很低。解决方案增加数据增强的强度如随机裁剪、遮挡使用早停Early Stopping在模型结构中加入Dropout层如果自定义模型或者直接收集更多样化的数据。数据分布不一致训练集和验证集的数据分布光照、场景、人物差异太大。确保你的数据分割是随机且均匀的。推理时漏检严重调整置信度阈值模型推理时有一个conf参数默认0.25。如果漏检可以尝试降低这个阈值如0.1让更多候选框被保留但可能会增加误检。检查输入分辨率训练时用imgsz640推理时也必须用相同的尺寸。如果你用不同尺寸推理效果会大打折扣。NMS参数非极大值抑制NMS的iou阈值默认0.7也可能影响。对于密集小目标可以适当提高iou阈值如0.8让重叠的框更容易被保留。在嵌入式设备上速度慢使用TensorRT或OpenVINO这是最有效的加速手段。降低推理分辨率如果精度允许可以将推理时的图像尺寸从640降到480甚至320。使用半精度FP16大部分现代GPU和嵌入式芯片都支持FP16速度比FP32快精度损失很小。6. 数据集扩展与应用场景展望这份5163张图的数据集是一个强大的起点但真实世界是复杂多变的。要让你的疲劳检测系统真正可靠可以考虑从以下几个方向扩展数据集增加极端场景更多强光、逆光、夜间低光照、戴墨镜、戴普通眼镜、侧脸角度极大超过90度的样本。增加干扰物模拟被手、手机、食物等物体部分遮挡口鼻的情况。丰富人种与年龄段确保数据集中包含不同肤色、年龄的驾驶员减少模型偏见。标注连续帧序列目前是图片级标注。未来可以标注视频片段用于训练时序模型如3D CNN, LSTM结合YOLO更好地理解疲劳的动态过程。这个数据集和训练出的模型其应用场景远不止于驾驶员疲劳检测在线教育专注度分析检测学生上网课时是否走神长时间闭眼、打哈欠。远程办公会议参与度在征得同意和符合隐私法规的前提下分析会议参与者的精神状态。安防与看护用于监控特殊岗位如保安、流水线工人的精神状态或者看护老人、病人是否出现异常长时间闭眼。互动娱乐作为游戏或AR应用的一种输入方式通过张嘴、眨眼触发特定互动。最后我想强调的是任何一个AI落地项目高质量的数据都是地基。这份数据集是我在多个实际项目中反复清洗、标注、迭代的成果希望它能帮你跳过从0到1最痛苦的阶段。模型训练和调参固然需要技巧但比起数据质量它们更像是“锦上添花”。如果你在使用的过程中有任何新的发现或者用这个数据集做出了更有趣的应用也欢迎一起交流。本文还有配套的精品资源点击获取
返回列表