【YOLO26 系列】基于YOLO26火灾检测系统【python源码+Pyqt5界面/WEB+数据集+训练代码】


导读

本文基于最新YOLO26目标检测模型,开发了一套适用于监控场景的火灾检测系统。项目针对火灾场景中的烟雾、火焰两类目标进行检测,配套包含数千张标注完成的火灾场景图像数据集,支持从数据集标注转换、模型训练到部署的全流程落地。系统同时提供PyQt5桌面GUI界面与Flask Web网页端两种交互方式,集成单张图片检测、文件夹批量检测、视频检测、实时摄像头检测四大核心功能,支持检测结果保存与报告导出,兼具高精度与实时推理能力,可广泛应用于森林防火、工业监控、楼宇安防等多种火灾预警场景。

演示视频


基于yolo26的火灾检测系统

一、软件功能演示

本项目提供桌面GUI界面和Web网页端两种交互方式,核心功能保持一致,包含以下五大核心子功能:

1.1 单张图片检测

操作流程

  1. 点击【📁 模型选择】按钮,加载训练完成的YOLO26火灾检测权重文件
  2. 点击【🖼️ 图片检测】按钮,选择待检测的单张火灾场景图片
  3. 系统自动完成推理,在界面展示检测结果并统计检测信息

检测结果示例:

序号 图片名称 检测类型 检测类别 置信度 坐标位置
1 test_001.jpg 图片检测 fire 0.92 (35, 120)-(280, 360)
2 test_001.jpg 图片检测 smoke 0.87 (250, 40)-(420, 180)

1.2 文件夹批量检测

操作流程

  1. 加载模型权重后,点击【📂 文件夹检测】按钮
  2. 选择包含多张待检测图片的目标文件夹
  3. 系统自动批量检测文件夹内所有支持格式的图片,并将所有检测结果保存至输出目录
  4. 自动生成检测结果统计报告

批量检测结果统计示例:

总检测图片数:20张
检测到火灾目标:16张
总检测目标数:28个

  • fire:12个
  • smoke:16个

1.3 视频文件检测

操作流程

  1. 加载模型权重后,点击【🎬 视频检测】按钮
  2. 选择本地视频文件(支持mp4、avi等常见格式)
  3. 系统逐帧进行检测,实时在界面展示带检测框的推理画面
  4. 检测完成后可选择保存带标注的检测视频

视频实时检测结果示例:

序号 画面位置 检测类型 检测类别 置信度 坐标位置
1 第128帧 视频检测 fire 0.89 (182, 142)-(320, 286)
2 第128帧 视频检测 smoke 0.78 (86, 52)-(220, 168)
3 第128帧 视频检测 fire 0.65 (340, 210)-(412, 298)

1.4 实时摄像头检测

操作流程

  1. 确保本地电脑连接可用摄像头,加载模型权重
  2. 点击【📹 实时摄像头】按钮,启动摄像头实时采集
  3. 系统对摄像头每一帧画面进行实时推理并展示检测结果
  4. 点击【⏹️ 停止检测】可终止摄像头采集

1.5 检测结果保存

操作流程

  1. 完成任意类型的检测后,点击【💾 保存结果】按钮
  2. 系统自动将带检测框的结果图片/视频保存至配置的输出目录
  3. 同时导出txt/csv格式的检测结果报告,包含所有目标的类别、置信度、坐标信息

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、环境搭建

本项目基于PyTorch框架开发,提供两种环境搭建方式,请根据自身情况选择:

2.1 PyTorch手动安装(推荐)

本项目未包含torch和torchvision,需手动安装适配本地电脑CUDA版本的PyTorch,官方下载地址如下:

若对环境配置不熟悉,可参考B站详细安装教程:torch环境配置从零开始安装

2.2 pip安装其他依赖

配置好PyTorch环境后,进入项目根目录,执行以下命令安装剩余依赖:

pip install -r requirements.txt

requirements.txt包含的依赖列表:

aiohttp==3.14.1
albumentations==2.0.8
ax==0.52.0
clip==0.2.0
comet_ml==3.58.3
ConfigSpace==1.2.2
coremltools==9.0
dvclive==3.49.1
dx_com==2.3.0
faster_coco_eval==1.7.2
Flask==3.1.3
hub_sdk==0.0.24
ipython==8.12.3
lap==0.5.13
matplotlib==3.11.0
mct_quantizers==1.7.0
MNN==3.6.0
mobileclip==0.0.1
model_compression_toolkit==2.6.0
moviepy==2.2.1
pyqt5  # 若使用GUI界面需额外安装

