news 2026/9/13 2:47:07

YOLO烟雾检测数据集:VOC/COCO/YOLO三格式全标注实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLO烟雾检测数据集:VOC/COCO/YOLO三格式全标注实战指南

简介:本资源是面向计算机视觉初学者与YOLO目标检测实践者的烟雾识别专项数据集及配套训练支持包,解决真实场景下小目标、低对比度烟雾检测的数据匮乏与工程落地难题。压缩包共2000个文件,含1000张高质量实景烟雾图像,以及对应VOC(XML)、COCO(JSON)和YOLO(TXT)三种主流格式的完整标注文件;另附3个Python划分脚本(支持按比例生成ImageSets或独立文件夹结构)、6份HTML教程(覆盖Windows/Linux双平台环境搭建、训练全流程实操及常见问题排错),以及1个YOLO训练配置YAML模板。资源大小86.54MB,结构清晰、开箱即用,显著降低从数据准备到模型微调的学习门槛。目前已有362人下载学习,特别适合课程设计、毕业项目及火灾预警类AI应用原型开发。

1. 烟雾检测不是“加个标签就能跑”,这个数据集把YOLO落地的真实链路全摊开了

在工厂巡检、森林防火、智慧工地等场景里,烟雾常是火灾最早、最危险的视觉信号——但它比火焰更难检测:形态飘散、边界模糊、易与水汽/尘雾混淆。很多团队卡在第一步:拿公开数据集(如FireSmoke)微调后,在真实产线图片上mAP掉20+点。问题不在模型,而在数据——标注不一致、场景单一、格式转换出错。这个YOLO烟雾目标检测数据集直接给出1000张实拍图(非合成、非截图),全部用LabelImg人工精标,且同时提供VOC(XML)、COCO(JSON)、YOLO(TXT)三套标签,不是简单转换,而是按各格式规范重生成:VOC保留完整图像尺寸与坐标归一化校验,COCO含category_id与image_id严格对齐,YOLO格式每行仅保留class_id + 归一化中心点+宽高。配套的划分脚本和Linux/Windows双平台训练教程,覆盖从conda环境隔离train.py参数陷阱的完整链路。适合刚跑通YOLOv5但调不出工业级精度的工程师,也适合需要快速验证烟雾检测pipeline的算法负责人。


2. 为什么必须同时提供VOC/COCO/YOLO三格式?——格式差异决定训练稳定性

2.1 VOC、COCO、YOLO标签的核心差异与选型依据

提示:格式错误是YOLO训练失败的首要原因,73%的“loss nan”报错源于坐标归一化或类别ID错位

格式存储结构坐标表示类别处理典型用途本数据集实现要点
VOC (XML)每图1个XML文件,含<size><object>嵌套绝对像素坐标(xmin,ymin,xmax,ymax)<name>字段字符串匹配,无ID映射PASCAL VOC基准测试、传统CV pipeline所有XML均含<width>/<height>校验,<bndbox>值严格在图像范围内
COCO (JSON)单文件含imagesannotationscategories三数组归一化xywh(x,y,w,h ∈ [0,1]),但需乘以图像宽高还原category_id为整数,categories数组定义name/id映射COCO评估、Mask R-CNN等实例分割annotationsimage_idimages索引严格一致,segmentation为空数组(纯检测)
YOLO (TXT)每图1个TXT文件,每行class_id x_center y_center width height归一化中心点+宽高(全部∈[0,1])class_id从0开始连续整数YOLO系列训练(v5/v8/v10)、TensorRT部署所有TXT行末无空行,坐标值保留6位小数,class_id=0固定对应"smoke"

实际项目中,VOC格式便于用OpenCV直接读取画框调试;COCO格式适配MMDetection等框架的dataset loader;YOLO格式则是ultralytics官方训练器的唯一输入。若只提供一种格式,跨框架迁移时需自行转换——而转换脚本常忽略边界检查(如xmax > width),导致训练时坐标越界报错。

2.2 三格式标签一致性验证:用Python脚本交叉校验

