首页 / 资讯中心 / 文章详情

疲劳驾驶监测数据集实战:从数据清洗到疲劳判断入门

疲劳驾驶监测数据集实战:从数据清洗到疲劳判断入门 ★ FEATURED ARTICLE
简介这份疲劳驾驶监测数据集面向深度学习与图像识别方向的入门学习者适合作为目标检测新手练习的小项目素材。数据采集自驾驶员疲劳状态下的真实图像建议以打哈欠张嘴和闭眼两类状态作为疲劳判定标准帮助读者搭建从数据清洗到模型训练的基础流程。压缩包共约2000个文件以2915张jpg图像和2914个xml标注文件为主jpg用于模型输入xml提供对应目标框标注整体约256.28MB。需要留意的是原数据集中存在图片与标注不匹配的情况资源描述中附有一段Python脚本可遍历JPEGImages与Annotations目录删除缺少同名xml的图片为后续训练扫清脏数据障碍。目前已有4742人学习下载读者可借此熟悉VOC格式数据组织、标注校验与疲劳状态分类思路完成一次完整的小型图像识别实践。1. 从一张打哈欠的照片说起疲劳驾驶监测数据集到底是什么你有没有过这种经历开车上高速开着开着眼皮开始打架等反应过来的时候已经过了好几个出口后背一阵发凉。疲劳驾驶这件事危险就危险在它来得悄无声息。那能不能让机器帮我们盯着比如车里装个摄像头一旦发现司机开始频繁打哈欠、眼睛眯成一条缝就立刻发出提醒。这个想法听起来挺酷但真动手做的时候第一个卡住你的问题往往不是算法而是——我上哪儿找那么多“疲劳状态”的照片去这份疲劳驾驶监测数据集解决的就是这个“没米下锅”的问题。它是一批已经整理好的驾驶员面部图像每张图都配了一份 XML 标注文件里面记录了人脸的位置和关键点信息。你可以把它理解成一个“疲劳表情素材库”有人闭眼的、有人张嘴打哈欠的、有人正常睁眼开车的。对于刚接触图像识别和深度学习的新手来说它最大的价值是让你跳过最枯燥的“找图、标图”阶段直接进入“训练模型、看效果”的正反馈循环。适合谁适合已经学过一点 Python、想找个真实小项目练手但又被各种“从零搭建”教程劝退的人。2. 为什么值得从这份数据集入手新手练项目最怕的三件事它都避开了2.1 第一怕没数据1429 张图加标注够你跑通完整流程很多新手学深度学习卡在第一步不是不会写代码而是不知道拿什么数据练。网上公开的大数据集动辄几十 G下载慢、解压久好不容易跑起来还发现显存不够。这份数据集里的图像数量适中配合 XML 标注文件刚好够你走完“读数据 → 预处理 → 搭模型 → 训练 → 看结果”这一整条链路。它不会让你在数据加载上耗掉三天耐心也不会小到模型根本学不出东西。更重要的是它自带标注。XML 文件里通常包含人脸框的坐标和关键点位置这意味着你可以直接做两件事一是裁剪出人脸区域二是定位眼睛和嘴巴。对于疲劳检测这个任务来说眼睛闭合程度和嘴巴张开程度就是最核心的两个信号。你不用自己从头标数据省下来的时间可以花在理解模型为什么能判断“疲劳”上。2.2 第二怕任务太玄疲劳判断的逻辑新手用肉眼就能验证有些深度学习项目比如语义分割或者目标检测效果好不好得靠指标算新手看半天也不知道模型到底学没学会。疲劳检测不一样它的判断标准非常直观眼睛闭着的时间比例高、嘴巴张开的频率高那就倾向疲劳。你甚至可以先不训练模型自己写几行规则用标注里的关键点算一算眼睛纵横比就能得到一个粗糙但能跑的基线。这种“肉眼可验证”的特性对新手特别友好。你训练完一个模型拿几张图一测马上能看出它是真学到了还是瞎猜。这种即时反馈是坚持学下去的重要动力。而且当你发现规则方法在光线变化、戴眼镜等情况下容易翻车时自然就会想去了解深度学习到底强在哪里——这个学习动机比任何教程都管用。2.3 第三怕环境复杂一个 Python 脚本就能开始清理数据这份数据集还有一个很实在的好处它的使用门槛低。你不需要配置复杂的标注工具也不需要理解分布式训练。摘要里给了一段参考代码用 Python 的 os 和 shutil 库就能完成数据清洗。这意味着你打开编辑器装好 Python就能开始动手。对于零基础的人来说“能立刻跑起来”比“理论多完美”重要得多。提示新手最容易犯的错是一上来就想把模型精度调到最高。先让流程跑通哪怕准确率只有百分之六七十也比卡在环境配置上强。3. 动手之前先避坑数据不匹配是这份数据集最大的暗礁3.1 图片和标注对不上训练时直接报错现象你写了个 DataLoader准备把图片和 XML 配对读进来结果程序跑着跑着突然报 FileNotFoundError说某个 XML 找不到对应的图片或者反过来。原因原数据集在整理过程中可能因为复制中断、重命名失误等原因导致一部分图片文件没有对应的标注文件或者标注文件成了“孤儿”。这种不匹配在数据量小的时候不明显一旦开始批量训练就会暴露。解决在训练之前先跑一遍数据清洗脚本把没有标注的图片删掉或者把没有图片的标注删掉。摘要里给出的代码就是干这个的核心逻辑是遍历图片文件夹检查每个图片名对应的 XML 是否存在于标注文件夹不存在就删除该图片。3.2 路径写错脚本删了个寂寞现象你照着参考代码改了路径运行完发现图片数量没变或者更糟——把别的文件夹清空了。原因参考代码里的路径是示例直接复制很容易漏掉层级或者用错斜杠方向。比如Dataset/dataset/JPEGImages这种嵌套少写一层就找不到。解决运行删除操作前先打印一下len(jpeg_list)和len(anno_list)确认读到的文件数量符合预期。然后再把os.remove那一行先注释掉换成print输出要删除的文件名肉眼检查一遍没问题再真正执行。3.3 删完不备份想回头都难现象清洗完数据训练到一半发现删多了想把某些图找回来结果回收站也清空了。原因os.remove是直接删除不进回收站。新手在调试阶段很容易因为路径参数写错而误删。解决第一次跑清洗脚本时不要用os.remove用shutil.move把不匹配的图片移动到一个trash文件夹。确认模型训练正常后再决定要不要彻底删除。这个习惯能给你留一颗后悔药。3.4 忽略 XML 内容只看文件名现象图片和 XML 文件名对上了但训练时模型学不动损失降不下去。原因有些 XML 文件可能是空的或者标注框坐标全是 0这种“假标注”光看文件名发现不了。解决在清洗完文件名不匹配之后再抽检几个 XML打开看看里面有没有object节点坐标是不是合理。如果发现一批 XML 内容异常也要一并处理掉。3.5 清洗完不重新划分训练集和验证集现象清洗前划分好了训练集和验证集清洗后直接拿旧划分去训练结果验证集里混进了被删掉的图片路径。原因数据清洗改变了文件列表但划分文件没有同步更新。解决每次清洗数据后重新跑一遍划分脚本确保训练集、验证集、测试集里的每一张图都真实存在。这个步骤多花两分钟能省掉后面排查半天的心力。4. 第一个能跑的例子从清洗数据到读出第一张图4.1 先跑通数据清洗脚本打开你的代码编辑器新建一个clean_data.py。把摘要里的参考代码抄进去但注意把路径改成你本地解压后的实际路径。下面是我整理过的版本加了几行打印和备份逻辑更适合新手第一次运行import os import shutil # 原始图片文件夹路径根据你解压的位置修改 jpeg_dir Dataset/dataset/JPEGImages # 标注文件夹路径 anno_dir Dataset/dataset/Annotations # 备份文件夹用来存放不匹配的图片而不是直接删除 trash_dir Dataset/trash # 如果备份文件夹不存在就创建 if not os.path.exists(trash_dir): os.makedirs(trash_dir) # 列出所有图片和标注文件 jpeg_list os.listdir(jpeg_dir) anno_list os.listdir(anno_dir) print(f图片总数: {len(jpeg_list)}) print(f标注总数: {len(anno_list)}) count 0 for pic in jpeg_list: # 去掉图片后缀拿到文件名主体 name pic.split(.)[0] # 拼接对应的 XML 文件名 anno_name name .xml # 如果这个 XML 不在标注列表里说明图片没有对应标注 if anno_name not in anno_list: src os.path.join(jpeg_dir, pic) dst os.path.join(trash_dir, pic) shutil.move(src, dst) # 移动到备份文件夹而不是直接删除 count 1 print(f已移出无标注图片: {pic}) print(f共处理 {count} 张不匹配图片)这段代码的逻辑很直白遍历图片文件夹里的每一个文件把文件名的主体部分拿出来拼上.xml后缀然后去标注列表里查。查不到就说明这张图没有对应的标注把它移到trash文件夹。用shutil.move而不是os.remove是给新手留一条退路。运行完之后你会看到打印出来的图片总数、标注总数以及被移出的图片数量。如果被移出的数量是 0那说明你的数据本来就是匹配的可以直接进入下一步。4.2 用 Python 读出第一张图看看清洗完数据下一步是确认你能正常读取图片和标注。新建一个check_data.py写几行代码把第一张图和它的 XML 内容读出来import os import cv2 import xml.etree.ElementTree as ET jpeg_dir Dataset/dataset/JPEGImages anno_dir Dataset/dataset/Annotations # 取第一张图片 first_pic os.listdir(jpeg_dir)[0] pic_path os.path.join(jpeg_dir, first_pic) print(f正在读取: {pic_path}) # 用 OpenCV 读图片 img cv2.imread(pic_path) if img is None: print(图片读取失败检查路径或文件是否损坏) else: print(f图片尺寸: {img.shape}) # 打印高度、宽度、通道数 # 读取对应的 XML name first_pic.split(.)[0] xml_path os.path.join(anno_dir, name .xml) tree ET.parse(xml_path) root tree.getroot() # 遍历 XML 里的 object 节点打印标注信息 for obj in root.findall(object): label obj.find(name).text bbox obj.find(bndbox) xmin bbox.find(xmin).text ymin bbox.find(ymin).text xmax bbox.find(xmax).text ymax bbox.find(ymax).text print(f标注类别: {label}, 框坐标: ({xmin}, {ymin}, {xmax}, {ymax}))这里用到了两个库cv2是 OpenCV用来读图片xml.etree.ElementTree是 Python 自带的 XML 解析库不用额外安装。代码先取图片文件夹里的第一个文件打印它的尺寸然后找到同名的 XML解析出里面的object节点。每个object通常包含一个name类别标签和一个bndbox边界框坐标。如果你看到类似“标注类别: face, 框坐标: (120, 80, 300, 260)”的输出说明数据读取链路是通的。注意如果cv2.imread返回 None先检查图片路径里有没有中文或空格再确认图片文件本身能不能用系统看图软件打开。这两个原因占了新手读图失败的九成。4.3 把疲劳判断的规则先写出来数据能读了先别急着上神经网络。用标注里的关键点或者边界框写一个最简单的疲劳判断规则能帮你建立对任务的直觉。假设 XML 里标注了眼睛和嘴巴的位置你可以算一个“嘴巴张开高度”和“眼睛闭合高度”的比值。下面是一个示意性的伪代码逻辑# 假设已经从 XML 中解析出左眼、右眼、嘴巴的坐标 # 这里用变量代替具体解析过程 left_eye_height 8 # 左眼上下关键点距离 right_eye_height 7 # 右眼上下关键点距离 mouth_height 25 # 嘴巴上下距离 # 眼睛闭合阈值如果眼睛高度小于某个值认为闭眼 eye_threshold 5 # 嘴巴张开阈值如果嘴巴高度大于某个值认为打哈欠 mouth_threshold 20 eye_closed (left_eye_height eye_threshold) and (right_eye_height eye_threshold) mouth_open mouth_height mouth_threshold if eye_closed or mouth_open: print(疲劳状态) else: print(正常状态)这段代码没有任何机器学习纯粹是规则判断。它的意义在于让你亲手体验一下“从数据到判断”的完整过程。你会发现阈值定多少很依赖具体图片光线一变、角度一偏规则就不准了。这种“规则不够用”的挫败感恰恰是你接下来学习深度学习的动力——神经网络能从大量样本里自己学出更鲁棒的特征而不是靠你手动调阈值。5. 从跑通到学下去新手下一步该往哪儿走第一个例子跑通之后你手里已经有了一个能读数据、能看标注、能写简单规则的小脚本。接下来最自然的路径是把规则替换成一个真正的图像分类模型。入门的话建议先不要碰目标检测而是做“二分类”把图片裁成人脸区域然后判断这张脸是“疲劳”还是“正常”。这样你只需要一个卷积神经网络输入一张小图输出两个概率训练流程和 MNIST 手写数字识别几乎一样只是数据换成了真实人脸。具体怎么走第一步用 XML 里的边界框把每张图的人脸区域裁剪出来保存成统一尺寸的小图比如 128x128。第二步根据标注里的关键点或者文件名规则给每张图打上“疲劳”或“正常”的标签。摘要里提到可以把打哈欠张嘴的状态和闭眼的状态作为疲劳标准这个思路很实用。第三步用 PyTorch 或 TensorFlow 搭一个简单的 CNN跑一个训练循环。第一次训练不用追求高准确率先看损失能不能下降验证集准确率能不能超过随机猜。我第一次做类似项目的时候犯过一个很典型的错误把所有数据都拿来训练没有留验证集结果模型在训练集上准确率冲到 99%一拿新图片测试就翻车。从那以后我每次划分数据都强制走一遍“训练集 70%、验证集 15%、测试集 15%”的流程哪怕数据量再小也不省这一步。这个习惯帮我省掉了无数次“以为模型很行、实际很不行”的尴尬。再往后你可以尝试把静态图片换成视频流用 OpenCV 读摄像头每隔几帧做一次判断统计一段时间内的疲劳次数。到这一步你就已经从一个“跑通例子”的新手变成了能做出一个小 Demo 的入门者。这份数据集里的 1429 张图就是你这一路最好的练习素材。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站