2.3 Conda环境安装(可选)

若使用Anaconda管理环境,可通过以下命令创建新环境并安装依赖:

# 创建新环境
conda create -n yolo26-fire python=3.10 -y
conda activate yolo26-fire

# 安装PyTorch(以CUDA11.8为例)
conda install pytorch torchvision pytorch-cuda=11.8 -c pytorch -c nvidia

# 安装其他依赖
pip install -r requirements.txt

三、模型训练、评估、预测

3.1 数据集上传说明

3.1.1 数据集格式要求

本项目使用标准YOLO格式数据集,目录结构如下:

VOCData/
└── VOdevkit/
    ├── dataset.yaml  # 数据集配置文件
    ├── train/
    │   ├── images/   # 训练集图片
    │   └── labels/   # 训练集标签(txt格式)
    ├── val/
    │   ├── images/   # 验证集图片
    │   └── labels/   # 验证集标签
    └── test/
        ├── images/   # 测试集图片
        └── labels/   # 测试集标签
3.1.2 YOLO格式标签说明

YOLO格式中每个图片对应一个同名txt标签文件,每一行代表一个目标,格式为:

<class_id> <x_center> <y_center> <width> <height>

所有坐标均为归一化后的数值(范围0~1),示例:

1 0.432 0.356 0.215 0.420
0 0.218 0.126 0.154 0.218
  • 本项目中:0代表smoke1代表fire
3.1.3 从VOC格式转换(XML转YOLO格式)

若数据集为VOC标注格式(XML标注文件),可使用本项目提供的xml2txt.py脚本完成格式转换,完整代码如下:

import os
import xml.etree.ElementTree as ET

# 定义本项目类别顺序
categories = ['smoke', 'fire']
category_to_index = {category: index for index, category in enumerate(categories)}

# 替换为实际的XML文件夹路径和输出TXT文件夹路径
input_folder = r'./VOCData/Annotations'
output_folder = r'./VOCData/labels'

# 确保输出文件夹存在
os.makedirs(output_folder, exist_ok=True)

# 遍历输入文件夹中的所有XML文件
for filename in os.listdir(input_folder):
    if filename.endswith('.xml'):
        xml_path = os.path.join(input_folder, filename)
        # 解析XML文件
        tree = ET.parse(xml_path)
        root = tree.getroot()
        # 提取图像的尺寸
        size = root.find('size')
        width = int(size.find('width').text)
        height = int(size.find('height').text)
        # 存储目标信息
        objects = []

        # 遍历XML中的object标签
        for obj in root.findall('object'):
            name = obj.find('name').text
            if name in category_to_index:
                category_index = category_to_index[name]
            else:
                continue  # 如果name不在指定类别中,跳过该object

            bndbox = obj.find('bndbox')
            xmin = int(bndbox.find('xmin').text)
            ymin = int(bndbox.find('ymin').text)
            xmax = int(bndbox.find('xmax').text)
            ymax = int(bndbox.find('ymax').text)

            # 转换为中心点坐标和宽高,并归一化
            x_center = (xmin + xmax) / 2.0
            y_center = (ymin + ymax) / 2.0
            w = xmax - xmin
            h = ymax - ymin

            x = x_center / width
            y = y_center / height
            w_norm = w / width
            h_norm = h / height

            objects.append(f"{category_index} {x} {y} {w_norm} {h_norm}")

        # 输出结果到对应的TXT文件
        txt_filename = os.path.splitext(filename)[0] + '.txt'
        txt_path = os.path.join(output_folder, txt_filename)
        with open(txt_path, 'w') as f:
            for obj in objects:
                f.write(obj + '\n')

print("VOC格式转换YOLO格式完成!")

运行前请修改input_folderoutput_folder为本地实际路径。

3.1.4 数据集划分脚本

格式转换完成后,使用SplitDataset.py将数据集划分为训练集、验证集、测试集,完整代码如下:

import os
import shutil
import random

