灭火器识别数据集:基于YOLO与VOC格式的单类目标检测实战
2026/9/15 0:02:13 网站建设 项目流程

简介:灭火器识别数据集面向目标检测开发与研究者,提供YOLO与VOC两种常见的标注格式,类别为extinguisher,对应3262张图片的目标框标注,并已预先划分好训练集、验证集和测试集,可直接用于YOLOv5至YOLOv10、Faster RCNN、SSD等主流算法的训练与验证,适合高校实验室、企业项目或消防场景的模型落地研究。资源包共2000个文件,压缩包大小约311MB,主体为1999个txt标签文件和一个yaml类别配置文件,txt中记录了目标框坐标与类别,yaml用于指定类别信息和训练参数,解压后无需额外整理即可接入训练流程。目前已有1424人浏览学习,尤其适合希望快速验证灭火器检测效果、又不想从原始图像开始手动标注的开发者。使用这份数据可以省去标注和数据集拆分的时间,直接聚焦模型调参与精度提升。

1. 灭火器识别数据集:单类目标检测的够用与好用

在实际工程项目里,消防设施巡检、安防监控、工厂安全合规检查经常会出现同一个需求:从画面里把灭火器找出来。它看起来简单,却比想象中麻烦。一是灭火器外观高度统一,但场景光照变化大,远距离时像素占比很小,属于典型的小目标检测问题;二是公共数据集里灭火器通常混在 COCO 的几十个类别中,针对单一类目单独优化的资源很少。这类“够用即可”的数据集反而最受项目欢迎。这份 YOLO 与 VOC 双格式的灭火器识别数据集包含 3262 张图片,标注类别只有extinguisher一个,并且已经按训练集、验证集、测试集划分好,拿到手可以直接喂给 YOLOv5 到 YOLOv10 任一版本,省去整理标注和划分数据的重复劳动。

2. 目录结构与 YOLO 标注格式解析

2.1 文件命名规律与目录划分

从文件列表可以看到大量形如2412_jpg.rf.783a14b0c3f2798912b547ec65d89ed9.txt的标签文件,这是 Roboflow 导出数据集的常见命名方式。2412_jpg是原始图片名,rf表示经过 Roboflow 处理,后面跟一串哈希值,用来保证同名文件在多轮导出时不冲突。每个 txt 文件对应一张 JPG 图片,文件内容保存的是该图片中灭火器目标的位置信息。

数据集解压后的典型目录结构如下:

extinguisher_dataset/ ├── train/ │ ├── images/ │ │ ├── 0001_jpg.rf.a1b2c3d4.jpg │ │ └── ... │ └── labels/ │ ├── 0001_jpg.rf.a1b2c3d4.txt │ └── ... ├── valid/ │ ├── images/ │ └── labels/ ├── test/ │ ├── images/ │ └── labels/ ├── data.yaml └── annotations/ └── ...voc_xml...

trainvalidtest三个目录分别存放训练集、验证集、测试集。labels目录下的 txt 文件是 YOLO 格式标注,annotations目录下是 VOC 格式的 XML 标注。data.yaml用于 YOLO 系列模型直接读取数据配置。以下是文件组成概览:

文件类型格式用途
图片文件JPG训练/验证/测试输入
标签文件TXT(YOLO 格式)YOLO 系列算法直接使用
标签文件XML(VOC 格式)Faster R-CNN / SSD 等使用
配置文件YAML指定数据路径与类别信息

这种双格式设计对工程实用的价值在于:同一个数据集既能跑通 YOLOv5 到 YOLOv10 的快速迭代,又能切换到 Faster R-CNN、SSD 做对比实验。单类目标检测任务里,很多项目并不需要复杂的多类别数据处理,一份干净、格式对齐的单一类别数据集能省去大量格式转换时间。

2.2 YOLO 标签坐标解析

YOLO 格式的 txt 文件每一行代表一个目标,内容为:

0 0.5123 0.4765 0.2345 0.3210

其中第一个字段是类别编号,由于只有extinguisher一个类别,这一行始终为0。后面四个字段分别是归一化后的中心点 x 坐标、中心点 y 坐标、目标宽度、目标高度。所有坐标值都在 0 到 1 之间,是相对图片宽高的比例,因此不依赖具体图片分辨率。

我一般会写个几行的小脚本快速检查一遍标签质量,防止出现负数坐标或越界值:

import os from pathlib import Path label_dir = Path("extinguisher_dataset/train/labels") for txt_path in label_dir.glob("*.txt"): with open(txt_path, "r") as f: for line in f: parts = line.strip().split() if len(parts) != 5: print(f"格式错误: {txt_path} -> {line}") continue _, cx, cy, w, h = map(float, parts) if cx < 0 or cy < 0 or w <= 0 or h <= 0 or cx + w / 2 > 1 or cy + h / 2 > 1: print(f"坐标越界: {txt_path} -> {line.strip()}")

这段脚本遍历训练集所有标签,先检查一行是否有 5 个字段,再检查归一化坐标是否满足基本几何约束。中心点与半宽半高之和不能超过 1,否则说明目标框超出了画面边界。如果是 Roboflow 导出的标准数据,通常不会出现这些问题,但经过二次编辑或手工标注的数据常常会踩这个坑。