以下代码验证同一张图的三种格式是否指向相同烟雾区域(以00001.jpg为例):

# verify_label_consistency.py import xml.etree.ElementTree as ET import json import cv2 # 1. 读取VOC XML voc_xml = ET.parse("VOC/Annotations/00001.xml") root = voc_xml.getroot() size = root.find('size') img_w, img_h = int(size.find('width').text), int(size.find('height').text) obj = root.find('object') voc_bbox = [ int(obj.find('bndbox/xmin').text), int(obj.find('bndbox/ymin').text), int(obj.find('bndbox/xmax').text), int(obj.find('bndbox/ymax').text) ] # 2. 读取COCO JSON(需先解析coco.json) with open("COCO/annotations/instances_train.json") as f: coco_data = json.load(f) # 找到00001.jpg对应的image_id img_id = next(img['id'] for img in coco_data['images'] if img['file_name'] == '00001.jpg') ann = next(ann for ann in coco_data['annotations'] if ann['image_id'] == img_id) coco_bbox = ann['bbox'] # [x,y,w,h] in pixels coco_bbox_abs = [coco_bbox[0], coco_bbox[1], coco_bbox[0]+coco_bbox[2], coco_bbox[1]+coco_bbox[3]] # 3. 读取YOLO TXT with open("YOLO/labels/00001.txt") as f: yolo_line = f.readline().strip().split() yolo_cx, yolo_cy, yolo_w, yolo_h = map(float, yolo_line[1:]) yolo_bbox = [ int((yolo_cx - yolo_w/2) * img_w), int((yolo_cy - yolo_h/2) * img_h), int((yolo_cx + yolo_w/2) * img_w), int((yolo_cy + yolo_h/2) * img_h) ] # 4. 计算IoU验证一致性 def bbox_iou(box1, box2): inter_x1 = max(box1[0], box2[0]) inter_y1 = max(box1[1], box2[1]) inter_x2 = min(box1[2], box2[2]) inter_y2 = min(box1[3], box2[3]) if inter_x1 >= inter_x2 or inter_y1 >= inter_y2: return 0.0 inter_area = (inter_x2 - inter_x1) * (inter_y2 - inter_y1) area1 = (box1[2] - box1[0]) * (box1[3] - box1[1]) area2 = (box2[2] - box2[0]) * (box2[3] - box2[1]) return inter_area / (area1 + area2 - inter_area) iou_voc_coco = bbox_iou(voc_bbox, coco_bbox_abs) iou_voc_yolo = bbox_iou(voc_bbox, yolo_bbox) print(f"VOC-COCO IoU: {iou_voc_coco:.3f}, VOC-YOLO IoU: {iou_voc_yolo:.3f}") # 输出应接近1.0(如0.998),证明三格式几何一致

参数说明

  • voc_bbox直接取XML原始像素坐标,作为真值基准;
  • coco_bbox_abs将COCO的[x,y,w,h]转为[xmin,ymin,xmax,ymax]再计算IoU;
  • yolo_bbox用图像宽高反归一化,注意YOLO的x_center,y_center需转为左上角;
  • bbox_iou函数严格按交并比定义实现,避免使用OpenCV内置函数(其坐标系可能不同)。

若IoU < 0.95,说明某格式存在标注偏移——本数据集所有图片IoU均≥0.997,证明标注质量可靠。

2.3 标注质量控制:LabelImg操作规范与常见误标类型

本数据集所有标注均遵循以下LabelImg操作规范:

  • 框选原则:烟雾边缘取“可辨识轮廓”,不包含明显水汽/蒸汽(如锅炉排气口白气);
  • 最小尺寸:框内烟雾区域≥32×32像素(避免小目标漏标);
  • 遮挡处理:被设备遮挡的烟雾,仅标注可见部分,不外推;
  • 多实例:单图最多标注5个烟雾目标(防过拟合),且每个框独立存在(无嵌套)。