# random.seed(0)  # 固定随机种子,可开启以保证划分结果可复现
def split_data(file_path, label_path, new_file_path, train_rate, val_rate, test_rate):
    images = os.listdir(file_path)
    labels = os.listdir(label_path)
    images_no_ext = {os.path.splitext(image)[0]: image for image in images}
    labels_no_ext = {os.path.splitext(label)[0]: label for label in labels}
    matched_data = [(img, images_no_ext[img], labels_no_ext[img]) for img in images_no_ext if img in labels_no_ext]

    unmatched_images = [img for img in images_no_ext if img not in labels_no_ext]
    unmatched_labels = [label for label in labels_no_ext if label not in images_no_ext]
    if unmatched_images:
        print("未匹配的图片文件:")
        for img in unmatched_images:
            print(images_no_ext[img])
    if unmatched_labels:
        print("未匹配的标签文件:")
        for label in unmatched_labels:
            print(labels_no_ext[label])

    random.shuffle(matched_data)
    total = len(matched_data)
    train_data = matched_data[:int(train_rate * total)]
    val_data = matched_data[int(train_rate * total):int((train_rate + val_rate) * total)]
    test_data = matched_data[int((train_rate + val_rate) * total):]

    # 处理训练集
    for img_name, img_file, label_file in train_data:
        old_img_path = os.path.join(file_path, img_file)
        old_label_path = os.path.join(label_path, label_file)
        new_img_dir = os.path.join(new_file_path, 'train', 'images')
        new_label_dir = os.path.join(new_file_path, 'train', 'labels')
        os.makedirs(new_img_dir, exist_ok=True)
        os.makedirs(new_label_dir, exist_ok=True)
        shutil.copy(old_img_path, os.path.join(new_img_dir, img_file))
        shutil.copy(old_label_path, os.path.join(new_label_dir, label_file))
    
    # 处理验证集
    for img_name, img_file, label_file in val_data:
        old_img_path = os.path.join(file_path, img_file)
        old_label_path = os.path.join(label_path, label_file)
        new_img_dir = os.path.join(new_file_path, 'val', 'images')
        new_label_dir = os.path.join(new_file_path, 'val', 'labels')
        os.makedirs(new_img_dir, exist_ok=True)
        os.makedirs(new_label_dir, exist_ok=True)
        shutil.copy(old_img_path, os.path.join(new_img_dir, img_file))
        shutil.copy(old_label_path, os.path.join(new_label_dir, label_file))
    
    # 处理测试集
    for img_name, img_file, label_file in test_data:
        old_img_path = os.path.join(file_path, img_file)
        old_label_path = os.path.join(label_path, label_file)
        new_img_dir = os.path.join(new_file_path, 'test', 'images')
        new_label_dir = os.path.join(new_file_path, 'test', 'labels')
        os.makedirs(new_img_dir, exist_ok=True)
        os.makedirs(new_label_dir, exist_ok=True)
        shutil.copy(old_img_path, os.path.join(new_img_dir, img_file))
        shutil.copy(old_label_path, os.path.join(new_label_dir, label_file))
    
    print("数据集划分完成!")

if __name__ == '__main__':
    # 修改为你本地的实际路径
    file_path = r"./VOCData/images"       # 所有图片所在文件夹
    label_path = r"./VOCData/labels"      # 所有标签所在文件夹
    new_file_path = r"./VOCData/VOdevkit" # 划分后数据存放位置
    # 划分比例:80%训练集,10%验证集,10%测试集
    split_data(file_path, label_path, new_file_path, train_rate=0.8, val_rate=0.1, test_rate=0.1)

运行脚本后,即可生成符合YOLO要求的数据集目录结构。

3.1.5 配置数据集yaml文件

最后,在VOCData/VOdevkit目录下创建dataset.yaml,内容如下(适配本项目火灾检测场景):

# 数据集路径,相对于项目根目录
path: ../VOCData/VOdevkit
train: train/images  # 训练集图片路径
val: val/images      # 验证集图片路径
test: test/images    # 测试集图片路径(可选)

# 类别信息
nc: 2
names: ['smoke', 'fire']

3.2 模型训练

数据集准备完成后,即可开始训练,核心训练代码train.py如下:

import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLO

if __name__ == '__main__':
    # 加载YOLO26n预训练模型
    model = YOLO('yolo26n.pt')
    # 开始训练
    results = model.train(
        data=r'./VOCData/VOdevkit/dataset.yaml', # 数据集配置文件路径
        epochs=100,       # 训练轮次总数
        batch=16,         # 批量大小,根据显卡显存调整
        imgsz=640,        # 训练输入图像尺寸
        workers=8,        # 数据加载线程数
        device=0,         # 训练设备,GPU填0/1/...,CPU填'cpu'
        optimizer='SGD',  # 优化器,可选auto, SGD, Adam, AdamW
        amp=False,        # 自动混合精度训练
        cache=False       # 缓存数据集到内存,大内存服务器可开启
    )