3. 训练、验证、测试划分与 YAML 配置要点

3.1 划分逻辑与可复现随机源

数据集在交付前已经完成划分,这对接手项目的开发人员来说非常友好。以 3262 张图片按 8:1:1 拆分为例,训练集约 2610 张,验证集和测试集约 326 张。这个比例适合数据量中等偏小的单类检测任务:训练数据足够让模型学到灭火器的外观特征,验证集用于调参,测试集留作最终评估。

如果你想在已有基础上重新划分,或者做 K 折交叉验证,建议把随机种子固定下来,否则每次运行都会得到不同组合,影响实验对比的公平性。常见做法是写一个把图片和同名标签同步移动的脚本:

python split_dataset.py \ --image_dir data/images \ --label_dir data/labels \ --output_dir data/split \ --train_ratio 0.8 \ --valid_ratio 0.1 \ --seed 42

这个脚本内部做的事情并不复杂:先读取全部图片文件名,按比例切分后,将图片和同名 txt 标签复制到trainvalidtest下的imageslabels目录。需要注意--seed参数必须固定,这样在不同机器上跑出的划分结果才完全一致。工程上我还会把划分后的文件清单导出为train.txtvalid.txt,方便后续在其他框架里直接读取。

比起盲目从网上下载来源不明的数据集,自己保留一份可复现的划分记录是更稳妥的做法。特别是做论文实验或者给客户交付时,模型的 mAP 数值需要能回溯到具体的数据切分。

3.2 YAML 配置与路径陷阱

YOLOv5 到 YOLOv10 的data.yaml结构基本一致。这份数据集自带的data.yaml内容大致如下:

train: extinguisher_dataset/train/images val: extinguisher_dataset/valid/images test: extinguisher_dataset/test/images nc: 1 names: ["extinguisher"]

trainvaltest指向对应图片目录,nc表示类别数量为 1,names列表里第一个元素是extinguisher。有些旧版本代码里还会出现names0:开头的情况,新版本统一用列表即可。

路径是最容易出问题的地方。data.yaml里的路径建议写绝对路径,或者写相对执行命令时的工作目录路径。如果直接复制别人项目里的相对路径,常会出现File not found错误。所以拿到数据集后第一件事就是检查 yaml 里的路径和实际目录是否一致。可以用以下命令快速验证:

head -n 5 data.yaml ls -la extinguisher_dataset/train/images | head

另一个常见误区是test字段并不是必填项。训练时如果只写trainval,YOLO 也能正常跑;但写上test可以在训练结束后自动评估测试集上的最终指标。在消防设施巡检这类项目交付场景里,这个测试集指标往往是甲方验收的直接依据。

4. 用 YOLOv8 跑通灭火器检测训练

4.1 环境安装与数据校验

YOLOv8 是目前 YOLO 系列里生态最完整的版本之一,训练流程非常简洁。先安装ultralytics包和依赖:

pip install ultralytics yolo checks

yolo checks会输出当前环境的 PyTorch 版本、CUDA 是否可用、GPU 型号及显存信息。如果输出里 CUDA 为不可用状态,训练只会走 CPU,速度会慢几十倍。对 3262 张图片的单类任务,有 GPU 时几分钟就能训练完一个 epoch,CPU 则要等上半小时甚至更久。

训练前我建议先跑一次数据校验,确认目标检测框架能正确读取图片和标签:

yolo detect train data=extinguisher_dataset/data.yaml model=yolov8n.pt epochs=1 imgsz=640 batch=16

如果这行命令能正常开始训练并输出 loss,说明数据集配置没有问题。epochs 设为 1 只是为了快速走通流程,不是真正训练参数。

4.2 训练命令与超参数详解

数据校验通过后,就可以正式训练。单类目标检测任务我一般从 nano 模型开始,因为参数少、训练快,而且灭火器外观相对固定,不需要太大网络容量:

yolo detect train \ data=extinguisher_dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ patience=15 \ project=runs/detect \ name=extinguisher_v8n

各参数含义如下:

参数名建议值作用说明
epochs100训练轮数,单类数据通常 100 轮以内就能收敛
imgsz640训练图片缩放尺寸,越大越利于小目标,但显存占用更高
batch16批大小,根据显卡显存调整,显存不足时降到 8 或 4
patience15连续多少轮验证集指标不提升就早停,防止过拟合
projectruns结果输出目录
name自定义本次训练结果子目录名,方便多版本对比

这里重点说imgsz。灭火器在监控画面中往往是小目标,如果原始图片是 1920x1080,imgsz=640会把目标缩小到原来的三分之一。最简单有效的办法是适当调大imgsz到 960 或 1280,但显存占用会成倍上涨。另一种思路是保持imgsz=640,依赖 YOLOv8 的 Anchor-Free 结构对中小目标的检测能力。实际项目中我一般先用 640 训练一版,再用 960 微调一版,对比测试集上的 mAP 再决定。

4.3 训练结果解析与错误排查

训练结束后,终端会输出类似下面的验证指标:

