资讯动态

火焰烟雾检测数据集整理与YOLOv8训练实战指南

发布时间:2026/9/11 22:37:31 来源:尧图企业网站定制
简介面向火焰烟雾检测任务的数据集压缩包采用YOLO格式图片由人工精心挑选并标注场景覆盖广阔可直接作为通用模板数据集针对特定环境只需补充少量现场数据即可完成适配省去了自行收集、筛选与标注的繁琐过程。压缩包共332个文件约32.18MB核心内容包括txt/names等标注与类别文件yaml/cfg模型配置文件py/sh训练及预处理脚本以及Darknet框架的C/CUDA源码如detector、yolo_layer等便于二次开发与底层调试同时附有jpg示例图片和mp4演示视频供快速预览效果。目前已有2017人学习下载。这份数据集不仅包含高质量标注数据还内置了可运行的代码链路与模型权重适合深度学习目标检测初学者系统学习也适合工业应用开发者直接集成到火焰烟雾检测项目中加速算法验证与落地。1. 火焰烟雾检测刚起步时最容易卡住的是手里的zip数据集做工业安全、森林防火或工地监控的人订单里大概率会出现“火焰烟雾识别”这个需求。于是你会去搜数据集运气好会找到一个“火焰烟雾数据集YOLO.zip”看着名字像是能直接塞进YOLO训练。但实际解压之后目录可能是乱的标签可能是标到一半的VOC格式甚至同一张图被复制到train和val两遍。真正能跑通训练的人往往不是靠运气而是靠一套固定的整理流程。这篇内容就顺着“拿到的zip离能训练还差几步”来展开从解压、标注格式转换、data.yaml配置到训练参数和常见报错排错最后讲一个验证模型是否被烟雾干扰的实操方法。适合正在用YOLOv5或YOLOv8训练自己数据集的读者尤其是第一次处理火焰烟雾这类半透明目标的人。2. 从zip到YOLO训练集先理清火焰烟雾数据集的目录与标注格式2.1 解压后的标准目录结构长什么样常见的“火焰烟雾数据集YOLO.zip”解压后真正能被YOLO训练流程直接使用的结构是下面这样的。注意不要求数据集作者一开始就标准但你要有能力把任意的zip整理成标准结构。unzip 火焰烟雾数据集YOLO.zip -d ./fire_smoke cd ./fire_smoke tree -L 2一个可用的train/val目录结构fire_smoke/ ├── images/ │ ├── train/ │ │ ├── fire_001.jpg │ │ └── smoke_001.jpg │ └── val/ ├── labels/ │ ├── train/ │ │ ├── fire_001.txt │ │ └── smoke_001.txt │ └── val/ └── data.yaml这里的关键不是tree输出好看而是images/train和labels/train下的文件名前缀必须严格一致。YOLO训练时是拿图片像素再去读同名的txt标签文件名对不上直接跳过该样本且不报错。另一个常见问题是zip里套zip解开第一层发现里面还有一个“火焰烟雾标注版.zip”这种情况我一般先用find . -name *.zip扫一遍再二次解压避免训练到一半发现数据集不完整。2.2 火焰烟雾标注格式从VOC/COCO转成YOLO txt的正确姿势很多公开的火焰烟雾数据集合规的标注是VOC格式的XML或者COCO的JSON。YOLO则需要每一张图对应一个txt文件文件内每行是class_id x_center y_center width height注意这五个值全部是归一化坐标取值范围[0,1]不是像素值。x_center是目标框中心点的横坐标占图片宽度的比例width是目标框宽度占图片宽度的比例。如果你直接拿像素值填进去训练时边界框会飞出图片损失直接NaN。下面是一个把VOC XML批量转成YOLO txt的脚本这是处理火焰烟雾数据集时最常见的一步。import os import xml.etree.ElementTree as ET from glob import glob # 类别要保持固定顺序YOLO用索引表示类别 CLASSES [fire, smoke] def convert_xml_to_yolo(xml_path, out_path, img_w, img_h): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.iter(object): cls_name obj.find(name).text if cls_name not in CLASSES: continue cls_id CLASSES.index(cls_name) bndbox obj.find(bndbox) x1 float(bndbox.find(xmin).text) y1 float(bndbox.find(ymin).text) x2 float(bndbox.find(xmax).text) y2 float(bndbox.find(ymax).text) x_center (x1 x2) / 2 / img_w y_center (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) with open(out_path, w) as f: f.write(\n.join(lines)) for xml_path in glob(annotations/*.xml): # 实际上图片尺寸要从对应图片读不能假设全图一致 # 这里只是演示结构真实场景请使用PIL或cv2读取 img_w, img_h 640, 640 out_path labels/ os.path.basename(xml_path).replace(.xml, .txt) convert_xml_to_yolo(xml_path, out_path, img_w, img_h)逻辑说明脚本先固定类别顺序确保fire是0、smoke是1然后从XML里取边界框的左上角和右下角像素坐标最后通过归一化公式计算中心点和宽高。参数说明CLASSES顺序一旦确定后面训练时的data.yaml里names也必须用同一个顺序否则模型预测的类别索引对不上真实类别。需要强调一个容易踩的坑图片尺寸不要用固定值。火焰烟雾图片有竖屏有横屏分辨率从480p到4K都有。正确做法是先用cv2或PIL读一遍图片宽度和高度再传入脚本否则边界框位置全部偏移。2.3 验证标签与图片是否对齐数据集整理完不能急着训练。跑下面这个命令能快速找出没有标签的图片和没有图片的标签文件。cd fire_smoke for f in images/train/*.jpg; do base$(basename $f .jpg) [ -f labels/train/$base.txt ] || echo missing label: $f done for f in labels/train/*.txt; do base$(basename $f .txt) [ -f images/train/$base.jpg ] || echo missing image: $f done这段逻辑很简单第一个循环遍历训练图片检查同名txt是否存在第二个循环反向遍历标签文件。运行后只要没有任何输出就说明对齐通过了。我再补充一个检查统计标签文件里的行数如果是0行说明该图片没有目标。YOLO允许空标签但训练时这类图片只会贡献背景损失如果数量太多会让模型偏向“什么都不检测”。3. 用YOLOv8训练火焰烟雾模型数据集配置与关键参数3.1 准备data.yaml的四个必填项当目录结构整理好之后下一步是编写data.yaml。这是YOLOv8训练自己数据集时的入口配置路径错误会导致训练直接失败。# data.yaml path: /home/yourname/fire_smoke # 数据集根目录 train: images/train val: images/val names: 0: fire 1: smokepath是根目录的绝对路径推荐写绝对路径避免不同终端当前目录不同导致定位失败。train和val是相对path的路径注意这里只需要到images目录YOLO会自动把images替换为labels去找对应txt。names必须从0开始连续编号如果你的类别只有一个fire也要写作0: fire不能从1开始。这里额外说一个和“kitti标注转yolo”相通的经验KITTI数据集的类别有Car、Pedestrian多个转换时同样要求类别索引连续。如果你在data.yaml里写了0和2跳过了1YOLO训练时索引会错乱损失函数计算会拿到错误的类别数。3.2 训练命令与超参数选择YOLOv8训练火焰烟雾模型的最小命令如下yolo detect train \ data/home/yourname/fire_smoke/data.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ device0参数说明modelyolov8s.pt是YOLOv8的s规格预训练权重火焰烟雾这类目标不算特别复杂s规格足够如果你的数据集中小目标很多可以换成yolov8s.yaml从头训练或继续用s预训练但不建议直接上x规格训练时间会成倍增加。imgsz640表示训练分辨率烟雾对比度低且边界模糊低于640容易丢失细节。batch取决于显存显卡是RTX 3060 12G时可以设16如果是8G显存请降低到8。训练过程中要盯两个指标box_loss和cls_loss。如果box_loss持续下降到0.06以下但是验证集mAP50不涨说明过拟合了。火焰和烟雾的相似度会造成类别混淆最常见的表现是mAP50-95远低于mAP50这时需要加大数据增强。3.3 针对火焰烟雾小目标的数据增强参数火焰烟雾在画面里的尺度变化极大远处森林火灾的烟雾可能只占几十个像素近景的火焰几乎占满全图所以YOLO自带的增强策略要调整。# aug.yaml augment: true hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 fliplr: 0.5 scale: 0.5 mosaic: 1.0 mixup: 0.2 close_mosaic: 10在训练命令中加入cfgaug.yaml即可。这些参数里最值得注意的是hsv_h。火焰的颜色偏橙红烟雾偏灰白如果色调扰动太大火焰可能会变成紫色烟雾变成绿色这种增强对真实场景没有意义。我一般会把hsv_h压到0.015颜色亮度饱和度改动可以略大。close_mosaic: 10表示训练最后10个epoch关闭马赛克增强因为mosaic拼接的图像中火焰烟雾可能被拼接缝压扁导致模型学到的边界框形状失真。如果你遇到“yolo实例分割”场景比如要分割火焰边缘那么数据增强参数需要额外加一个degrees: 10允许小角度旋转。因为旋转会让烟雾的羽流形状变化但火焰的柱状外形对旋转其实很敏感旋转角度大了会让模型误以为出现新的形态。4. 训练卡住/不收敛/漏检时的排错路径4.1 zip解压后图片损坏导致的失败数据集的zip文件在传输过程中可能损坏或者原始作者打包时就有问题。训练时报错如Could not load image或Corrupt JPEG data多数是图片文件头损坏。先跑一遍校验find images -name *.jpg -o -name *.png | while read f; do file $f | grep -q image data || echo broken: $f donefile命令输出中如果包含image data字样说明文件是有效图片否则就是损坏。找出损坏图片后建议直接删除并同步删除对应的txt标签文件而不是去费力修复。因为一张损坏图可能会在训练中途触发MemoryError或数据加载进程崩溃影响所有后续epoch。4.2 类别标签不连续或背景类干扰我在整理火焰烟雾数据集时经常遇到这样的标签文件2 0.5 0.5 0.3 0.3 0 0.1 0.1 0.2 0.2类别索引从2开始而data.yaml里只定义了0和1。这会让YOLO在计算分类损失时越界表现为cls_loss突然NaN。解决办法是重新映射类别索引而不是修改data.yaml去适配这个混乱的标签。另一个问题是背景类干扰。有些数据集作者会把“无火焰无烟雾”的图片也标成第三类background这其实是错误做法。YOLO通过负样本学习背景不需要在类别里显式定义背景类。如果发现标签文件里有大量class_id2那这些标注需要全部删除或者重新标注。4.3 锚框与分辨率设置对烟雾这种半透明目标的影响烟雾是半透明的边缘没有锐利轮廓YOLO在默认锚框下对长条形烟雾的召回率比较低。你可以用下面代码统计标签里所有标注框的宽高比看看分布是否和默认锚框对齐。import os import numpy as np ratios [] for f in os.listdir(labels/train): with open(flabels/train/{f}) as fp: for line in fp: parts line.strip().split() if len(parts) 5: w float(parts[3]) h float(parts[4]) ratios.append(w / h) ratios np.array(ratios) print(mean ratio:, ratios.mean(), std:, ratios.std())如果平均宽高比超过3说明数据集中存在大量横向长条烟雾。此时把imgsz提高到1280通常比改锚框更有效。因为分辨率提高后长条目标的像素信息更充足YOLO能学到更细的边缘特征。如果显存不够则考虑缩小batch而不是降低imgsz。还有一种情况是模型把远处的白色烟雾误检为白色的墙体或云层这种漏检和误检要通过下一章的混淆矩阵定位。5. 验证模型的一个小技巧用热力图和混淆矩阵检查过拟合5.1 用val模式快速看效果训练完成后不要只看最后的mAP数字。先跑一次验证把预测图输出出来人工扫一遍yolo detect val \ modelruns/detect/train/weights/best.pt \ data/home/yourname/fire_smoke/data.yaml \ conf0.25 \ save_jsonTrue \ save_txtTrue \ save_confTruesave_jsonTrue让YOLO输出预测结果的JSONsave_txt输出包含类别、坐标、置信度的txtsave_conf把置信度也写进去。这时打开输出目录里的预测图重点关注两类一类是无火有烟但模型框出fire置信度大于0.5的图另一类是火焰被烟雾完全包住的图。5.2 从混淆矩阵判断火焰和烟雾类别的互相污染YOLOv8在验证结束后会在runs/detect/val下生成confusion_matrix.png。这个矩阵能直接看出问题。预测\真实firesmokebackgroundfire0.820.150.03smoke0.120.710.17background0.060.140.80如果看到smoke那行有0.17跑到background说明大量烟雾被当成背景。如果fire那一列有0.15被预测成smoke说明火焰和烟雾在颜色、纹理上产生了语义混淆。解决思路不是盲目加数据而是到第5.1步保存的txt预测结果里找出具体的类别错误样本看是不是标注框太小导致模型没看到全局的火焰颜色。这时可以单独用烟雾样本做一次重训练只训练smoke一个类别让模型先学会区分烟雾与干净背景再冻结backbone微调fire类别。这个方法比直接调锚框快得多。最后一步在测试集上统计每个类别在不同置信度阈值下的F1曲线找到让火焰和烟雾同时达到F1最大的conf阈值然后写进部署代码检测效果会比默认的0.25好很多。本文还有配套的精品资源点击获取

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

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

免费获取报价