训练参数说明:

参数 说明 推荐值
epochs 训练总轮次 火灾检测推荐100~150
batch 批量大小,需根据显卡显存调整 8G显存推荐8,16G显存推荐16
imgsz 输入图像尺寸 通用场景640,小目标检测可调整为800
workers 数据加载线程数 一般设置为CPU核心数的一半
device 训练设备,支持多GPU并行 有NVIDIA显卡使用GPU(填0),无显卡填cpu
amp 自动混合精度训练,可减少显存占用、加快训练速度 大部分场景可开启

启动训练命令:

python train.py

训练启动成功后,日志会输出模型信息、数据加载进度,随后开始逐轮训练。

3.3 训练结果评估

训练完成后,所有训练结果将保存至runs/detect/train/目录下,核心内容如下:

文件名/文件夹 说明
weights/ 保存训练得到的权重文件
├─ best.pt 验证集表现最优的权重(推荐实际部署使用)
├─ last.pt 最后一轮训练结束时的权重
└─ epoch*.pt 每N轮训练保存的阶段性权重(需在训练参数中配置)
args.yaml 本次训练的完整参数配置记录
results.csv 每轮训练的精度、损失等指标数值记录
results.png 训练指标变化曲线可视化图(如损失曲线、精度曲线)
confusion_matrix.png 混淆矩阵,展示模型对各类别的分类情况
confusion_matrix_normalized.png 归一化混淆矩阵,消除类别样本数量差异的影响
BoxF1_curve.png F1分数曲线,反映模型在不同置信度阈值下的综合性能
BoxPR_curve.png PR曲线,展示精确率与召回率的权衡关系
BoxP_curve.png 精确率曲线,反映不同置信度阈值下模型的精确率变化
BoxR_curve.png 召回率曲线,反映不同置信度阈值下模型的召回率变化
labels.jpg 数据集标签分布可视化,展示各类别样本数量占比
train_batch*.jpg 训练批次样本可视化,展示数据增强后的效果
val_batch*_labels.jpg 验证集标签可视化,展示验证集原始标注情况
val_batch*_pred.jpg 验证集预测结果可视化,对比模型预测与原始标注的差异

可使用项目提供的val.py脚本在验证集上评估模型性能:

from ultralytics import YOLO
import numpy as np
from datetime import datetime

# 加载训练完成的最优权重
model = YOLO(r"runs/detect/train/weights/best.pt")

# 在验证集上进行评估
metrics = model.val(data=r"VOCData/VOdevkit/dataset.yaml")

# 计算均值精确率、均值召回率
mean_p = np.mean(metrics.box.p)
mean_r = np.mean(metrics.box.r)