Class Images Instances Box(P) R mAP50 mAP50-95 all 326 ? 0.935 0.912 0.948 0.821

Box(P)是精确率,R是召回率,mAP50是 IoU 阈值为 0.5 时的平均精度均值。对于单类灭火器检测,mAP50在 0.9 左右基本满足工程使用。如果发现mAP50偏低,可以从训练日志里看 loss 曲线:box_losscls_loss是否持续下降。如果 loss 不降,优先检查标签是否为空或坐标是否正确。

常见排错经验我整理成了一张表:

现象可能原因处理方式
No labels founddata.yaml中标签路径错误检查 yaml 路径,确认 images 与 labels 对应
CUDA out of memorybatch 或 imgsz 过大减小 batch 或 imgsz,或启用梯度累积
mAP50 一直为 0标签类别编号与 yaml 不一致用脚本统计 txt 中第一个字段,并与 names 对应
训练正常但识别不到目标背景复杂或目标太小增大 imgsz,或尝试 TTA 推理

这类排错的核心思想是:目标检测训练链路中,数据集配置错误占了 80% 以上的问题。先验证标签与图片对应,再检查类别编号和输出路径。

5. 从 YOLO 到 VOC:格式转换与单类小目标调优

5.1 YOLO 转 VOC XML 脚本

虽然这份数据集已经提供了 VOC 格式的 XML,但很多工作流需要自己根据需求重新生成。比如要加入第八个类别,或者调整标注框的边界,写一个转换脚本比手动改 XML 高效得多。以下脚本可以把 YOLO txt 转换成 Pascal VOC 格式的 XML:

import os import cv2 from pathlib import Path from xml.etree import ElementTree as ET def yolo_to_voc(img_path, txt_path, xml_path, class_names): img = cv2.imread(str(img_path)) h, w, _ = img.shape annotation = ET.Element("annotation") folder = ET.SubElement(annotation, "folder") folder.text = "VOC2007" filename = ET.SubElement(annotation, "filename") filename.text = img_path.name size = ET.SubElement(annotation, "size") width = ET.SubElement(size, "width") width.text = str(w) height = ET.SubElement(size, "height") height.text = str(h) depth = ET.SubElement(size, "depth") depth.text = "3" with open(txt_path, "r") as f: for line in f: cls_id, cx, cy, bw, bh = map(float, line.strip().split()) xmin = int((cx - bw / 2) * w) ymin = int((cy - bh / 2) * h) xmax = int((cx + bw / 2) * w) ymax = int((cy + bh / 2) * h) obj = ET.SubElement(annotation, "object") name = ET.SubElement(obj, "name") name.text = class_names[int(cls_id)] bndbox = ET.SubElement(obj, "bndbox") for tag, val in zip(["xmin", "ymin", "xmax", "ymax"], [xmin, ymin, xmax, ymax]): node = ET.SubElement(bndbox, tag) node.text = str(val) tree = ET.ElementTree(annotation) tree.write(xml_path, encoding="utf-8", xml_declaration=True) img_dir = Path("extinguisher_dataset/train/images") txt_dir = Path("extinguisher_dataset/train/labels") xml_dir = Path("extinguisher_dataset/train/xmls") xml_dir.mkdir(parents=True, exist_ok=True) class_names = ["extinguisher"] for txt_path in txt_dir.glob("*.txt"): img_path = img_dir / (txt_path.name.replace(".txt", ".jpg")) if not img_path.exists(): continue xml_path = xml_dir / (txt_path.stem + ".xml") yolo_to_voc(img_path, txt_path, xml_path, class_names)

转换的关键是先从归一化坐标还原出像素坐标,再把xminyminxmaxymax写入 XML。注意不要漏掉图片尺寸信息,Faster R-CNN 和 SSD 在训练时需要读取size节点做坐标变换。如果图片是 PNG 格式,上面的脚本也能工作,cv2.imread能自动加载。

5.2 单类小目标的推理增强技巧

灭火器在真实场景里经常位于画面远端,标注框宽度可能只有 20 到 30 像素。YOLOv8 虽然对中小目标有优化,但面对极端小目标依然容易漏检。一个通用做法是切片推理,也就是 SAHI(Slicing Aided Hyper Inference)。把输入图片切成 256x256 的切片,逐片预测后再将检测框映射回原始坐标,能显著提升小目标召回率。

from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction detection_model = AutoDetectionModel.from_pretrained( model_type="yolov8", model_path="runs/detect/extinguisher_v8n/weights/best.pt", confidence_threshold=0.3, image_size=640, device="cpu", ) result = get_sliced_prediction( image="test_camera_001.jpg", detection_model=detection_model, slice_height=256, slice_width=256, overlap_height_ratio=0.2, overlap_width_ratio=0.2, )

切片尺寸设置在 256 到 320 之间比较适合灭火器这种小尺度目标,重叠率建议 0.2,避免目标被切片边界切断。如果叠加yolo predict --augment的 TTA 模式,推理速度会变慢,但置信度更稳定。把这些策略组合起来,做一轮针对监控视频帧的验证,基本能覆盖绝大多数场景。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询