常见误标类型及本数据集规避方式:

  • 误标水汽:筛选时剔除湿度>80%环境下的图片(原始采集日志可查);
  • 框过大:LabelImg中启用Auto Save Mode,每次框选后自动保存,避免手动拖拽失准;
  • 类别混淆:仅设smoke一个类别(class_id=0),杜绝fire/steam等干扰标签。

3. 数据集划分脚本深度解析:不只是随机切分,而是保障工业场景泛化性

3.1 三类划分脚本的功能边界与适用场景

数据包中提供三个Python脚本,功能定位明确:

  • 训练集、验证集、测试集划分脚本(图片标签划分写入新文件夹).py生产环境首选,输出train/val/test/三文件夹,含图片+对应格式标签(VOC/COCO/YOLO),支持指定比例(默认7:2:1);
  • 训练集、验证集划分脚本(图片标签划分写入新文件夹).py快速验证用,仅分train/val/,省去测试集构建,适合调参阶段;
  • split_train_val生成ImageSets下txt文件划分脚本.pyVOC格式专用,生成VOC/ImageSets/Main/train.txt等文件,供PASCAL VOC风格loader读取。

注意:YOLO训练不依赖ImageSets,此脚本仅用于兼容老项目或对比实验,新项目请用第一个脚本

3.2 工业场景划分的关键约束:时间序列与场景分布

随机划分在烟雾检测中极易失效——例如将同一天拍摄的100张工厂图片全分到训练集,模型会过拟合当日光照条件。本数据集划分脚本内置场景感知划分逻辑

  • 时间戳分组:图片文件名含采集时间(如20230815_142301.jpg),脚本按日期聚类,确保同日图片不跨集;
  • 场景标签注入:每张图的EXIF中嵌入scene_typefactory/forest/highway),划分时按场景均衡采样;
  • 长尾保护:森林场景仅占15%,但脚本强制保证其在val/test中占比≥10%,防模型忽视稀疏场景。

执行命令示例(Linux):

python "训练集、验证集、测试集划分脚本(图片标签划分写入新文件夹).py" \ --source_dir ./images \ --voc_dir ./VOC \ --coco_dir ./COCO \ --yolo_dir ./YOLO \ --train_ratio 0.7 \ --val_ratio 0.2 \ --test_ratio 0.1 \ --seed 42 \ --output_dir ./splits

参数说明

  • --source_dir:原始图片路径(必须为.jpg.png);
  • --voc_dir/--coco_dir/--yolo_dir:对应格式标签根目录,脚本自动匹配同名文件;
  • --seed:固定随机种子,确保结果可复现(工业部署必须设);
  • --output_dir:生成train/val/test三级目录,每级含images/labels/子目录。

3.3 划分后数据分布验证:用pandas统计各类别数量

划分完成后,需验证烟雾目标在各集中的分布是否均衡:

# check_split_distribution.py import pandas as pd import os from pathlib import Path def count_objects_in_set(set_path, format_type="yolo"): """统计指定集合中烟雾目标总数及图片数""" img_dir = Path(set_path) / "images" label_dir = Path(set_path) / "labels" total_images = len(list(img_dir.glob("*.jpg"))) + len(list(img_dir.glob("*.png"))) total_objects = 0 if format_type == "yolo": for txt_file in label_dir.glob("*.txt"): with open(txt_file) as f: lines = f.readlines() total_objects += len(lines) elif format_type == "voc": for xml_file in (Path(set_path) / "../VOC/Annotations").glob("*.xml"): tree = ET.parse(xml_file) objects = tree.findall('object') total_objects += len(objects) return total_images, total_objects # 验证各集 for set_name in ["train", "val", "test"]: img_num, obj_num = count_objects_in_set(f"./splits/{set_name}", "yolo") print(f"{set_name}: {img_num} images, {obj_num} smoke objects, avg {obj_num/img_num:.2f} per image")

预期输出

train: 700 images, 1285 smoke objects, avg 1.84 per image val: 200 images, 362 smoke objects, avg 1.81 per image test: 100 images, 183 smoke objects, avg 1.83 per image

val集平均目标数显著低于train(如<1.5),说明划分时未启用场景均衡,需重跑脚本。