# 整理评估结果
content = []
content.append("="*60)
content.append(f"验证时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
content.append("="*60)
content.append(f"整体 mAP50:        {metrics.box.map50:.4f}")
content.append(f"整体 mAP50-95:     {metrics.box.map:.4f}")
content.append(f"平均 Precision:    {mean_p:.4f}")
content.append(f"平均 Recall:       {mean_r:.4f}")
content.append("-"*60)
content.append(f"{'类别':<12}{'Precision':<12}{'Recall':<12}{'AP50':<12}")
content.append("-"*60)

# 输出每个类别的指标
for i, class_name in enumerate(['smoke', 'fire']):
    ap50 = metrics.box.ap50[i]
    precision = metrics.box.p[i]
    recall = metrics.box.r[i]
    content.append(f"{class_name:<12}{precision:<12.4f}{recall:<12.4f}{ap50:<12.4f}")

# 保存结果到文件
os.makedirs("results", exist_ok=True)
with open("results/detection_report.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(content))

print("\n".join(content))

执行评估命令:

python val.py

3.4 模型预测

本项目支持单张图片、文件夹批量、视频、实时摄像头多种预测方式,单张图片预测示例代码如下:

from ultralytics import YOLO
import os

# 获取项目根目录
root = os.getcwd()
# 加载训练好的最优模型
model = YOLO(rf'{root}/runs/detect/train/weights/best.pt')
# 待预测图片路径,修改为本地实际路径
source = r'img_video/test_imgs/test_fire_01.jpg'
# 运行推理
results = model.predict(
    source,
    save=True,                # 自动保存结果到 runs/detect 目录
    conf=0.45,                # 置信度阈值,过滤低置信度预测结果
    iou=0.25                  # NMS IOU阈值,控制重复框的合并
)

# 弹窗展示检测结果
results[0].show()
# 自定义保存路径
os.makedirs("results", exist_ok=True)
results[0].save(filename=r"results/test_fire_01_result.jpg")

启动预测命令:

python predict.py

四、项目目录结构

基于YOLO26火灾检测系统/
│
├── 📄 README.md                    # 项目说明文档
├── 📄 requirements.txt             # Python依赖列表
├── 📄 yolo26n.pt                   # YOLO26n预训练权重
│
├── 🐍 train.py                     # 模型训练入口脚本
├── 🐍 predict.py                   # 模型预测/推理入口脚本
├── 🐍 val.py                       # 模型验证/评估脚本
│
├── 📂 UI/                          # 界面相关代码
│   ├── 🐍 web.py                   # Flask/Web后端主程序
│   ├── 🐍 GUI.py                   # PyQt5 GUI界面逻辑
│   ├── 📄 config.yaml              # UI全局配置文件
│   ├── 📄 user.txt                 # 用户信息存储
│   ├── 📂 templates/
│   │   ├── 📄 index.html           # Web主页面
│   │   └── 📄 login.html           # Web登录页面
│   └── 📂 models/
│       └── 📦 best.pt              # UI使用的最优模型权重
│
├── 📂 img_video/                   # 测试素材目录
│   ├── 📂 test_imgs/               # 测试图片
│   │   ├── test_001.jpg
│   │   └── ...
│   └── 🎬 test_MP4.mp4             # 测试视频
│
├── 📂 results/                     # 推理结果输出目录
│
├── 📂 runs/                        # 训练运行记录
│   └── 📂 detect/train/
│       ├── 📄 args.yaml            # 训练参数配置
│       ├── 📄 results.csv          # 训练指标记录
│       ├── 📊 results.png          # 训练指标曲线图
│       ├── 📊 confusion_matrix.png # 混淆矩阵
│       ├── ...                     # 各类指标图表
│       └── 📂 weights/
│           ├── 📦 best.pt          # 最优权重
│           └── 📦 last.pt          # 最后一轮权重
│
├── 📂 VOCData/                     # 数据集处理工具
│   ├── 🐍 SplitDataset.py          # 数据集划分脚本
│   ├── 🐍 ViewCategory.py          # 类别统计脚本
│   ├── 🐍 xml2txt.py               # VOC XML转YOLO TXT格式
│   ├── 🐍 pic_to_mp4.py            # 图片转视频脚本
│   └── 📂 VOdevkit/
│       ├── 📄 dataset.yaml         # 数据集配置文件
│       └── 📄 数据集单独下载.txt    # 数据集下载说明
│
├── 📂 ultralytics/                # Ultralytics YOLO框架源码
│   ├── 📂 cfg/                     # 模型和数据集配置
│   ├── 📂 data/                    # 数据加载和增强
│   ├── 📂 engine/                  # 训练/预测/验证引擎
│   ├── 📂 models/                  # 模型定义
│   └── ...
│
└── 📂 .idea/                       # PyCharm IDE配置(可忽略)

在这里插入图片描述


五、项目README摘要

本项目是基于YOLO26目标检测模型开发的火灾检测系统,包含完整的数据集处理、模型训练、桌面GUI部署、Web部署全流程代码。

项目核心特点

  1. 基于最新YOLO26模型,兼顾检测精度与推理速度
  2. 支持烟雾、火焰两类火灾相关目标的精准检测
  3. 同时提供PyQt5桌面端和Flask Web端两种交互方式
  4. 集成单图检测、文件夹批量检测、视频检测、实时摄像头检测四种模式
  5. 支持检测结果可视化保存与结构化报告导出
  6. 提供完整的数据集处理脚本,支持VOC格式转YOLO格式,可快速适配自定义数据集

使用流程

  1. 按照第二章说明配置Python运行环境
  2. 按照第三章说明准备并配置火灾检测数据集
  3. 运行train.py启动模型训练
  4. 训练完成后,运行python GUI.py启动桌面界面,或运行python web.py启动Web服务

文末互动区

如果您觉得本项目有帮助,欢迎点击【分享】【推荐】支持我们!

如需获取完整项目代码与数据集,可回复基于YOLO26火灾获取。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