ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

煤矿井下安全帽数据集构建与YOLOv8检测实战

煤矿井下安全帽数据集构建与YOLOv8检测实战 简介煤矿井下作业安全监测场景中已标注安全帽数据集面向计算机视觉、目标检测方向的研究者与煤矿智能安防开发者可用于训练与评估安全帽佩戴识别模型。资源共436个文件包含218张井下实拍jpg图像及一一对应的218个xml标注文件标注采用边框形式标明安全帽位置压缩包整体约179.65MB格式规范便于直接转换为VOC或YOLO等常用训练格式。数据集覆盖多种井下光照与角度条件可支撑目标检测、佩戴合规检查、异常预警、行为分析等任务也可作为算法横向对比的基准数据。目前已有810人学习下载适合用于模型训练、调优与科研实验能有效节省自行采集和标注数据的时间和成本。 刚把煤矿井下安全帽数据集整理完最后一轮质检通过的时候整个人才真正松了口气。做安全帽检测的人都知道调模型其实是最简单的一步真正耗时间的是数据和标注。我之前试过直接用开源的通用安全帽检测模型跑井下监控视频效果一言难尽暗光下漏检、反光误检、遮挡漏检根本没办法直接上线。所以才决定自己从零构建一套煤矿井下安全帽数据集并且已经把全部图片完成标注。这篇就把整个数据采集、标注规范、质检流程和后续训练落地过程中的关键经验写出来给同样在做矿井智能监控的同行一个参考。1. 为什么煤矿井下安全帽检测值得单独做一个数据集1.1 井下场景和普通工地场景差异很大真的不是矫情。在做这个数据集之前我拿开源的安全帽检测模型在煤矿井下监控视频上跑了一轮结果漏检错检相当多。你会发现井下画面和普通工地完全不是一个物种普通工地有自然光安全帽颜色鲜明井下照明靠矿灯和巷道灯整体亮度低黄色安全帽在煤壁背景下变成暗黄色轮廓很模糊。更麻烦的是水雾和粉尘会让画面蒙上一层噪点矿灯直射镜头时会产生大面积过曝和反光这些干扰在工地数据集里很少出现。我把两类场景的差异整理成了下面这张表方便还没接触过矿区数据的人有个直观感觉场景维度普通工地煤矿井下光照条件自然光补光灯整体亮度高矿灯/巷道灯低照度、逆光、局部过曝背景纹理建筑结构、脚手架、绿网煤壁、皮带机、液压支架纹理复杂且颜色偏暗干扰因素车辆、行人、工具粉尘、水雾、煤泥、矿灯光晕安全帽形态颜色鲜艳轮廓完整煤粉附着后颜色发暗帽檐和头灯容易遮挡边界一旦用了通用模型最常见的失败模式是暗光下直接把安全帽当成背景压根没检出矿灯反光区域出现一个亮斑模型却把它当作安全帽框出来还有人员弯腰操作设备时安全帽只露出一小块模型认为目标太小直接忽略。这些失败模式直接影响矿山安全监管场景的可用性所以不能靠通用模型凑合。1.2 安全帽检测在矿山智能监控里的落地位置煤矿井下的作业安全管理里入井人员戴不戴安全帽是非常基础又高频的检查项。人工盯监控视频不现实几十路画面轮播人眼很容易疲劳所以需要靠视频分析算法自动识别“未佩戴安全帽”事件。实际工业落地时这类算法通常接在矿区的智能视频分析平台上对摄像头实时流做推理再通过告警联动通知安全员。这就要求模型在低照度、高噪声、强遮挡的井下画面里尽可能不放过任何一个人头。单靠通用预训练模型达不到现场要求必须有贴近井下分布的数据来微调甚至重新训练。也正因为如此一份“已标注”的煤矿井下安全帽数据集价值很大它既可以直接用于训练YOLO、Faster R-CNN这类检测模型也可以作为智慧矿山项目验收时的数据资产。数据处理流程并不复杂但每步都有坑我下面按实际搭建顺序展开。2. 数据集的构成与标注规范2.1 数据来源与场景覆盖构建数据集的第一个问题不是“选什么算法”而是“图从哪来”。我当时从矿区现场收集了多路摄像头的监控录像覆盖井口检身处、运输大巷、采掘工作面、皮带机头、避难硐室等位置同时尽量覆盖白班、夜班不同时段。采集完原始视频后用抽帧脚本按每秒1帧或2帧抽取再人工筛掉大量重复帧、模糊帧和纯静止画面最终保留约1.2万张有效图像。这里要特别强调场景覆盖的多样性。如果数据全来自同一个摄像头角度训练出来的模型换一个安装位置就很可能失效。我建议至少覆盖三个维度不同安装高度2米、3米、5米、不同朝向正面、侧面、俯视、不同环境状态干燥、喷雾降尘、淋水。另外涉及现场人员的图片要按数据合规要求做脱敏或内部授权处理这个在数据采集阶段就要和矿区沟通好不要等标注完再处理返工成本很高。2.2 标注类别用head和helmet而不是person标注时我采用的类别不是大家第一反应里的“person”和“helmet”而是“head”和“helmet”。原因很简单安全帽佩戴检测本质上是在判断“头部区域有没有被安全帽遮盖”如果只标注person一个成年人的框那么大即使没戴帽子也能检测到person无法直接判断是否佩戴。标注成head可以让模型精确定位头部再结合helmet框是否覆盖头部来判断佩戴状态。具体标注规则如下画面中只要出现可辨识的人头不管戴没戴安全帽都标注head如果该头部佩戴了安全帽则同时在安全帽的帽体外边缘标注helmet如果没戴安全帽则不标helmet。推理时用一个head框和所有helmet框计算IoU如果最大IoU大于某个阈值就认为该人员戴帽否则就是未戴帽。这套规则在后续业务逻辑里非常清晰也便于人工审核。有人可能问为什么不直接标注“戴帽人员”和“未戴帽人员”两个类别那样确实更直接但训练样本中同一个人在不同帧里会同时出现在两类里类别语义不稳定模型容易学偏。head加helmet的组合把“人的位置”和“帽子位置”解耦了实际效果更稳。2.3 标注格式选型VOC、YOLO还是COCO标注格式我建议不要把鸡蛋放在一个篮子里。原始标注选择VOC XML格式保存因为它是人类可读的XML文件里面记录图片名、尺寸、每个目标的类别和坐标方便做人工复核和脚本修改。随后通过脚本导出YOLO格式的txt文件用于YOLOv8等模型训练。COCO格式的JSON也可以一键导出主要用于Mask R-CNN等需要分割的模型但检测任务用不上时可以先不生成。YOLO格式的核心是每行一个目标格式为“class_id x_center y_center width height”坐标都是相对于图片宽高的归一化小数。VOC格式则是绝对像素坐标的xmin、ymin、xmax、ymax。从VOC转YOLO时需要做一次数学换算我后面会给出脚本。这里提醒一点很多标注工具默认保存成绝对像素坐标但不同工具的坐标系原点不一致有的从左上角开始有的从图片中心开始。如果混用工具一定要先统一格式否则模型训练时会莫名其妙损失大量梯度。3. 标注全流程实操选工具、做质检、避坑3.1 标注工具选型CVAT、X-AnyLabeling还是LabelImg标注工具的选择直接影响效率。我用过三套工具简单对比一下工具优点缺点适用场景LabelImg轻量、部署简单、单机可用只能手工框效率低不适合大规模几千张以下的快速验证CVAT支持Web多人协作、任务分配、自动标注扩展环境搭建麻烦中小项目用起来重团队协作标注、数据量数万张X-AnyLabeling支持加载自己训练的模型做自动预标注需要一定配置和模型文件单人半自动标注、快速迭代我实际使用的组合是先拿一个已经在公开数据集上训练过的安全帽检测模型对全部图片跑一遍推理生成预标注框再用X-AnyLabeling加载这套预标注结果人工逐张修改。对于井下这种单张图里目标数量通常只有1到5个人的场景人工修正速度能从每张1分钟降到15秒左右效率提升非常明显。3.2 标注质检的关键指标标注完成后不能急着训练质检一旦跳过后面的模型会不断“讨债”。我从三个维度把关第一是漏标率。随机抽5%到10%的图片人工重新数一遍画面里的人头再和标注框数量对比。如果漏标率超过1%说明标注员疲劳了需要把该批图片发回重标。第二是贴合度框要贴住目标边缘上下左右不要留太多背景对head来说尤其不要框进安全帽边缘对helmet来说要包含帽檐但不要包含肩部。第三是坐标合法性即用脚本确认所有坐标都在图片尺寸范围内宽高大于0类别名称没有拼写错误。我写了个最基础的检查脚本批量跑一遍目录下的YOLO标签文本。给个简化版参考import os from pathlib import Path label_dir Path(labels/train) bad_files [] for label_path in label_dir.glob(*.txt): with open(label_path) as f: for line in f: parts line.strip().split() if len(parts) ! 5: bad_files.append((label_path, 字段数错误)) continue cls, cx, cy, w, h parts[0], float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) if not (0 cx 1 and 0 cy 1 and 0 w 1 and 0 h 1): bad_files.append((label_path, 坐标越界或宽高非法)) break print(bad_files)这个脚本不能查漏标但能过滤掉格式错乱保证训练程序不会因为一行坏标签崩溃。3.3 井下场景标注避坑井下标注最大的坑不是工具而是“看不清”。暗光图片里安全帽和煤壁颜色几乎融在一起这时候我会在标注工具里临时调高亮度和对比度辅助分辨但保存的框仍然要基于原图坐标。千万不能直接把增强后的图像拿去训练因为测试时摄像头画面依然是暗的模型习惯暗图就好。第二个坑是“假安全帽”。粉尘、水雾和矿灯光晕会在图像上形成圆弧形高光特别像帽子边缘。标注团队内部必须统一只标注真实存在的人头和安全帽不标阴影、光晕、镜像。第三是严重遮挡问题。如果一个人只露出一条胳膊但没有头不标注如果头被矿车挡住半截但可见部分能明确判断出头部轮廓就标注可见部分如果安全帽被设备完全遮挡宁可漏标这一帧也不要打一个位置不准的框。第四点经验是安全帽上的头灯会突出在帽檐外不要刻意把灯光部分包含进helmet框否则模型会学习到“帽子带一条亮尾巴”部署时容易误检矿灯。这些规则看起来繁琐但只有定义得足够明确多个标注人员才能保持一致。我前期规则没定死结果三个人标出三种风格训练出来的模型在验证集上摇摆不定后期重标了三分之一的数据才恢复水准这个教训挺深刻。4. 从已标注数据到可用的训练集4.1 按视频来源划分数据集很多人在数据准备阶段直接做随机划分把图片随机分到训练集和验证集这对煤矿井下数据来说是一个隐蔽的坑。同一段监控视频里抽出来的帧高度相似如果同一摄像头下的图像同时出现在训练集和验证集模型会“背题”验证指标虚高部署到新点位后立刻原形毕露。正确的做法是先把所有图片按摄像头ID或视频文件归组再在组级别做划分。我采用的是按采集点分组大约80%的摄像头点位图片进训练集10%进验证集10%进测试集。测试集单独放好只允许在模型最终确定后测试一次不能拿它反复调参。4.2 数据增强策略井下场景的数据增强重点在光度扰动而不是几何扰动。我会在训练时开启亮度、对比度、饱和度扰动模拟不同矿灯角度和镜头曝光差异随机左右翻转是安全的因为监控画面里目标从左往右或从右往左出现概率均衡但不要用上下翻转监控摄像头固定在支架上画面很少倒置翻转会让模型学到不存在的姿态。YOLOv8的超参数里可以直接开启mosaic和mixup两个增强对小目标和遮挡目标帮助很大。不过训练后期我会把mosaic关闭否则小目标在合成图上占比不稳定最终mAP会波动。可以这么操作前80个epoch开mosaic后20个epoch关闭并继续微调。4.3 格式转换与路径修复从VOC到YOLO的转换不难但要批量处理时注意路径。我提供一个简化脚本import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, out_path, class_names): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_names: continue cls_id class_names.index(name) box obj.find(bndbox) x1 float(box.find(xmin).text) y1 float(box.find(ymin).text) x2 float(box.find(xmax).text) y2 float(box.find(ymax).text) cx (x1 x2) / 2 / img_w cy (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) with open(out_path, w) as f: f.write(\n.join(lines))有一个容易踩的坑确保每张训练图片都有对应的txt标签。如果某张图片里没有任何目标那它的txt文件应该是空文件而不是缺失。YOLOv8训练时缺失标签会导致图片被跳过或报错空文件是合法行为。5. 用YOLOv8训练煤矿安全帽检测模型5.1 环境准备与数据配置拿到“已标注”的数据集后最快的落地路径是YOLOv8。安装ultralytics包之后需要写一个data.yaml声明数据集路径、类别数量和类别名。我这里用head和helmet两个类别path: /path/to/dataset train: images/train val: images/val test: images/test nc: 2 names: 0: head 1: helmet然后运行训练命令yolo detect train datadata.yaml modelyolov8s.pt epochs100 imgsz640 batch16 device0预训练权重我推荐从yolov8s开始。yolov8n和yolov8s的推理速度差异不大但精度差距明显井下监控摄像头算力通常有限yolov8s在边缘设备上也能跑到实时。如果硬件允许试试yolov8m会有更多提升。5.2 训练参数与结果解读训练完成后重点看val目录下的结果文件和曲线。对于井下安全帽检测我更关注召回率recall而不是精确率precision因为在安全监管场景下漏掉一个未戴帽人员比多报一次警严重得多。理想情况是mAP50达到90%以上recall达到95%左右。如果你看到precision低但recall高说明模型把很多阴影误检成了安全帽这时可以调高置信度阈值或者检查标注数据里是否混入了“假帽子”。如果训练损失正常下降但验证mAP卡住优先怀疑标注质量问题不急着堆epoch。这时候把预测错误的图像可视化出来看往往能发现某些框的类别标反或者遮挡规则没统一。5.3 模型导出与部署时的易错点模型训练完要导出成ONNX或TensorRT引擎再部署到现场的推理服务器。导出本身很简单yolo export modelbest.pt formatonnx imgsz640但部署时有一个很常见的坑训练时的输入是letterbox后640x640导出ONNX后若推理端直接把原始1920x1080图片缩放成640x640没有做等比例缩放和填充目标比例会和训练分布不一致导致精度下降。正确做法是推理前先做letterbox推理后再按原始坐标比例还原检测框。另一个坑是类别过滤。现场只关心“未戴帽事件”那么模型输出的helmet框和head框需要做一次后处理逻辑遍历head框计算它与所有helmet框的IoU若最大IoU小于0.3则判定为未佩戴安全帽。这个阈值不是固定的要拿现场视频测试后确定过小会漏报过大会误报。最后提一个井下特有的坑矿灯强光下摄像头会出现大面积过曝模型在这种情况下会把整个亮斑识别成head。我在部署时给检测结果加了一个前置过滤只接受面积处于合理区间且宽高比在0.5到2.0之间的head框能过滤掉大量光斑误检。在一路皮带巷的摄像头实测下来这个简单规则让误报次数明显下降而计算量增加几乎可以忽略。这类后处理规则看起来不起眼但往往比盲目调模型参数更管用也最容易被刚入门的人忽略。本文还有配套的精品资源点击获取
返回列表