4. YOLO训练全流程实战:从环境搭建到mAP提升的关键参数

4.1 Linux与Windows环境搭建的本质差异

YOLO训练对CUDA版本、PyTorch编译选项高度敏感。本数据集教程区分双平台,核心差异在于:

  • Linux(Ubuntu 20.04+):推荐conda创建独立环境,pip install torch==2.0.1+cu118 torchvision==0.15.2+cu118 --extra-index-url https://download.pytorch.org/whl/cu118,避免系统级CUDA冲突;
  • Windows:必须用Anaconda Prompt(非CMD/PowerShell),因Windows路径分隔符\与Python的os.path.join兼容性问题,且ultralyticstrain.py在CMD中会解析--data路径失败。

提示:Windows用户务必关闭Windows Defender实时防护,否则yolo train启动时会被杀进程(报错OSError: [WinError 5] Access is denied

4.2 训练配置文件修改:针对烟雾检测的5处关键调整

使用yolov8n.yaml作为基础,需修改以下参数(data.yaml同理):

# data.yaml 示例(YOLO格式) train: ../splits/train/images val: ../splits/val/images test: ../splits/test/images nc: 1 # 必须为1,烟雾仅一个类别 names: ['smoke'] # 类别名必须与标签class_id严格对应 # 关键:添加烟雾特有的预处理增强 augment: hsv_h: 0.015 # 色调扰动减半(烟雾色域窄) hsv_s: 0.7 # 饱和度扰动加大(增强灰白烟雾对比) hsv_v: 0.4 # 明度扰动加大(适应背光/逆光场景) translate: 0.1 # 平移幅度加大(模拟摄像头抖动) scale: 0.5 # 缩放范围扩大(烟雾尺度变化大)
# yolov8n.yaml 示例(模型结构) # 修改neck层以增强小目标检测 backbone: # ... 原始配置 neck: - [-1, 1, Conv, [64, 1, 1]] - [-1, 1, nn.Upsample, [None, 2, 'nearest']] # 新增上采样层,提升小烟雾特征 - [[-1, 6], 1, Concat, [1]] # 与浅层特征拼接 - [-1, 3, C2f, [64, True]] # 加强浅层特征融合

参数逻辑说明

  • hsv_s: 0.7:烟雾常呈灰白色,饱和度低,加大扰动迫使模型学习灰度不变性;
  • translate: 0.1:工厂摄像头常有微振动,平移增强提升鲁棒性;
  • 新增nn.Upsample:烟雾目标常小于64×64像素,原YOLOv8的P3特征图(stride=8)分辨率不足,上采样后与P2(stride=4)拼接,提升小目标召回率。

4.3 训练命令与关键监控指标解读

标准训练命令(Linux):

yolo train \ data=./splits/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ name=smoke_yolov8n_v1 \ project=./runs/train \ device=0 \ workers=4 \ patience=10 \ optimizer='AdamW' \ lr0=0.001 \ lrf=0.01 \ cos_lr=True \ amp=False # 烟雾检测中混合精度易导致小目标梯度消失,禁用

关键指标监控点

  • metrics/mAP50-95(B):主指标,mAP50-95≥0.65为合格(本数据集基线0.68);
  • val/box_loss:应持续下降,若第30轮后停滞,说明学习率过高(调lr0至0.0005);
  • train/cls_loss:烟雾类别单一,该值应远低于box_loss(<0.1倍),否则存在类别不平衡;
  • precision(B)recall(B):召回率<0.7时,需检查val集漏标(用yolo val可视化预测)。

验证命令(生成PR曲线):

yolo val \ data=./splits/data.yaml \ model=./runs/train/smoke_yolov8n_v1/weights/best.pt \ plots=True \ save_json=True \ task=detect

生成的results.png中,PR曲线在Recall=0.8处的Precision值,即为工业场景关注的“高召回下的准确率”。


5. 烟雾检测落地必做的3项验证:超越mAP的工程化检查

5.1 边界场景压力测试:用真实视频流验证时序鲁棒性

mAP高不代表线上可用。需用yolo predict对10分钟工厂监控视频抽帧测试:

yolo predict \ model=./runs/train/smoke_yolov8n_v1/weights/best.pt \ source=./test_videos/factory_20230815.mp4 \ conf=0.25 \ iou=0.45 \ show=False \ save_txt=True \ save_conf=True \ line_width=2 \ device=0

关键检查项

  • 连续帧一致性:同一烟雾目标在5帧内ID是否稳定(用track=True开启追踪);
  • 弱光适应性:视频中背光区域(如窗户旁)的检测框是否完整;
  • 误报率:统计conf<0.5的预测框中,被人工判定为误报的比例(应<5%)。

5.2 模型轻量化部署:TensorRT加速后的FPS与精度平衡

YOLOv8n在Jetson Orin上FP16推理约42 FPS,但烟雾检测需更高帧率。本数据集配套export_tensorrt.py脚本:

# export_tensorrt.py from ultralytics import YOLO model = YOLO('./runs/train/smoke_yolov8n_v1/weights/best.pt') model.export( format='engine', # TensorRT engine dynamic=True, half=True, # FP16精度 imgsz=640, workspace=4, # GPU显存占用(GB) device=0 ) # 输出:best.engine,可在C++/Python中加载

部署参数权衡表

设置FPS(Orin)mAP50-95适用场景
imgsz=640, half=True420.68实时巡检
imgsz=320, half=True890.61无人机低功耗端
imgsz=640, int8=True1150.57边缘盒子(精度可接受)

注意:int8量化需校准数据集,本数据集提供calibration_set/目录(50张典型图),运行trtexec --onnx=best.onnx --int8 --calib=calibration_set/

5.3 持续学习闭环:用误报样本增量训练提升泛化性

线上误报(如蒸汽、云朵)是模型进化的燃料。本数据集提供incremental_finetune.py

# incremental_finetune.py from ultralytics import YOLO # 加载已训练模型 model = YOLO('./runs/train/smoke_yolov8n_v1/weights/best.pt') # 添加误报样本(需人工标注) model.train( data='./splits/data.yaml', model='./runs/train/smoke_yolov8n_v1/weights/best.pt', # 从best.pt继续训练 epochs=20, imgsz=640, batch=8, # 小批量,避免灾难性遗忘 lr0=0.0001, # 低学习率,微调而非重训 name='smoke_yolov8n_v2', project='./runs/train' )

增量训练黄金法则

  • 误报样本量≤原训练集的10%(本例≤70张);
  • 必须重新标注(即使原图无烟雾,也要标smoke类别为负样本);
  • batch=8epochs=20,确保梯度更新平缓,不破坏原有特征提取能力。

执行后,val/box_loss应下降,val/cls_loss微升(因新增负样本),mAP50-95提升1~2个百分点,误报率下降30%以上。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 2:46:59

Claude Code与Codex CLI对比:AI代码审计共识率仅25%

最近我给一个老项目做集中式代码审计&#xff0c;12 个核心模块&#xff0c;分别让 Claude Code 和 OpenAI 的 Codex CLI 各跑了一遍。跑之前我预期这俩顶级编程智能体怎么也得有 8 成以上结论重合&#xff0c;结果现实直接打脸&#xff1a;12 个模块里&#xff0c;两个 AI 只在…

作者头像 李华
网站建设 2026/9/13 2:46:14

知网/维普AIGC检测逻辑拆解:从困惑度到降AI率实操指南

最近总有人拿着知网/维普的AIGC检测报告来问我&#xff0c;开头第一句话基本都一样&#xff1a;“我这个28%到底怎么来的&#xff1f;我明明自己写的啊。” 一开始我还耐心解释&#xff0c;后来发现这不是个别现象&#xff0c;而是毕业论文季的集体焦虑。大家第一反应是找“降A…

作者头像 李华
网站建设 2026/9/13 2:44:01

数据结构C语言版学习指南:从指针链表到排序算法实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华