资讯动态

驾驶员行为检测数据集:22600张YOLO格式图片的训练实战经验

发布时间:2026/9/30 5:33:16 来源:尧图企业网站定制
做驾驶员状态监控最头疼的不是模型选型而是数据。我最初跑疲劳预警项目翻遍公开数据集要么是实验室摆拍、场景单一要么标注格式老旧、还得自己转一遍。后来自己动手整理了一套驾驶员行为检测数据集总共22600张图片全部标注成YOLO格式直接丢进YOLOv8就能开训。到今天这套数据支撑了我好几个版本的检测模型也帮不少同行绕过了一些坑这里把完整经验写出来。这套数据集覆盖驾驶员在座舱内的常见行为包括正常驾驶、打电话、喝水、抽烟、疲劳打哈欠、分心看手机等每张图都带有目标框和类别标签。它解决的问题很直接训练一个能实时识别驾驶员当前动作的检测模型为DMS驾驶员监测系统、疲劳预警、分心提醒等功能提供感知基础。适合正在做智能驾驶座舱感知、车载边缘AI部署、或者想用YOLO练手目标检测的开发者参考。我不打算只告诉你“这个数据集有多少张、都有什么类”那没意思。重点会放在数据怎么用、训练怎么调、实际部署会踩哪些坑以及为什么有些数据决定了模型能力的上限。整个过程按真实项目流程来写你拿过去就能对着做。1. 驾驶员行为检测到底是什么为什么数据集这么关键1.1 智能驾驶里驾驶员状态监控承担什么角色自动驾驶分级L2到L3的过渡阶段系统并不能在所有场景下完全脱手。哪怕开启领航辅助驾驶员仍然需要保持对道路的注意力随时准备接管。这时候车辆必须知道驾驶员“在不在状态”于是就有了DMS。DMS一般通过红外摄像头采集驾驶员面部和上半身图像用视觉算法判断视线方向、闭眼程度、头部姿态、手部动作等。视线和闭眼这类细粒度状态靠关键点检测而打电话、喝水、抽烟这类动作目标检测是最直接的方式先用检测框定位到手、脸、手机、水杯等目标再根据框的位置关系和类别组合判断行为是否发生。但是目标检测模型不能凭空认识“打电话”它需要看到大量“手拿手机靠近耳朵”的正样本也需要看到“手自然放在方向盘上但手里有手机”这类容易混淆的负样本。如果数据集里都是同一角度、同一光照、同一人的摆拍模型在实车上基本是废的。所以我整理这套数据时优先级从来不是“数量有多夸张”而是“场景变化够不够多、正负样本能不能逼出模型的判别力”。1.2 一套能用的行为检测数据集应该满足哪些条件我在项目里总结过DMS用的行为检测数据有三个硬性条件。第一是成像环境要和实际安装位置一致。驾驶员监控摄像头通常装在方向盘管柱上或者A柱附近俯拍角度为主能看到方向盘、仪表盘和驾驶员上半身。如果训练数据全是平视角度部署后检测框会偏、置信度会掉。这套数据全部采用类似DMS视角至少贴近真实装机角度。第二是类别定义要能覆盖高频行为且互斥性合理。我见过有些数据集把“打电话”和“玩手机”分开标但实际画面里两种行为很难区分训练时loss反复横跳。我这边最终定下来七个类别normal正常驾驶、call打电话、drink喝水、smoke抽烟、yawn打哈欠、look_away视线偏离、hand_on_wheel_eating? 不对这个太乱。我在固定类别里保留六个核心动作类还有一个用于“其他分心行为”再单独处理。宁可类别少而清晰也不要为了凑数量把边界搞模糊。第三是负样本要足。很多公开数据集只标了“有问题的行为”却没有告诉你“正常但容易误判”的画面长什么样。比如嘴里叼着烟但手在方向盘上这算抽烟吗手里拿着手机但正在看导航这算分心吗我在数据集里专门保留了大量这种模糊边界样本让模型学会在不确定时倾向于保守输出而不是乱报报警。1.3 22600张这个规模够不够用先算一笔账。假设一共七个类平均每个类三千多张。如果每张图里只有一个目标那只够模型“见一次”完全不足以学稳定。但行为检测单张图里通常有多个目标一张打电话的图既有手又有手机还有人脸。同一个“打电话”行为可以对应三四个框的上下文关系。所以真正有效的训练样本不只是图片数量而是“行为事件”的数量。22600张图里如果每张平均出现两个标注目标实例数就在四万以上用来训练YOLOv8这类模型做驾驶行为识别完全够起步。如果你要追求更高精度比如漏检率低于1%那这个规模只能说“够用但不宽裕”。我的经验是先用这套数据把基座模型训出来再通过半监督或者难例挖掘持续补充最终达到量产要求。数据量从来不是一次到位的而是一个迭代滚雪球的过程。2. 数据集的构成与标注规范2.1 类别设计与行为定义最终定稿的类别是六类normal、call、drink、smoke、yawn、look_away。每一类都对应明确可标注的视觉特征而不是抽象含义。normal双手握方向盘视线看前方面部自然没有额外手持物。call手持手机靠近耳侧或者使用蓝牙耳机但面部有明显说话动作蓝牙耳机场景单独标避免和手持混淆。drink手握水杯或饮料瓶且杯口靠近嘴边或者有明显仰头饮用动作。smoke手指夹烟/电子烟或烟/烟头在画面可见范围内。yawn嘴巴张大有明显打哈欠面部特征。look_away头部明显转向非前方区域比如看侧窗、看后座、低头看仪表台。有一点很关键我不用“危险行为”这种标签因为危险与否是策略层判断不是感知层该做的事。感知层只负责输出“驾驶员此刻正在做什么”至于发不发报警由上层规则决定。这样模型职责清晰也容易迭代。2.2 图像采集场景与多样性数据来源不只是单一红外摄像头。我混合了常规RGB摄像头画面和近红外画面。白天用自然光夜间用红外补光。近红外图像整体偏灰但脸部细节保留度高在暗光下反而比RGB稳定。模型如果只在RGB上训练放到夜间的红外视频里基本崩所以训练集里必须保证一定比例的灰度感图像。除了光照多样性还体现在人种、年龄、衣着、戴眼镜/帽子、口罩遮挡等。我在整理时特别注意了口罩样本。这两年戴口罩开车的场景太常见如果模型把口罩当成遮挡而漏检打哈欠这功能等于废了。所以在yawn类里我专门加了部分口罩遮挡样本虽然嘴巴张合特征看不清但脸颊、眼周、头部运动依然能提供线索。椅子位置、方向盘位置、身材差异也会导致同一行为在画面中的位置和尺度差异很大。有的驾驶员把方向盘调得很远手部目标非常小有的调得很近上半身几乎占满全图。YOLO对尺度敏感训练数据必须覆盖这些变化。我这边专门按“小目标占比不少于15%”来挑选图片避免模型变成大目标检测器。2.3 YOLO格式标注到底长什么样YOLO格式是每个txt文件对应一张图片每一行代表一个目标class_id x_center y_center width height这四个数值全部归一化到0~1坐标值除以图片宽高。比如图片宽1920、高1080一个手机框的中心点像素坐标是(960, 540)框宽是300高200那么对应的一行就是2 0.5 0.5 0.15625 0.185185class_id从0开始与类别文件classes.txt里的顺序一一对应。文件夹结构建议这样组织dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── classes.txttrain和val的图片与label文件名一一对应后缀不同而已。YOLOv8用这样的结构可以直接训练不需要额外转成COCO。实测中有一个容易踩的坑标注软件导出的坐标有可能是老版YOLO格式或者VOC格式。我收集到的部分数据就是从XML转过来的转换时务必注意坐标原点。YOLO的中心点坐标是基于左上角原点不是左下角。搞反了的话目标框会对称错位训练时loss直接爆掉。每次拿到新数据我第一件事就是随机抽几张画框可视化校验不校验就训练等于闭眼开车。2.4 标注质量如何保证22600张图不是一次性标完的我分了几轮。第一轮用预标注模型自动生成候选框人工只负责修正和删除。第二轮重点修边界模糊样本两个人独立标注冲突部分交第三方仲裁。第三轮做质量抽检每类随机抽200张计算标注框和人工复标框的IoU低于0.7的回炉。你可能会觉得这些流程太繁琐但如果标注质量不稳定模型学的就是“标注者的不确定性”。尤其是打电话这种动作框到底是把手和手机连在一起标一个框还是分别标两个框有的标注员习惯把手机和手合并有的分开模型会在训练时被搞糊涂。我最后的规范是目标有清晰边界就分开标比如手机是一个独立目标手是另一个目标但烟这种小物体标注抽烟行为时和手合并成一个框因为烟本身在红外画面里可能只有几个像素单独标意义不大。3. 基于YOLO的训练实操3.1 环境准备与数据划分我用的是YOLOv8ultralytics框架安装很简单pip install ultralytics显卡建议至少8G显存我训练时用的是一块24G的卡batch size能开到16甚至32。如果显存小把batch size调小同时把图像尺寸从640降到512也能跑就是精度会掉一点。划分比例我建议图片目录里按句子划分而不是随机全乱分。因为很多图是同一段视频抽帧出来的随机划分会把同一段视频的帧同时塞进train和val造成数据泄露验证指标虚高。按“来源片段”划分才能真实反应泛化性能。我这边按9:1划分出train和val又额外留了一个test集里面全是完全没参与训练的视频片段用于最终评估。3.2 训练参数选择与loss观察我用YOLOv8n起步预训练权重选yolov8n.pt先跑50个epoch看能不能正常收敛。如果baseline表现ok再换yolov8s或者yolov8m提升精度。关键参数如下train: dataset/images/train val: dataset/images/val nc: 6 names: [normal, call, drink, smoke, yawn, look_away]训练命令yolo taskdetect modetrain modelyolov8n.pt datadriver.yaml batch16 epochs100 imgsz640观察loss时我主要盯box_loss和cls_loss。正常情况两条线都会平稳下降最后在val上不再明显下降说明已经收敛。如果发现box_loss降不下去多半是标注框不准确如果cls_loss震荡多半是类别边界模糊样本太多。这时候不要盲目加大epoch先回头清洗数据。然后是混淆矩阵。跑验证集之后输出混淆矩阵重点看normal和其他动作类的误检。比如正常驾驶被误报成look_away这在实际DMS里非常讨厌会把驾驶员惹毛。如果这类误检多我会额外增加normal样本而不是简单调阈值。3.3 模型评估与mAP陷阱很多人只看mAP0.5但这个指标在行为检测里会骗人。打过哈欠和看手机这类动作目标和目标之间有大量重叠IoU本来就不精确。mAP0.5只要框大致对就算对mAP0.75才更接近实际可用性。我训练时会把这两个指标同时记录下来如果mAP0.5很高但mAP0.75低说明定位不够精准反而要在回归分支上多花功夫。行为检测最终要看“行为时序上的稳定输出”。单帧检测准确率再高如果逐帧输出乱跳上层也无法用。所以我在评估时还会跑一段连续视频统计检测结果的连续帧数一个真实的打哈欠动作至少持续2秒也就是在30fps视频里大概60帧。如果检测框只在其中10帧出现还不如当噪声丢掉。3.4 部署时的性能优化部署到车载平台算力通常有限。YOLOv8n在Jetson Orin NX上能跑到实时但再往下压成本需要做剪枝和量化。我建议优先做TensorRT FP16量化精度损失很小速度能快一倍左右。如果还要量化到INT8注意校准集要选好我试过用正常白天图片校准结果夜间红外图片掉点严重后来把夜间样本加进校准集才拉回来。另一个优化是输入分辨率。DMS画面里的手和手机经常比较小分辨率降到416会明显漏检。我最终选择输出尺寸640但把原始ROI裁剪到方向盘以上区域再缩放相当于用更少的像素完成了同样的事情。这个操作比全局缩放了了省算力而且小目标保留度更高。3.5 从检测到行为判断的进阶检测只能告诉你“画面里有一个手机框、一个手框、一张脸框”但光有这些框还不足以直接报“打电话”。我实现了一套基于检测结果的事件融合逻辑当手框与脸框的IoU大于某个阈值同时存在手机框且这个状态持续超过0.5秒才判定为call行为。喝水动作需要检测到水杯框靠近嘴部抽烟动作需要手框附近出现烟的目标。这些逻辑虽然不复杂但能极大减少单帧误报。融合逻辑跑通之后我再把结果输出到CAN信号或者故障报警灯就构成了一个完整DMS功能链路。数据集在这里起到的作用不仅是训练检测器还帮我验证了不同行为的时序特征。比如长时间闭眼和打哈欠的时序模式完全不同检测器输出类别后再用一个小状态机去累积持续时长报警决策会稳很多。4. 常见问题与避坑指南4.1 标注框偏移和类别不平衡问题表现训练时box_loss在0.05附近降不下去验证集可视化发现很多框“偏上”或“偏左”半个身位。原因一般是标注时对“目标中心点”理解不一致。我这边整理数据时就发现有一批老数据把“手机中心”标到了屏幕中心导致框始终偏一截。解决方式没有捷径只能人工复查相关批次的框。后来我写了个脚本计算每个框中心点相对图像中心的分布如果大量集中在某一象限就有理由怀疑标注偏移再抽检确认。类别不平衡方面normal类样本最多因为正常驾驶是绝大多数时间的状态yawn和smoke占比相对少。直接用不平衡数据训练模型会倾向于把不确定目标归类为normal。处理方法不是粗暴降采样而是在loss计算时给少数类加权重。YOLOv8里可以通过修改数据集的类别权重参数或者干脆复制少数类样本做oversampling。我更推荐后者简单直接不容易把模型训坏。4.2 光照和遮挡带来的误检夜间红外场景头发、衣领、方向盘的轮廓经常被识别成手机或水杯。我实测过不止一次后排乘客的手臂从座椅侧面伸出来被当成吸烟手框。要解决这个问题光靠检测器本身比较难因为纹理线索太弱。我的经验是引入“手部区域先验”DMS画面里驾驶员的手通常只出现在方向盘左右两侧和档杆附近超出这个区域的手部检测结果可信度要打折。遮挡问题更多发生在驾驶员戴口罩时。口罩遮住了下半张脸打哈欠的嘴部特征看不到模型容易漏检。我的应对是在训练时加入随机块遮挡增强模拟口罩、墨镜等局部遮挡。具体做法是在Mosaic增强的基础上对检测目标区域随机加一个高斯噪声块。这招能让模型更多依赖眼睛和脸颊的上下文而不是死盯嘴巴。4.3 训练中loss不收敛或NaN最常见的原因是学习率太大。YOLOv8默认学习率0.01如果batch size改小但学习率没跟着调梯度更新容易震荡。特别是用TPU或者小显存时batch size降到4学习率最好降到0.005甚至0.001。另外如果训练数据里有空白label文件也会导致loss出现NaN。我在预处理时会过滤掉所有没有标注框的图片避免干扰。另一个容易忽视的点是标注框的width/height必须大于0。有些标注工具输出负坐标或零宽高YOLO读取后坐标归一化出现负数训练过程就会出现奇怪的loss值。我从网上收集的一部分数据就发生过这种情况一个简单的脚本解决python -c with open(labels.txt,r) as f: linesf.readlines() for line in lines: parts[float(x) for x in line.split()] if parts[3]0 or parts[4]0: print(invalid) 4.4 小目标检测效果差手机、水杯、烟在画面中经常小于32x32像素这属于YOLO的小目标类漏检率天然高。我的经验是不要靠加深网络来解决而是从数据入手。首先增大输入分辨率到960手动牺牲一点速度换小目标召回。其次在训练时把原图中间区域放大1.5倍再缩放至网络输入尺寸模拟座舱视角下目标被放大的效果。这一步操作我是在Mosaic中实现的叫做random crop with scale jitter。实测能提升小目标Recall大约8%到10%。如果上线后还是漏检小目标另一个思路是把检测器改成两个输入分支一路看全图另一路只看方向盘区域。全图分支负责检测整体行为方向盘区域分支负责专门盯水杯和手机。两分支结果做逻辑合并比单一模型做多尺度检测要稳定得多。4.5 数据增强怎么调才不弄巧成拙YOLOv8默认开启Mosaic、随机翻转、HSV扰动等。用在通用场景没问题但在驾驶座舱里有几个增强要慎用。第一垂直翻转不要开。驾驶员不可能倒立开车垂直翻转生成的样本根本没有意义反而让模型学到错误的空间先验。第二旋转角度别超过15度。方向盘区域的物体姿态相对固定大角度旋转会把手和方向盘的关系搞乱。第三HSV扰动强度不能太大。红外图像没有彩色信息过度调色会让模型依赖伪色彩真实红外场景下反而失效。我的配置是mosaic1.0fliplr0.5hsv_h0.01hsv_s0.2hsv_v0.2旋转角度限制在±10度。这样增出来的样本既有变化又不会破坏座舱结构的真实性。5. 这个数据集还能怎么用5.1 疲劳驾驶判定与报警联动单个yawn类检测只能说明“这个人在打哈欠”但打哈欠并不一定等于疲劳。更合理的做法是把yawn检测结果和头部姿态、眼睛闭合时长结合起来做一个疲劳评分。我后来在项目里就是这样yawn事件每累计5次疲劳分数加1闭眼超过1秒分数加2当疲劳分数超过3才触发报警。这套逻辑用检测框很容易实现因为yawn的检测结果配上时间戳就是一个事件流。5.2 分心行为与座舱智能化除了安全报警行为检测还能做座舱的主动交互。检测到驾驶员在喝咖啡系统可以自动调整杯托加热模式检测到抽烟自动开启天窗换气检测到长时间看手机语音提醒注意前方。这些功能不需要很强的策略只要检测结果足够稳体验提升就非常明显。我用这套数据训出来的模型对接过一个简单的语音助手当日饮品检测准确率在90%以上时整个交互体验发生质变不再是噱头而是真能减少视线转移。5.3 多模态数据融合的补充单一摄像头在极端工况下始终有局限比如驾驶员用手挡住摄像头或者驾驶员转头幅度极大导致脸部出画。我后来在系统里加入了一个毫米波雷达方案监测呼吸和心跳作为音频特征再用本数据集训练的视觉检测结果做交叉验证。视觉和雷达置信度同时高的时候行为判断的可靠性显著提升。这个数据集的视觉检测结果作为fusion的一路输入非常适合用来做多传感融合算法开发。5.4 从2D检测到3D姿态估计如果你不满足于“框框检测”下一步可以基于这个数据集扩展出关键点标注把打哈欠、打电话这类行为从“框存在”升级到“人体姿态理解”。有了2D关键点再通过相机模型反推3D姿态就能做更精细的视线估计和手部轨迹预测。我这边已经在尝试用YOLO-pose联合检测人脸关键点和手部关键点实测在座舱场景下比单独训练躯干关键点模型稳定因为脸和手才是行为判断的核心区域。数据集里的类别定义在这个方向上依然适用只是需要在格式上做额外转换。5.5 迁移学习与模型迭代这套数据你不应该只用来训练一个模型就完事。我建议把它当作“母数据集”用来做不同硬件平台的适配。比如车载边缘盒子用YOLOv8s低算力MCU上拆成轻量化模型高算力座舱域控可以用YOLOv8x。同一份数据训练出来的模型在不同骨架上的表现可以帮你反推出硬件选型。很多团队先买算力再回头看模型结果浪费预算。先用数据跑通精度和速度空间再定硬件这个顺序更科学。一点实际操作中的体会整理数据远比训练模型耗时。22600张图片听起来不多但从采集、清洗、标注、校验到格式统一我前后折腾了一个多月。中间有无数次想放弃直接拿公开数据集凑合。但到了实车验证阶段数据多样性带来的收益非常直观。同样一个打电话动作公开数据集训练出来的模型在傍晚逆光下一会儿报一会儿不报我这边整理的数据因为包含了各种光照和角度输出稳定得多。如果让我给你一个建议不要纠结于“再标5000张会不会更准”先把手头数据用起来训一个初版模型然后去跑真实视频把误检漏检收集回来不断补充难例这才是数据集越用越强的正确路径。这套22600张的整理成果到今天还在我后续多个项目里复用每一轮难例补充都在变相给这套数据增值。至少对我来说它已经不是一份静态资源而是整个DMS项目的地基。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