简介:这份火灾烟雾人员检测数据集面向智能消防、安防监控与应急救援方向的算法开发者与研究者,用于训练和评估火灾场景下的多目标检测模型。数据全部来自真实监控与航拍环境,覆盖室内外不同光照与天气条件,标注为YOLO格式,可直接接入YOLOv5、v7、v8等主流框架,无需额外转换。压缩包共1800个文件,包含899张jpg图像、899个同名txt标注、1个yaml配置文件与1份docx说明文档,整体约36.53MB,目录结构清晰,便于按训练、验证、测试划分快速加载。其中训练集744张、验证集110张、测试集45张,类别涵盖火焰、烟雾与人员三类目标,可支撑火灾早期预警、公共场所危险源与人员同步检测、救援机器人视觉导航、森林防火监测及工业安全管控等任务。目前已有355人学习下载,适合需要真实场景数据、追求即用性与多目标协同检测效果的中高级视觉开发者参考使用。
1. 火灾烟雾人员检测数据集:一份能直接喂给 YOLO 的工业级样本包
做消防视觉项目的同行大概都有过这种经历:算法框架搭好了,模型结构也调通了,结果卡在数据上——网上能找到的公开火灾数据集要么只有火焰没有烟雾,要么标注格式五花八门,更别提把「人员」这个类别单独标出来。这份火灾烟雾人员检测数据集.zip 解决的正是这个卡脖子环节。它把火灾场景下三类目标——火焰、烟雾、人员——打包成一套可直接用于 YOLO 系列训练的标注数据,省掉了从爬图、清洗到标注的整条脏活链路。适合谁用?做智慧消防、工地安全帽识别、园区烟火预警的算法工程师,以及需要快速验证检测方案的学生和独立开发者。下面我从数据构成、格式转换、训练接入到踩坑排查,把这份资源拆开讲透。
2. 数据集构成与 YOLO 格式适配:先看清标签再动手
2.1 三类目标的标注逻辑与目录结构
拿到压缩包解压后,常见做法是先别急着写训练脚本,而是把目录结构和标签文件翻一遍。这类工业数据集通常按images/和labels/平行存放,images下再分train、val,labels下对应同名.txt。每行标签遵循 YOLO 标准:class_id x_center y_center width height,坐标全部归一化到 0~1。三类目标的class_id一般是0=fire、1=smoke、2=person,但不同批次可能顺序不同,必须以随包附带的classes.txt或data.yaml为准。
我一般会先跑一段统计脚本,确认每个类别的实例数量和图片分布,避免训练到一半才发现某个类别只有几十个框。
import os from collections import Counter label_dir = "labels/train" counter = Counter() img_with_person = 0 for fname in os.listdir(label_dir): if not fname.endswith(".txt"): continue with open(os.path.join(label_dir, fname)) as f: lines = [l.strip() for l in f if l.strip()] classes = [int(l.split()[0]) for l in lines] counter.update(classes) if 2 in classes: # 假设 2 是 person img_with_person += 1 print("类别实例统计:", dict(counter)) print("含人员的图片数:", img_with_person)这段脚本做两件事:统计每个class_id出现的总次数,以及统计包含「人员」类别的图片数量。参数上只需改label_dir指向你的标签目录,2换成你data.yaml里 person 对应的编号。如果发现 person 实例远少于 fire 和 smoke,说明数据存在类别不平衡,后面训练时要么加copy_paste增强,要么在损失里给 person 更高权重。
2.2 从 VOC/COCO 到 YOLO 的格式转换
有些批次的资源会同时附带 XML 或 JSON 原始标注,方便你转成其他框架。如果你拿到的是 VOC 的 XML,转 YOLO 的核心是把绝对坐标除以图片宽高。下面这个转换脚本我用了很多次,处理边界框越界和图片缺失两个高频问题。
import os import xml.etree.ElementTree as ET from PIL import Image classes = ["fire", "smoke", "person"] xml_dir = "annotations" img_dir = "images" out_dir = "labels" os.makedirs(out_dir, exist_ok=True) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(".xml"): continue tree = ET.parse(os.path.join(xml_dir, xml_file)) root = tree.getroot() img_name = root.find("filename").text img_path = os.path.join(img_dir, img_name) if not os.path.exists(img_path): print("缺图跳过:", img_name) continue w, h = Image.open(img_path).size lines = [] for obj in root.findall("object"): cls = obj.find("name").text if cls not in classes: continue cid = classes.index(cls) bbox = obj.find("bndbox") x1 = float(bbox.find("xmin").text) y1 = float(bbox.find("ymin").text) x2 = float(bbox.find("xmax").text) y2 = float(bbox.find("ymax").text) # 裁剪越界坐标,防止归一化后超出 0~1 x1, y1 = max(0, x1), max(0, y1) x2, y2 = min(w, x2), min(h, y2) xc = (x1 + x2) / 2 / w yc = (y1 + y2) / 2 / h bw = (x2 - x1) / w bh = (y2 - y1) / h lines.append(f"{cid} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}") with open(os.path.join(out_dir, xml_file.replace(".xml", ".txt")), "w") as f: f.write("\n".join(lines))逻辑说明:先按classes列表确定类别顺序,保证和data.yaml一致;max(0, x1)和min(w, x2)是血泪经验,标注员手抖把框拖出图片边界是常事,不裁剪的话归一化坐标会出现负数或大于 1,YOLO 训练时直接报错或学出诡异框。参数上classes必须和你的data.yaml完全对应,顺序错了模型会把烟雾当人员。转换完建议抽查几张可视化,确认框位置没偏移。
2.3 data.yaml 的写法与路径陷阱
YOLOv5/v8 都靠data.yaml定位数据和类别名。一个能跑的配置长这样:
path: /home/user/fire_dataset train: images/train val: images/val nc: 3 names: ["fire", "smoke", "person"]path用绝对路径最稳,相对路径在不同工作目录下启动训练时经常翻车。nc必须等于names长度,多一个少一个都会在加载时抛断言错误。如果你的验证集和训练集共用标签目录,val只写图片路径即可,YOLO 会自动把images替换成labels去找标签——这个隐式规则很多人不知道,导致明明标签存在却报「找不到 label」。
3. 训练接入与参数配置:把数据集跑起来
3.1 用 YOLOv8 跑通第一轮基线
数据格式确认无误后,先跑一个最小基线,别一上来就堆 epoch。下面命令用 YOLOv8n 这种小模型快速验证数据管道是否通畅。
yolo detect train \ data=/home/user/fire_dataset/data.yaml \ model=yolov8n.pt \ epochs=50 \ imgsz=640 \ batch=16 \ project=fire_runs \ name=baseline参数说明:imgsz=640是工业检测的常用起点,火灾烟雾目标通常占画面比例不小,640 够用;batch=16在 8G 显存上比较稳,显存不够就降到 8 并配合accumulate;epochs=50只是看 loss 是否正常下降,真正收敛通常要 150 以上。跑完先看results.png里的mAP50曲线,如果前 10 个 epoch 就平了,八成是标签或路径有问题,而不是模型不行。
3.2 针对烟雾和人员的增强策略
火灾场景有两个特殊性:烟雾是半透明、边界模糊的目标,人员往往被烟雾遮挡。默认增强里mosaic和mixup对烟雾有帮助,但mixup开太大会让烟雾和背景糊成一团。我一般这样调:
# 在 hyp 配置或命令行覆盖 mosaic: 1.0 mixup: 0.1 copy_paste: 0.3 hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 degrees: 5.0 translate: 0.1 scale: 0.5copy_paste=0.3对人员类别特别有用,它把人员实例复制粘贴到其他图上,缓解 person 样本不足。hsv_s=0.7提高饱和度扰动,让模型适应不同光照下的火焰颜色。degrees=5.0只做小角度旋转,火灾监控摄像头基本是固定的,大角度旋转反而引入不真实样本。这些值不是金科玉律,但作为起点比默认值更贴合消防场景。
3.3 训练日志里该盯哪几个指标
跑起来之后别只等结果,日志里有几个信号要实时看。box_loss和cls_loss应该同步下降,如果cls_loss震荡而box_loss平稳,通常是类别不平衡或标签有噪声。mAP50和mAP50-95的差距能反映框的定位精度,火灾烟雾这种边界模糊的目标,mAP50-95偏低是正常的,别为了刷这个指标去改标注。另外注意val/val_loss,如果它持续上升而训练 loss 下降,就是过拟合,该加增强或减模型规模了。
4. 避坑与排查:那些让我重跑过训练的坑
4.1 现象:训练启动即报「No labels found」
原因:YOLO 默认按images→labels的路径替换规则找标签,如果你的目录名不是标准的images/labels,或者val写成了绝对路径而标签在别处,它就找不到。解决:要么把目录改成标准结构,要么在data.yaml里显式写train和val的图片路径,并确保同级存在同名labels目录。我习惯转换完先跑一次yolo detect train ... epochs=1做冒烟测试。
4.2 现象:mAP 一直是 0 或接近 0
原因:names顺序和标签里的class_id对不上,或者归一化坐标没做。常见于自己转格式时忘了除以宽高。解决:用 2.1 的统计脚本确认class_id分布,再随机抽一张图用labelImg或脚本可视化,看框是否落在目标上。坐标没归一化的框会全部挤在图片左上角。
4.3 现象:烟雾类别召回率极低
原因:烟雾标注本身模糊,不同标注员对「烟雾边界在哪」判断不一致,导致同一类目标框大小差异巨大。解决:训练前做一次框尺寸聚类,用 K-means 看width/height分布,把极端离群的框挑出来复核。另外可以适当降低烟雾的置信度阈值做推理,先保召回再谈精度。
4.4 现象:显存溢出(CUDA out of memory)
原因:batch或imgsz设太大,或者workers开太多导致数据加载进程占满内存。解决:先把batch减半,再降imgsz到 512;workers在 Windows 上设 0 或 2,Linux 上可以到 8。如果还爆,检查是不是cache=True把整个数据集缓存进内存了,大数据集别开。
4.5 现象:验证集指标好但实际推理漏检
原因:训练集和验证集可能来自同一段视频的相邻帧,存在数据泄漏,模型记住了背景而不是目标。解决:按视频或时间段划分 train/val,而不是随机抽帧。如果资源包里已经分好,检查一下train和val里有没有高度相似的图片,有的话手动挪走。
5. 进阶技巧:用切片推理和类别权重把烟雾人员检测再提一档
基础训练跑通后,如果指标还差口气,有两个技巧我反复用过。第一个是切片推理(SAHI),火灾监控画面里烟雾和人员往往只占一小块,整图缩放到 640 后小目标信息丢失严重。SAHI 把大图切成重叠小图分别检测再合并,对烟雾边缘和远处人员提升明显。用法上先装sahi,然后:
from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction model = AutoDetectionModel.from_pretrained( model_type="yolov8", model_path="fire_runs/baseline/weights/best.pt", confidence_threshold=0.3, device="cuda:0" ) result = get_sliced_prediction( "test_fire.jpg", model, slice_height=512, slice_width=512, overlap_height_ratio=0.2, overlap_width_ratio=0.2 ) result.export_visuals(export_dir="sahi_out")slice_height/width=512配合overlap=0.2是精度和速度的平衡点,切片太小会切碎大火焰,太大又失去小目标优势。第二个技巧是在损失里给 person 类别加权。YOLOv8 不直接暴露类别权重,但可以通过复制 person 样本或自定义cls_pw实现。我一般用更土的办法:把含 person 的图片在训练列表里重复一遍,简单但有效。
验证提升是否真实,别只看mAP。我习惯固定一组现场图,用同一套置信度跑推理,人工数漏检和误检。有一次mAP涨了 3 个点,但现场图里烟雾误报反而多了,原因是验证集里烟雾样本和训练集太像。从那以后我每次调完参,都强制走一遍独立现场图验证,不看验证集指标就下结论。希望这份数据集和上面的流程,能帮你把消防视觉项目从「跑通」推到「敢用」。
本文还有配套的精品资源,点击获取