恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
基于YOLOv8与PySide6的火灾火焰检测识别系统实现
首页
资讯中心
/
基于YOLOv8与PySide6的火灾火焰检测识别系统实现
基于YOLOv8与PySide6的火灾火焰检测识别系统实现
发布时间:2026/9/3 18:16:03
在实际消防预警项目中火焰检测往往需要把目标检测模型和桌面客户端放到一起工作。基于 YOLOv8 和 YOLOv5PySide6 的火灾火焰检测识别系统正是解决“视频流进来、火焰框出来、告警能看到”这一类问题的常见方案。YOLO 负责定位画面中的火焰区域PySide6 负责生成可操作的桌面界面两者结合以后既可以处理图片和视频也可以接入摄像头做实时识别。下面从技术选型讲起逐步介绍数据集准备、模型训练、界面集成、运行验证和常见问题排查最终落成一套可复现的桌面检测工具。1. 火焰检测系统的技术选型YOLO 负责“看见”PySide6 负责“操作”1.1 火焰检测和普通目标检测的差异火焰检测在安防消防场景里并不等于普通的分类任务。火焰没有固定轮廓颜色会随燃烧物质和环境光照变化形状也会不断抖动这导致传统的颜色阈值分割很容易把夕阳、车灯、红色反光误判成火焰。目标检测模型的做法是从大量标注样本中学习火焰的颜色、纹理、边缘和上下文特征因此比纯图像处理更稳健。YOLO 系列属于单阶段目标检测算法。它把目标检测当成回归问题在整张图上直接预测边框位置、类别和置信度。对火焰检测场景来说单阶段模型最大的价值是实时性好能够以较低延迟处理摄像头视频流。相比两阶段检测器YOLO 在同样硬件条件下的推理速度通常更快落地到桌面客户端更容易满足实时预览需求。1.2 YOLOv5 和 YOLOv8 各自适合什么场景YOLOv5 是社区使用非常广泛的目标检测框架资料多、插件多早期有很多基于它的消防项目。YOLOv8 是后续迭代版本训练入口更统一模型结构也做了调整使用 C2f 模块和 Anchor-Free 解耦头自定义数据集时可以通过一个 YOLO API 完成训练、验证、导出和推理。从项目维护角度看两者不一定是替代关系。老项目如果已经用 YOLOv5 训练了一批火焰数据可以继续沿用新项目如果从零开始建议优先考虑 YOLOv8因为它对自定义数据集的流程更友好导出 ONNX、TensorRT 也比较方便。如果团队希望同时支持两个模型则需要在业务层抽象一个检测接口避免界面代码绑定到具体版本。下面用表格整理两者的常见差异实际选型还要结合硬件、历史代码和团队熟悉程度判断。对比项YOLOv5YOLOv8常用仓库独立 YOLOv5 仓库detect.py、train.pyultralytics 统一包YOLO API网络结构CSPDarknet 骨干Anchor-Based 预测C2f 模块Anchor-Free 解耦头自定义训练有成熟脚本需要按仓库约定整理data.yaml YOLO API流程统一推理接入torch.hub、detect.py、ONNXultralytics YOLO 类predict/export部署方式ONNX、TensorRT、TorchScriptONNX、TensorRT、OpenVINO 等更统一维护成本资料多社区成熟新项目更省心升级路径明确1.3 PySide6 在系统里的定位PySide6 是 Qt 6 的 Python 绑定用来做桌面界面。它的作用是把 YOLO 的检测能力包装成用户可以操作的窗口选择图片、打开视频、启动摄像头、调整置信度、查看检测结果。为什么不直接用命令行处理视频因为火焰检测系统最终可能交给安保人员或值班员使用这些人不会去修改训练参数也不应该直接接触模型权重。一个简单的界面至少需要包含文件选择按钮、检测结果预览区和日志区。PySide6 的优势是控件齐全能直接配合 OpenCV 显示图片也能通过 QThread 把耗时推理放到后台线程避免窗口卡死。2. 环境准备先让模型推理和桌面界面都跑起来2.1 需要的基础软件环境开发这套系统最常见的技术栈是 Python PyTorch OpenCV PySide6。Python 版本建议使用 3.9 或 3.10这两个版本对 PySide6、ultralytics 和 PyTorch 的兼容性都很好。硬件方面训练阶段推荐有 NVIDIA GPU显存 6GB 以上跑 YOLOv8s 比较合适如果只做推理CPU 也可以运行只是实时视频检测的帧率会低一些。下面是一个环境检查清单开始安装前先确认Python 版本是否在 3.8 到 3.10 之间。是否有 NVIDIA 显卡并确认显卡驱动版本。是否已有 conda 或 venv 虚拟环境管理工具。操作系统是 Windows 还是 LinuxPySide6 的显示依赖不同。是否预留了至少 10GB 磁盘空间用于安装依赖和保存训练结果。2.2 安装 ultralytics、PySide6 和 OpenCV安装分为两步先装 PyTorch再装其他库。PyTorch 的安装方式决定了 GPU 是否可用建议不要直接用默认命令而是根据显卡驱动安装对应 CUDA 版本。下面是使用 conda 创建环境的示例。conda create -n fire_detection python3.9 -y conda activate fire_detection # 安装 PyTorch这里以 CUDA 11.8 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装训练和推理相关依赖 pip install ultralytics opencv-python pyside6如果只是 CPU 环境可以去掉--index-url参数直接安装默认 PyTorch 包。安装完成后建议运行下面命令验证依赖是否可用。python -c import ultralytics, cv2, PySide6; print(ultralytics.__version__, cv2.__version__, PySide6.__version__)这里要注意PySide6 版本更新较快如果后面发现QVBoxLayout或QImage相关 API 报错多半是版本接口变化需要根据自己的 PySide6 版本调整代码。2.3 项目目录和模型文件规划检测系统不建议把所有代码写在一个文件里。训练代码、推理代码、界面代码和模型权重分开存放后续维护会方便很多。下面是一个适合个人项目的目录结构。fire_detection/ ├── main.py # PySide6 主程序入口 ├── detector.py # 检测逻辑封装 ├── ui_main.py # 主窗口界面代码 ├── datasets/ │ ├── images/ │ │ ├── train/ │ │ └── val/ │ └── labels/ │ ├── train/ │ └── val/ ├── runs/ │ └── detect/ │ └── fire_v1/ │ └── weights/ │ ├── best.pt │ └── last.pt └── models/ └── fire_data.yamldetector.py负责加载 YOLO 模型并输出标注后的图像ui_main.py负责窗口控件和信号槽连接main.py只负责启动界面。这样写的好处是后续更换模型的时候不需要改动整个窗口逻辑。3. 准备火灾火焰数据集完成 YOLOv8 训练与增量训练3.1 火焰数据集的标注格式YOLO 系列训练时使用的是 txt 标注文件每张图片对应一个同名的 txt 文件。文件每一行表示一个目标格式如下。类别编号 中心点x 中心点y 归一化宽度 归一化高度如果只检测火焰一个类别类别编号就是 0。中心点和宽高都要除以图片宽高归一化到 0 到 1 之间。例如下面这行表示一个火焰目标中心在图片横向 0.5、纵向 0.4 的位置宽度占全图 0.2高度占全图 0.3。0 0.500 0.400 0.200 0.300使用 LabelImg 或 Label Studio 标注时要特别注意输出格式选 YOLO而不是 VOC 或 COCO。VOC 的 XML 转 YOLO 需要额外脚本容易在目录名和类别 id 上出错。3.2 编写 data.yaml 并拆分数据集训练前需要准备一个 data.yaml告诉 YOLO 训练数据和验证数据在哪里以及有哪些类别。下面是一个火焰数据集的示例。path: D:/datasets/fire_smoke train: images/train val: images/val nc: 1 names: 0: firepath是数据集根目录的绝对路径train和val是相对于根目录的训练和验证图片目录。类别数量nc必须和names一一对应否则训练过程会出现索引错位。数据拆分要保证训练集和验证集不重叠。常见做法是每个场景的连续帧只放进一个集合避免同一段视频既出现在训练集又出现在验证集否则评估的 mAP 会虚高。3.3 YOLOv8 训练命令和增量训练使用 ultralytics 训练 YOLOv8 非常直接。在命令行执行或者在 Python 脚本里调用YOLO.train()都可以。下面是最小训练命令。yolo detect train dataD:/datasets/fire_smoke/fire_data.yaml modelyolov8s.pt epochs100 imgsz640 batch16 device0也可以写成 Python 脚本方便把训练参数保存到文件。from ultralytics import YOLO model YOLO(yolov8s.pt) model.train( dataD:/datasets/fire_smoke/fire_data.yaml, epochs100, imgsz640, batch16, device0, workers4, )训练过程中如果中断不需要从头开始。YOLOv8 会自动保存last.pt可以用resumeTrue继续训练。model YOLO(runs/detect/fire_v1/weights/last.pt) model.train( dataD:/datasets/fire_smoke/fire_data.yaml, epochs50, resumeTrue, )增量训练在火焰检测里很实用。第一次训练可能只有几千张图片模型对夜间火焰、远处小火苗的检测效果不好。后续补充了新的负样本和火焰样本后按住上次的best.pt或last.pt继续训练会比重新训练节省大量时间。需要注意的是增量训练的数据集类别定义、图片尺寸要保持一致否则模型结构会对不上。3.4 训练完成后的验证与导出训练结束后在runs/detect/fire_v1/下会生成weights/best.pt、weights/last.pt、confusion_matrix.png、results.png等文件。best.pt是验证集上指标最好的模型部署时优先选择它。先用下面的命令验证单张图片效果。yolo predict modelruns/detect/fire_v1/weights/best.pt sourcetest_fire.jpg conf0.25如果要把模型接入 PySide6 做实时推理不一定要用 PyTorch 原格式。对于桌面端尤其是 CPU 环境建议导出为 ONNX再交给 ONNX Runtime 或 OpenVINO 加载。yolo export modelruns/detect/fire_v1/weights/best.pt formatonnx opset12导出后可以看到生成的best.onnx。ONNX 文件体积通常比 PyTorch 权重小推理时依赖也更轻。如果界面直接使用 ultralytics 的YOLO(best.pt)加载也可以但首次加载 PyTorch 模型需要导入 torch启动时间会更长。3.5 训练结果文件怎么看results.png中包含训练损失曲线、验证损失曲线、mAP 等结果。火焰检测场景里mAP 50 是最先看的指标其次是 mAP 50-95。mAP 50 高说明模型能框出基本火焰区域mAP 50-95 高说明边界框定位更准。损失曲线如果出现训练损失下降但验证损失上升通常说明过拟合可以增加数据增强、增加数据量或缩小模型规模。火焰数据里如果模型对灯光误报很多检查方向不是单纯增加训练轮数而是补充大量“像火但不是火”的负样本。4. 用 PySide6 搭建检测界面把 YOLO 模型接入图片、视频和摄像头4.1 界面功能拆分桌面端火焰检测系统至少要包含三个功能图片检测、视频检测、摄像头实时检测。界面可以通过三个按钮拆开再配一个结果显示区和一个置信度输入框。界面代码不用追求复杂核心是把长耗时操作放到后台线程。下面是一个最简主窗口的代码结构只保留了关键部分。from PySide6.QtWidgets import QMainWindow, QLabel, QPushButton, QFileDialog, QLineEdit, QVBoxLayout, QWidget class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(火灾火焰检测识别系统) self.label QLabel(检测结果) self.conf_input QLineEdit(0.25) self.image_btn QPushButton(选择图片检测) self.video_btn QPushButton(选择视频检测) self.camera_btn QPushButton(启动摄像头检测) layout QVBoxLayout() layout.addWidget(self.conf_input) layout.addWidget(self.image_btn) layout.addWidget(self.video_btn) layout.addWidget(self.camera_btn) layout.addWidget(self.label) container QWidget() container.setLayout(layout) self.setCentralWidget(container) self.detector NoneQLineEdit用来接收置信度阈值。这里要注意不能只在初始化时读取输入框内容。用户可能在窗口打开后才改数值所以应该在点击检测按钮的槽函数中重新调用self.conf_input.text()并且判断输入是否为空、能否转成浮点数。4.2 后台推理线程在 PySide6 中不能把耗时的视频循环直接放在按钮点击回调里否则界面会卡住窗口无法拖动或关闭。正确做法是把视频读取和模型推理放到 QThread 中通过信号把检测后的图像发送给主线程。from PySide6.QtCore import QThread, Signal import cv2 class VideoWorker(QThread): frame_ready Signal(object) error Signal(str) def __init__(self, detector, video_source0, parentNone): super().__init__(parent) self.detector detector self.video_source video_source self._running False def run(self): cap cv2.VideoCapture(self.video_source) if not cap.isOpened(): self.error.emit(无法打开视频源) return self._running True while self._running: ok, frame cap.read() if not ok: break annotated self.detector.detect_frame(frame) self.frame_ready.emit(annotated) cap.release()video_source如果是摄像头索引就传 0 或 1如果是视频文件就传文件路径。这个设计可以同时支持视频文件和摄像头。线程退出时通过_running标志控制避免强制终止线程导致摄像头没有释放。4.3 检测逻辑封装detector.py是模型和界面之间的边界。为了同时兼容 YOLOv5 和 YOLOv8可以封装一个统一接口。下面示例使用 ultralytics 加载 YOLOv8用 torch.hub 加载 YOLOv5。import cv2 class YOLOv8Detector: def __init__(self, model_path, conf0.25, iou0.45): from ultralytics import YOLO self.model YOLO(model_path) self.conf conf self.iou iou def detect_frame(self, bgr_frame): results self.model.predict( sourcebgr_frame, confself.conf, iouself.iou, verboseFalse, ) return results[0].plot()import torch class YOLOv5Detector: def __init__(self, model_path, conf0.25): self.model torch.hub.load( ultralytics/yolov5, custom, pathmodel_path, force_reloadFalse, ) self.model.conf conf def detect_frame(self, bgr_frame): results self.model(bgr_frame) return results.render()[0]results[0].plot()返回的是画好检测框和标签的 BGR 图像数组可以直接在窗口中显示。两个类的detect_frame输入输出保持一致主窗口不需要关心当前用的是 YOLOv5 还是 YOLOv8。4.4 在主线程中更新界面QThread 中不能直接修改 QLabel需要把检测结果通过信号传回来。主线程收到frame_ready信号后将 numpy 数组转换为QImage再设置到 QLabel。from PySide6.QtGui import QImage, QPixmap import numpy as np class MainWindow(QMainWindow): # 已有代码省略 def on_frame_ready(self, frame): rgb cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, c rgb.shape image QImage(rgb.data, w, h, c * w, QImage.Format_RGB888).copy() self.label.setPixmap(QPixmap.fromImage(image))这里特别要注意QImage后面加.copy()。因为rgb.data指向的是 numpy 数组内部内存如果不复制QMage 在数组被覆盖或释放后可能显示花屏或崩溃。5. 运行验证输入、阈值、输出和日志都要检查5.1 用测试图片和视频验证训练好的模型不能只在训练集上验证。至少准备三类测试数据白天火焰、夜间火焰、类似火焰的干扰物。把这三类图片分别放入测试目录逐一运行检测记录漏检和误报情况。命令行可以快速验证单张图和视频yolo predict modelruns/detect/fire_v1/weights/best.pt sourcetest.jpg saveTrue yolo predict modelruns/detect/fire_v1/weights/best.pt sourcetest_video.mp4 saveTrue在 PySide6 界面里选择图片检测后需要检查三件事窗口是否卡住、结果是否显示、日志区是否输出模型加载和检测信息。视频检测要额外验证关闭窗口时线程能正常退出摄像头要及时释放。5.2 置信度和 IoU 阈值对结果的影响界面中的conf阈值是最常调整的参数。阈值调高误报减少但漏检增加阈值调低检测框变多容易把灯光和暖色物体标成火焰。IoU 阈值影响同一火焰区域的重叠框数量不同模型对 IoU 的敏感度不同。下面是一个参数速查表实际项目可以按这个思路调。参数默认值调高影响调低影响conf0.25检测框更少误报降低漏检增加检测框更多容易误报iou0.45重叠框合并更少同一目标可能出现多框重叠框合并更多小目标可能被合并掉imgsz640小目标识别更好推理变慢速度更快小目标可能漏检火焰检测场景建议先固定imgsz640然后根据测试集反复调整conf。不一定要追求所有检测框都准确关键是值班人员看到的误报次数要在可接受范围。5.3 验证清单每次修改模型或界面后建议按下面清单走一遍单张近景火焰图能否正确框出火焰。单张远景小火苗能否检测到漏检是否在可接受范围。日落、路灯、红色车灯等干扰图是否误报。视频检测时帧率是否满足实时预览需求。点击停止按钮后线程是否退出摄像头指示灯是否熄灭。关闭窗口时是否出现 Python 报错或内存持续增长。模型权重路径是否存在中文中文路径是否能正常加载。6. 常见问题排查与生产环境部署建议6.1 常见错误现象与处理方案模型训练和桌面集成过程中错误类型比较集中。下面表格整理了火焰检测系统开发时最常见的几类问题。问题现象常见原因检查方式处理建议训练时提示无法加载数据集data.yaml 路径写错或类别数量不一致检查 yaml 中的 path、train、val使用绝对路径确认 labels 和 images 目录同名模型加载后检测不到火焰置信度阈值过高模型误学到其他特征降低 conf先输出调试图片检查训练集标注和模型在验证集上的 mAPPySide6 窗口点击按钮后卡死推理放在主线程执行看 CPU 是否占满窗口是否无法拖动把视频循环放到 QThread摄像头无法打开索引错误或摄像头被其他程序占用单独测试cv2.VideoCapture(0)依次尝试 0、1、2 索引显示图像花屏或颜色异常BGR 和 RGB 混用QImage 内存未复制检查通道转换代码先用 cvtColor 转 RGB再加.copy()QLineEdit 输入不生效只在窗口初始化时读取 text检查按钮点击回调在点击检测按钮时重新读取输入框内容YOLOv5 和 YOLOv8 权重混用加载方式不匹配看报错栈是 torch.hub 还是 ultralytics按模型版本切换加载逻辑6.2 排查顺序遇到检测或界面异常不要直接改随机参数可以按下面顺序排查。先确认输入是否正确图片路径、视频路径、摄像头索引。再确认模型是否加载成功打印模型结构或测试一张已知图片。然后确认预处理是否一致图像尺寸、通道顺序、归一化方式。再确认阈值参数当前 conf 是否过高或过低。最后看界面线程是否阻塞了主事件循环。例如“界面能打开但视频不显示”的问题排查重点是摄像头是否释放、QThread 信号是否连接、detector 是否在子线程中被正确初始化。很多情况下把崩溃日志的完整堆栈打出来就已经能定位到具体位置。6.3 生产环境部署建议学习环境用 PyTorch 权重直接推理没有问题但生产环境建议做以下调整。第一模型导出为 ONNX 或 TensorRT。PyTorch 推理依赖 torch启动慢且占用内存多。ONNX 模型体积更小CPU 上可用 OpenVINO 加速NVIDIA 显卡上可用 TensorRT 加速火焰检测的实时性会更好。第二增加配置外置化。模型路径、置信度阈值、摄像头地址不应该硬编码在界面代码中可以放到 config.yaml 或 json 文件里。model: path: ./models/best.onnx conf: 0.25 iou: 0.45 camera: source: 0 width: 1280 height: 720第三增加告警和日志。火焰检测系统不只是显示检测框还应该在连续多帧出现高置信度火焰时触发提示音、弹窗或记录日志。日志至少记录时间、图片来源、置信度和检测框坐标方便事后回溯误报。第四摄像头断线重连。现场环境摄像头可能掉线程序要在读取失败后自动重连不能直接退出。重连次数和重连时间间隔可以做成可配置项。6.4 可复用的最佳实践清单这里整理一份适合火焰检测系统开发和维护的清单可以直接复制到项目文档中。数据集文件夹使用英文命名不要带空格和中文。标注时统一类别 id训练前用脚本检查 labels 中是否有没有对应图片的文件。训练集和验证集按场景划分不按单帧随机划分。首次训练用 YOLOv8s快速验证流程再根据效果决定是否换更大模型。界面加载模型放在主窗口初始化之后的单独方法中避免启动即卡住。视频检测和摄像头检测统一走 QThread停止时关闭_running标志并 release 摄像头。所有用户输入在点击按钮后再读取不缓存 QLineEdit 的 text。检测结果图像先转 RGB 再放入 QImage并且复制内存。生产环境导出 ONNX 模型模型和阈值配置放在外部文件。每次更新数据集后保留训练命令和数据集版本号方便复现。这套系统从数据准备到桌面界面覆盖了火焰检测项目的大多数关键环节。实际项目中最值得优先做的事是把数据集质量做干净然后固定好模型版本和界面交互最后再考虑接入 TensorRT 或 ONNX Runtime。如果只是复现 Demo用 YOLOv8s 加一段 50 到 100 轮训练就能看到完整效果如果要交给现场人员使用还要补上日志、异常提醒、模型更新机制和摄像头断线重连。把 YOLO 的检测能力和 PySide6 的交互能力分开维护后续替换模型或调整界面都会容易很多。