简介这份资源是面向野火探测与火灾识别方向的航空图像目标检测数据集适合从事深度学习、计算机视觉研究的学生与工程师用于训练和验证火灾场景下的目标检测模型。压缩包内共2000个文件全部为XML格式的标注文件整体约165.02MB采用Roboflow完成标注包含4500个图像注释以手动方式精确标出图像中目标的位置及对应标签可直接对接主流检测框架的数据读取流程。目前已有361人学习下载说明其在火灾识别任务中具备一定参考价值。读者可借助这批高质量标注快速搭建训练与评估流程省去从零标注的时间成本同时便于对比不同检测算法在野火场景下的表现为模型调优与实验复现提供可靠的数据基础。1. 野火航空图像数据集4500 份 XML 标注到底怎么喂给检测模型去年帮一个做林火预警的团队看模型mAP 卡在 0.4 上不去查了一圈发现不是网络结构的问题是标注格式没对齐——他们拿到的航空图像标注是 XML训练脚本却按 YOLO 的 txt 读坐标全错位了。这类翻车在野火检测项目里特别常见因为航空图像数据集本身就比常规 COCO 类数据难伺候目标小、背景杂、烟雾和云层容易混淆标注格式再一错模型直接学废。这份专门为野火探测设计的综合性航空图像数据集核心价值就在于它把 4500 个图像注释文件整理成了统一的 XML 格式用 Roboflow 做标注指定了图像中对象及其对应标签的确切位置。它适合做火灾识别、烟雾检测、深度学习目标检测的从业者尤其是需要航空视角正样本的团队。下面我按「先搞懂标注结构、再动手转格式、最后避坑」的顺序拆一遍。2. 拆开 XML 标注Pascal VOC 结构里藏着哪些字段2.1 一份 fire-1044 标注文件的完整字段解读先别急着写转换脚本把单个 XML 打开看清楚结构后面所有操作都建立在这上面。这份数据集的注释文件命名类似fire-1044-_png.rf.a911498c3329c5db1b99383926264140.xml文件名里带rf基本能确认是 Roboflow 导出的 Pascal VOC 格式。典型结构长这样annotation folderfire-1044/folder filenamefire-1044-_png.rf.a911498c3329c5db1b99383926264140.jpg/filename size width640/width height640/height depth3/depth /size object namefire/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin212/xmin ymin98/ymin xmax389/xmax ymax301/ymax /bndbox /object /annotation这里几个字段必须盯死size里的宽高是原图尺寸bndbox的四个值是绝对像素坐标不是归一化值。name是类别标签野火数据集里常见的就是fire、smoke两类有的版本还会细分wildfire。difficult和truncated在训练时通常忽略但做数据清洗时有用——difficult1的样本可以考虑剔除避免拉低小目标召回。提示Roboflow 导出的 XML 有时filename后缀和实际图片不一致比如标注写.jpg但图是.png转换时要以实际图片文件为准别直接信 XML 里的 filename。2.2 为什么选 Pascal VOC 而不是直接上 YOLO txt很多人第一反应是「XML 太老了直接转 YOLO txt 多省事」。但这份数据集给 XML 是有道理的XML 保留了图像尺寸、类别名、截断和难度标记信息量比纯 txt 大。做野火检测时烟雾目标边界模糊difficult标记能帮你判断哪些样本标注置信度低而 YOLO txt 只有class x_center y_center w h五个归一化值这些元信息全丢了。常见做法是先用 XML 做一轮数据质检和可视化确认标注没问题再转成训练框架要的格式。我一般会保留 XML 原始文件转换脚本单独跑这样出问题能回溯。3. 从 XML 到 YOLO txt转换脚本与坐标归一化3.1 批量转换脚本一次处理 4500 份标注训练 YOLOv5/v8 需要每张图对应一个 txt格式是类别索引 中心x 中心y 宽 高全部归一化到 0~1。下面这个脚本遍历标注目录按类别映射表转换同时做边界裁剪防止坐标越界import os import xml.etree.ElementTree as ET # 类别映射按你数据集实际标签改 CLASS_MAP {fire: 0, smoke: 1} XML_DIR ./annotations OUT_DIR ./labels IMG_W, IMG_H 640, 640 # 若各图尺寸不一从 XML 的 size 读取 os.makedirs(OUT_DIR, exist_okTrue) 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() # 优先从 XML 读尺寸读不到再用默认值 size root.find(size) w int(size.find(width).text) if size is not None else IMG_W h int(size.find(height).text) if size is not None else IMG_H lines [] for obj in root.findall(object): name obj.find(name).text.strip() if name not in CLASS_MAP: continue cls_id CLASS_MAP[name] box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 裁剪到图像范围内防止标注越界 xmin, xmax max(0, xmin), min(w, xmax) ymin, ymax max(0, ymin), min(h, ymax) # 归一化为中心点 宽高 cx (xmin xmax) / 2.0 / w cy (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) out_name os.path.splitext(xml_file)[0] .txt with open(os.path.join(OUT_DIR, out_name), w) as f: f.write(\n.join(lines))逻辑说明先解析 XML 拿到图像真实宽高再对每个 object 做坐标裁剪和归一化。CLASS_MAP必须和你data.yaml里的names顺序一致否则类别全乱。:.6f保留六位小数是 YOLO 官方推荐精度太少会导致小目标框偏移。跑完检查一下labels目录文件数是否和图片数一致缺文件说明有 XML 解析失败得单独排查。3.2 转换后必做的两项校验转完不能直接开训先做校验。第一项是数量对齐图片数、XML 数、txt 数三者应该相等差一个都说明有漏转。第二项是可视化抽检随机抽 20 张把框画回图上肉眼确认框位置对不对import cv2 import os img cv2.imread(./images/fire-1044.png) h, w img.shape[:2] with open(./labels/fire-1044.txt) as f: for line in f: c, cx, cy, bw, bh map(float, line.split()) x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(check.jpg, img)如果框整体偏移或大小不对八成是宽高读错了——有的 XML 里size写的是缩放后尺寸和原图不符。这种情况要以实际图片cv2.imread拿到的 shape 为准把脚本里的w, h改成从图片读。4. 训练配置与野火小目标调参4.1 data.yaml 与类别数设置YOLO 训练靠data.yaml指定路径和类别。野火数据集通常两类配置如下path: ./wildfire_data train: images/train val: images/val nc: 2 names: [fire, smoke]nc必须等于CLASS_MAP的长度names顺序也要一致。常见错误是nc写了 1 但标注里有两类训练时第二类直接被忽略召回率上不去还找不到原因。划分训练验证集建议 8:2野火正样本本身不多验证集别切太大否则训练样本不够。4.2 针对小目标与烟雾的锚框和输入尺寸航空图像里火点往往只占几十个像素默认 640 输入下小目标特征几乎消失。我一般会把imgsz提到 1024显存不够就降到 896别硬撑 640。锚框方面YOLOv5 默认锚框偏大野火小目标建议重新聚类python utils/autoanchor.py --data data.yaml --imgsz 1024聚类完把新锚框写回配置。另外烟雾目标颜色淡、对比度低训练时开--hsv_v 0.5增强亮度扰动能让模型对薄烟更鲁棒。学习率别一上来就 0.01小数据集容易震荡用 0.001 配 cosine 衰减更稳。5. 避坑排查野火数据集转换与训练的五条血泪经验5.1 现象训练 loss 正常但 mAP 一直是 0原因类别索引错位。XML 里name是字符串转 txt 时映射表写错比如fire映射成 1、smoke映射成 0但data.yaml里names顺序反了模型学到的类别和验证时对不上。解决打印CLASS_MAP和names逐项比对确保字符串到索引的映射完全一致。5.2 现象框位置整体偏移或缩放原因XML 的size和实际图片尺寸不一致Roboflow 导出时可能记录了预处理后的尺寸。解决转换脚本里强制用cv2.imread读实际图片宽高覆盖 XML 里的size值别偷懒。5.3 现象部分图片没有对应 txt原因XML 解析时遇到空object或类别不在映射表里脚本跳过后没生成文件。解决在脚本里加计数日志记录每张图跳过了几个 object、跳过的类别名是什么跑完看日志定位。5.4 现象小目标召回率极低原因输入尺寸太小或锚框不匹配。解决imgsz提到 1024重聚类锚框另外检查标注里小框是否被min(w,h)过滤掉了——有的转换脚本会丢弃宽高小于阈值的框野火小目标正好中招。5.5 现象验证集 mAP 高但实际推理漏检严重原因训练验证集划分时同一场景的图被分到两边造成数据泄漏。解决按图像来源或拍摄批次划分别用随机划分。野火数据集里同一场火的多张图高度相似随机划分会让验证集「见过」训练集场景指标虚高。6. 进阶技巧用 XML 元信息做数据清洗与难例挖掘XML 比 txt 多出来的difficult、truncated和size字段其实是做数据清洗的金矿。我一般会先跑一遍统计脚本把difficult1和框面积占比小于 0.1% 的样本筛出来单独看。野火数据集里这类样本往往是远距离小火点或浓烟遮挡直接训练会拉低收敛速度但全删又可惜——更好的做法是先把它们放进一个hard_samples目录等基础模型训到收敛后再用这些难例做一轮微调通常能把小目标召回拉高 5~8 个点。import xml.etree.ElementTree as ET import os hard [] for f in os.listdir(./annotations): if not f.endswith(.xml): continue root ET.parse(os.path.join(./annotations, f)).getroot() size root.find(size) w float(size.find(width).text) h float(size.find(height).text) for obj in root.findall(object): diff obj.find(difficult) box obj.find(bndbox) bw float(box.find(xmax).text) - float(box.find(xmin).text) bh float(box.find(ymax).text) - float(box.find(ymin).text) area_ratio (bw * bh) / (w * h) if (diff is not None and diff.text 1) or area_ratio 0.001: hard.append(f) break print(f难例数量: {len(hard)})这段脚本输出的是需要重点关注的样本文件名列表你可以据此把它们从训练集里抽出来。参数上area_ratio 0.001这个阈值不是固定的1024 输入下可以放宽到 0.0005640 输入下建议 0.002按你的输入尺寸调。另外difficult字段不是每份 XML 都有脚本里做了 None 判断别直接.text否则报错。还有一个容易被忽略的点XML 里的folder字段有时记录了原始子目录如果数据集是从多个批次合并的可以用它做分层划分保证训练验证集场景不重叠。我吃过一次亏随机划分后验证集 mAP 0.78上线实测漏检一半回头查就是同一场火的图被分到了两边。从那以后我每次划分数据集都强制按folder或文件名前缀分层再也不敢图省事用随机划分。希望这些能帮到你少走点我踩过的弯路。本文还有配套的精品资源点击获取
