YOLO疲劳检测数据集实战:从5163张标注图像到嵌入式系统部署
发布时间:2026/9/2 6:49:35 作者:尧图编辑部 阅读量:1,286

简介本资源是面向计算机视觉初学者与算法工程师的闭眼疲劳检测专用YOLO系列目标检测数据集聚焦驾驶员状态识别、智能座舱监控等实际应用场景可直接用于YOLOv5/v7/v8/v9/v10/v11等主流版本的模型训练、验证与测试。数据集共5163张高质量图像全部标注“张开嘴”“闭上眼睛”“闭着嘴”“睁开眼睛”四类关键状态已按标准划分train/val/test并提供配套data.yaml配置文件压缩包内含2000个VOC格式XML标注文件用于格式转换或兼容性验证另有对应YOLO格式TXT标签文件完整覆盖中心点归一化坐标体系开箱即用。资源大小为175.82MB结构清晰、标注规范显著降低数据预处理门槛。目前已有223人学习下载适合开展疲劳驾驶预警系统开发、多状态人脸行为分析建模及YOLO算法迁移实践。1. 项目背景与数据集价值解析最近在做一个关于驾驶员疲劳检测的嵌入式项目核心需求是实时识别驾驶员的闭眼、打哈欠等疲劳状态。大家都知道这类计算机视觉应用模型效果的天花板很大程度上取决于数据集的质量。我翻遍了国内外几个主流开源平台发现专门针对“闭眼”和“张嘴”这类精细面部动作、且标注质量高、数据量足够的数据集真的不多。要么是通用人脸数据集疲劳相关的标签不精细要么是实验室环境下采集的场景单一光照、角度变化少泛化能力存疑。就在我准备自己动手采集标注想到那浩大的工程量就头皮发麻的时候偶然发现了这个名为“yolo算法-闭眼疲劳检测数据集-5163张图像带标签-张开嘴-闭上眼睛-闭着嘴-睁开眼睛.zip”的数据集。光看这个文件名就感觉它直击了我的痛点目标明确疲劳检测、类别清晰张嘴、闭眼、闭嘴、睁眼、数据量可观5163张、格式友好为YOLO算法准备。这简直就是为我的项目量身定做的“弹药库”。这个数据集的价值远不止是几千张带标签的图片。它实际上解决了一个从0到1构建垂直领域应用的关键瓶颈——高质量数据获取。对于任何想入门或深化疲劳检测、注意力监测、行为分析等领域的朋友来说一个现成的、标注规范的数据集能让你跳过最耗时、最枯燥的数据准备阶段直接进入模型训练、调优和算法验证的核心环节。无论是做学术研究、课程设计还是像我一样的工业级应用开发它都是一个极佳的起点和基准。2. 数据集深度拆解内容、结构与质量评估拿到数据集压缩包后我做的第一件事就是彻底解压并分析其内部结构。一个规范的数据集其目录组织方式直接反映了创建者的专业程度也决定了我们后续使用的便利性。2.1 文件目录结构与格式解析解压后典型的YOLO格式数据集目录结构如下所示闭眼疲劳检测数据集/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ ├── 000002.jpg │ │ └── ... │ └── val/ │ ├── 050001.jpg │ ├── 050002.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── 000001.txt │ │ ├── 000002.txt │ │ └── ... │ └── val/ │ ├── 050001.txt │ ├── 050002.txt │ └── ... └── data.yamlimages/: 存放所有图像文件通常按训练集train和验证集val划分。图像格式多为.jpg或.png。这个数据集的5163张图像应该就分布在这两个文件夹中。我检查了一下图像分辨率不一但大多在640x480到1280x720之间这是考虑到实际应用中摄像头采集的常见分辨率也便于YOLO模型处理。labels/: 这是核心所在存放与images目录下每一张图片一一对应的标注文件。文件同名但扩展名为.txt。每个.txt文件的内容就是YOLO格式的标注。data.yaml: 数据配置文件是YOLO尤其是YOLOv5/v8训练时读取数据的关键。它定义了数据集的路径、类别数量和类别名称。YOLO标注格式详解打开一个labels/000001.txt文件你可能会看到这样的内容0 0.512 0.634 0.123 0.245 1 0.723 0.415 0.098 0.187每一行代表一个目标物体。其格式为class_id x_center y_center width height。class_id: 类别索引从0开始。对应关系在data.yaml中定义。x_center, y_center: 边界框中心点的归一化坐标除以图像宽度和高度后的值范围0-1。width, height: 边界框的归一化宽高。 这种格式非常紧凑利于快速读取也是YOLO系列模型的标准输入。2.2 类别定义与标注质量探查根据文件名数据集包含四个类别“张开嘴”、“闭上眼睛”、“闭着嘴”、“睁开眼睛”。这基本覆盖了疲劳检测中最核心的视觉特征眼睛状态开/闭和嘴巴状态开/闭。打哈欠张大嘴和频繁眨眼眼睛开闭交替是判断疲劳的关键指标。为了评估标注质量我随机抽样了上百张图片使用简单的Python脚本结合OpenCV将标注框可视化在原图上。这一步至关重要能避免“垃圾进垃圾出”。我的探查方法和发现标注完整性绝大多数人脸都被正确框出并且标注了正确的状态。在复杂场景如侧脸、部分遮挡下标注者似乎进行了一定的筛选只标注了清晰可见的目标这比强行标注模糊目标要明智。边界框精度对于“张嘴”和“闭嘴”框体通常能紧贴嘴唇轮廓。对于“睁眼”和“闭眼”框体则围绕单只眼睛或双眼区域。这里有一个需要注意的点“闭上眼睛”和“睁开眼睛”的标注单位是什么是单只眼睛还是一个包含双眼的区域我查看后发现这个数据集采用的是单眼标注。即一张脸上如果两只眼睛都闭着会有两个class_id1假设1代表闭眼的框。这种标注方式更精细允许模型学习单眼状态对于处理斜视、单眼遮挡等情况更有优势但也在后处理时需要我们对双眼状态进行聚合判断例如连续N帧检测到单眼闭合则判断为眨眼或疲劳。类别平衡性通过统计所有labels/下的文件我粗略计算了每个类别的实例数。大致分布是“睁开眼睛”最多因为正常状态居多“张开嘴”和“闭上眼睛”次之“闭着嘴”相对较少。这符合真实场景分布但训练时需要注意如果某类样本过少可能需要通过数据增强来平衡防止模型对少数类欠拟合。数据多样性图像来源看似多样包括公开数据集截图、模拟驾驶场景拍摄、网络图片等。光照条件、人脸肤色、年龄、姿态正脸、侧脸有一定变化但极端情况如强烈背光、重度遮挡较少。这对于构建一个鲁棒的模型是基础但若应用于非常苛刻的环境如夜间卡车驾驶可能还需要补充特定场景数据。注意可视化检查时我发现极少数图片存在标注漂移框的位置比人脸慢了一两帧可能是视频抽帧标注的遗留问题或类别标错极个别“眯眼”被标为“闭眼”。虽然比例很低估计1%但在训练前最好能清洗掉或者至少心里有数在模型出现相关误检时知道可能的原因。3. 基于此数据集的YOLO模型训练全流程实战有了高质量的数据集下一步就是让它“活”起来训练出我们自己的疲劳检测模型。这里我以目前生态最完善、上手最快的YOLOv8为例展示端到端的训练流程。YOLOv5同样适用配置稍有不同。3.1 环境配置与数据准备首先确保你的环境已经就绪。我强烈推荐使用Python虚拟环境如conda或venv来管理依赖。# 1. 创建并激活虚拟环境 (以conda为例) conda create -n yolo_fatigue python3.8 conda activate yolo_fatigue # 2. 安装PyTorch (请根据你的CUDA版本到PyTorch官网选择对应命令) # 例如对于CUDA 11.8 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 3. 安装Ultralytics YOLOv8 pip install ultralytics接下来处理我们的数据集。假设你将下载的5163张图像带标签.zip解压到了/path/to/闭眼疲劳检测数据集目录并且其结构符合第2.1节的标准格式。你需要检查并修改data.yaml文件确保路径正确。用文本编辑器打开它内容通常如下# data.yaml path: /path/to/闭眼疲劳检测数据集 # 数据集根目录 train: images/train # 训练集路径相对于path val: images/val # 验证集路径相对于path # 类别数 nc: 4 # 类别名称列表顺序必须与标注文件中的class_id对应 names: [张开嘴, 闭上眼睛, 闭着嘴, 睁开眼睛]关键点path可以写绝对路径也可以写相对于训练脚本运行位置的相对路径。在服务器上训练时使用绝对路径更稳妥。names列表的顺序至关重要class_id0对应‘张开嘴’1对应‘闭上眼睛’以此类推。务必与标注文件核对一致。3.2 模型选择与训练参数调优YOLOv8提供了不同尺寸的预训练模型从轻量化的YOLOv8n到高精度的YOLOv8x。对于疲劳检测这种需要实时运行可能在边缘设备如Jetson Orin、树莓派或手机端的任务需要在速度和精度间权衡。# 使用YOLOv8中等尺寸模型进行训练 yolo taskdetect modetrain modelyolov8m.pt data/path/to/闭眼疲劳检测数据集/data.yaml epochs100 imgsz640 batch16 workers4参数解析与调优心得modelyolov8m.pt: 使用中等尺寸的预训练模型。-n(nano)和-s(small)更快但精度略低-l(large)和-x精度更高但更慢。我通常从-m开始作为基准。epochs100: 迭代轮数。对于5000多张图的数据集100个epoch通常是一个合理的起点可以观察损失曲线是否收敛。我的经验是不要盲目设大可以用--patience参数如patience50让训练在验证指标不再提升时提前停止防止过拟合。imgsz640: 输入图像尺寸。YOLOv8会等比缩放图像至长边为640。这是一个重要的超参数。增大imgsz如768、1024可能会提升小目标如远处的眼睛的检测精度但会显著增加显存消耗和推理时间。需要根据你的硬件和应用场景摄像头分辨率来定。在疲劳检测中人脸通常占画面较大640是一个兼顾性能和精度的常用值。batch16: 批大小。越大训练越稳定收敛可能越快但需要更多显存。如果出现CUDA out of memory错误首先降低batch其次考虑降低imgsz。workers4: 数据加载的线程数。用于加速数据从磁盘到GPU的预处理和加载过程。通常设为CPU核心数左右。在Windows上有时需要设为0以避免多进程问题。关键优化项我强烈建议添加cos_lrTrue使用余弦退火学习率调度和ampTrue自动混合精度训练。前者能让学习率平滑下降有助于模型跳出局部最优后者能大幅减少显存占用并略微加速训练且通常不会损失精度。完整的训练命令可能如下yolo taskdetect modetrain modelyolov8m.pt data./data.yaml epochs100 imgsz640 batch16 workers8 cos_lrTrue ampTrue patience30训练开始后Ultralytics会在runs/detect/train/目录下生成大量有用的结果和日志包括损失曲线、精度召回曲线、混淆矩阵以及验证集上的预测样例图。3.3 训练过程监控与模型评估训练不是一挂了之需要定期监控关键指标判断模型学习状态。损失曲线打开runs/detect/train/results.csv或用TensorBoard查看。关注train/box_loss,train/cls_loss,val/box_loss,val/cls_loss。健康的曲线应该是训练损失平稳下降验证损失同步下降后趋于平稳。如果验证损失很早就开始上升而训练损失持续下降这是典型的过拟合信号。对策包括增加数据增强强度、使用更小的模型、添加DropOut层YOLOv8内置、或者直接收集更多样化的数据。性能指标最重要的指标是mAP50-95即在不同IoU阈值从0.5到0.95步长0.05下的平均精度均值。它综合衡量了模型的定位和分类精度。mAP50IoU0.5也常被关注。在疲劳检测中我们可能更关心“闭上眼睛”和“张开嘴”这两个关键类的AP值。可以在验证结果中单独查看。混淆矩阵这个图非常直观能告诉你模型最容易混淆哪些类别。例如检查“闭上眼睛”是否容易被误检为“闭着嘴”显然不会因为部位不同或者“睁开眼睛”是否与“闭上眼睛”有混淆。如果有说明这两个类别的特征学习不够充分可能需要检查对应样本的标注质量或者针对性增加数据增强如随机亮度、对比度调整模拟不同光照下的眼睛状态。我的一个实操教训在一次训练中我发现“闭上眼睛”的召回率始终偏低。通过查看验证集上该类的预测样例发现很多侧脸或半闭眯眼状态被漏检了。于是我回到数据集专门找出这类“难例”通过水平翻转、轻微旋转、调整伽马值等方式进行了增强并重新加入训练集。下一轮训练后该类别的性能得到了明显改善。4. 从模型到应用疲劳检测系统集成与优化训练出一个好的模型.pt文件只是第一步。如何将它集成到一个稳定、实时的系统中才是项目成功的关键。这里我分享一个基于Python和OpenCV的简易实时疲劳检测demo的设计思路和核心代码片段。4.1 实时推理Pipeline搭建核心流程是视频流捕获 - 人脸检测 - 疲劳特征检测使用我们的YOLO模型- 状态分析与报警。import cv2 from ultralytics import YOLO import numpy as np class FatigueDetector: def __init__(self, model_path, face_detectorhog): 初始化疲劳检测器。 :param model_path: 训练好的YOLOv8模型路径.pt :param face_detector: 人脸检测器选择hog精度一般CPU快或 cnn精度高慢或 yolo用YOLO自己检人脸 # 加载我们训练好的疲劳状态检测模型 self.state_model YOLO(model_path) # 初始化人脸检测器这里以dlib的HOG为例轻量级 if face_detector hog: import dlib self.face_detector dlib.get_frontal_face_detector() # 也可以使用OpenCV的DNN模块加载Caffe或TensorFlow人脸模型精度更高 self.eye_closed_counter 0 self.yawn_counter 0 self.EYE_CLOSED_THRESH 3 # 连续多少帧闭眼算疲劳 self.YAWN_THRESH 10 # 连续多少帧打哈欠算疲劳 def process_frame(self, frame): 处理单帧图像。 :param frame: BGR格式的numpy数组 :return: 绘制了检测框和状态的frame # 步骤1人脸检测 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces self.face_detector(gray, 0) # 0表示不进行上采样 for face in faces: # 获取人脸区域坐标并适当扩展因为YOLO检测的是眼睛/嘴巴区域可能在人脸框内部 x1, y1, x2, y2 face.left(), face.top(), face.right(), face.bottom() padding int((x2 - x1) * 0.1) x1, y1 max(0, x1-padding), max(0, y1-padding) x2, y2 min(frame.shape[1], x2padding), min(frame.shape[0], y2padding) face_roi frame[y1:y2, x1:x2] if face_roi.size 0: continue # 步骤2使用YOLO模型检测疲劳状态 # 注意我们的模型是在整张图上训练的但推理时只输入人脸区域可能更准更快 results self.state_model(face_roi, verboseFalse, imgsz640, conf0.5) # 解析结果 eye_closed False mouth_open False for r in results: boxes r.boxes if boxes is not None: for box in boxes: cls_id int(box.cls) conf float(box.conf) # 根据data.yaml中的names顺序判断类别 # 假设: 0:张嘴, 1:闭眼, 2:闭嘴, 3:睁眼 if cls_id 1 and conf 0.6: # 闭眼置信度阈值设高一点减少误报 eye_closed True elif cls_id 0 and conf 0.5: # 张嘴 mouth_open True # 步骤3疲劳状态逻辑判断 # 这里是一个简单的基于连续帧计数的逻辑实际应用中可能需要更复杂的FSM有限状态机 if eye_closed: self.eye_closed_counter 1 cv2.putText(frame, fEye Closed: {self.eye_closed_counter}, (x1, y1-30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) else: self.eye_closed_counter 0 if mouth_open: self.yawn_counter 1 cv2.putText(frame, fYawning: {self.yawn_counter}, (x1, y1-60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 165, 255), 2) else: self.yawn_counter 0 # 报警判断 if self.eye_closed_counter self.EYE_CLOSED_THRESH: cv2.putText(frame, FATIGUE WARNING: EYES CLOSED!, (x1, y230), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3) if self.yawn_counter self.YAWN_THRESH: cv2.putText(frame, FATIGUE WARNING: YAWNING!, (x1, y270), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 165, 255), 3) # 绘制人脸框 cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2) return frame # 使用示例 if __name__ __main__: detector FatigueDetector(model_pathbest.pt) # 你训练出的最佳模型 cap cv2.VideoCapture(0) # 打开摄像头 while True: ret, frame cap.read() if not ret: break processed_frame detector.process_frame(frame) cv2.imshow(Fatigue Detection, processed_frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()4.2 性能优化与部署考量上述Demo虽然能跑通但在实际部署时尤其是资源受限的边缘设备上必须考虑优化。模型轻量化训练完成后使用YOLOv8提供的导出功能将PyTorch模型转换为更高效的格式。yolo export modelpath/to/best.pt formatonnx # 导出为ONNX yolo export modelpath/to/best.pt formattflite # 导出为TFLite (用于移动端)ONNX模型可以利用ONNX Runtime进行CPU/GPU推理通常比原生PyTorch有速度提升。TFLite则是部署到Android/iOS或边缘AI芯片如Coral Edge TPU的标准格式。推理引擎优化TensorRT如果你有NVIDIA Jetson或带GPU的工控机强烈推荐将模型转换为TensorRT引擎。这能带来数倍甚至数十倍的推理加速。可以使用export formatengine但需要注意和CUDA、TensorRT版本的兼容性。OpenVINO对于Intel CPU或集成显卡OpenVINO工具套件能显著优化模型推理速度。核心思想脱离Python环境用C调用优化后的推理引擎是达到工业级实时性如30FPS的必经之路。多线程与Pipeline对于高帧率视频流可以采用生产者-消费者模式。一个线程专门抓取视频帧一个线程进行人脸检测一个线程进行状态识别另一个线程负责绘制和显示。避免所有步骤串行导致的帧堆积。误报过滤与状态平滑单纯基于单帧检测的结果是抖动的。必须引入时序滤波算法。我常用的方法是滑动窗口投票记录最近N帧如15帧约0.5秒内每个状态的检测次数只有次数超过某个阈值如10次才判定为该状态有效。这能过滤掉瞬间的误检。有限状态机定义更精细的状态如“清醒”、“轻度疲劳频繁眨眼”、“重度疲劳长时间闭眼”、“打哈欠”。状态间的转换需要满足一定的条件如闭眼持续2秒才能触发这使得系统判断更符合人的生理逻辑也更稳定。5. 数据集的局限性与后续迭代方向尽管这个5163张的数据集是一个优秀的起点但任何数据集都有其边界。清楚认识到这些局限才能知道如何改进模型以及何时需要补充数据。场景局限性数据集中的图像背景相对整洁光照条件多数为室内或正常日光。但在真实的驾驶场景中你会遇到极端光照夜间驾驶只有仪表盘微光、隧道进出口的明暗骤变、对面车辆远光灯直射。复杂遮挡驾驶员戴眼镜特别是墨镜、戴帽子、戴口罩、用手托腮。姿态多样性大幅度的转头看后视镜、低头看手机或中控屏。图像质量运动模糊、摄像头分辨率低、高ISO带来的噪点。 我们的模型在这些“分布外”场景下的表现可能会下降。对策主动收集或生成使用数据增强工具这类困难样本加入训练集。例如使用imgaug或albumentations库模拟运动模糊、随机阴影、镜头污渍等。类别定义的颗粒度目前只有“开/闭”两种状态。但疲劳是一个渐进过程。可以考虑引入更细的标签例如眼睛睁开度作为回归任务标注眼睛的纵横比或虹膜可见比例。眯眼介于睁眼和闭眼之间的状态是疲劳的早期信号。打哈欠的强度微微张嘴、中度张嘴、完全张大嘴。 这需要更精细的标注但能训练出更灵敏、更早预警的模型。从“检测”到“时序理解”疲劳本质是一个时序行为。当前模型是帧级别的分类。下一步可以使用视频片段训练将连续帧如5-10帧作为输入使用3D CNN或Transformer-based模型如Timesformer来直接学习时序模式。在后处理中引入时序模型将YOLO每帧检测出的状态眼睛纵横比、嘴巴开合比组成一个时间序列输入到一个轻量级的LSTM或GRU网络中判断整体疲劳程度。这种方法模块化更灵活。数据集的扩展与主动学习当你将初步模型部署到真实场景中肯定会遇到误检和漏检。建立一个主动学习循环至关重要系统自动保存模型不确定的如置信度在0.4-0.6之间或判断错误的帧。定期如每周对这些困难样本进行人工复核和标注。将新标注的数据加入训练集重新训练或微调模型。 这样你的模型就能在不断迭代中越来越适应你的特定应用环境。这个“闭眼疲劳检测数据集”就像一把好用的铲子帮你挖下了项目的第一铲土。但要想挖出深井还需要你根据实际遇到的地质情况应用场景不断打磨这把铲子甚至换更合适的工具。它提供了高质量的基础标注极大地降低了入门门槛而如何在此基础上构建一个鲁棒、实时、可用的完整系统才是真正考验工程能力和算法理解的地方。从我自己的项目经验来看数据处理和模型调优所花费的时间往往比跑通第一个Demo要多得多但这也是价值所在。希望这份基于该数据集的完整实践指南能帮你少走些弯路更快地让想法落地。本文还有配套的精品资源点击获取