基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的火焰与烟雾检测系统详解(深度学习模型+UI界面升级版+训练数据集)-4. 代码简介

时间:2024-03-15 22:39:16

        在本节中,我们将详细介绍如何使用YOLOv8进行烟雾检测的代码实现。代码主要分为两部分:模型预测和模型训练。

4.1 模型预测

        在模型预测部分,首先导入了OpenCV库和YOLO模型。OpenCV库是一个开源的计算机视觉和机器学习软件库,包含了众多的视觉处理函数,使用它来读取和处理图像。YOLO模型则是要用到的目标检测模型。

import cv2  
from ultralytics import YOLO  

        接着,加载自行训练好的YOLO模型。这个模型是在大量的图像上预训练得到的,可以直接用于目标检测任务。

model.load_model(abs_path("weights/best-yolov8n.pt", path_type="current"))

        然后,使用OpenCV读取了一个图像文件,这个图像文件作为要进行目标检测的图像输入。

img_path = abs_path("test_media/1.jpg")
image = cv_imread(img_path)

        在读取了图像文件之后,将图像大小调整为850x500,并对图像进行预处理,就可以使用模型进行预测了。

image = cv2.resize(image, (850, 500))
pre_img = model.preprocess(image) 
pred, superimposed_img = model.predict(pre_img) 

在这里插入图片描述

4.2 模型训练

        在构建一个高效的烟雾检测系统时,我们不能忽视实际操作中模型训练的重要性。通过精心设计的训练流程,我们能够将理论转化为实践,实现对烟雾和火焰等潜在危险的快速识别。在本博客中,我将详细介绍使用Python语言和PyTorch框架进行YOLOv8模型训练的具体步骤和代码。

        我们的训练过程从导入必要的模块开始,包括os、torch、yaml以及专门的YOLO类。这些模块为我们处理文件路径、执行数值计算、解析配置文件以及实例化模型提供了基础。接下来,我们确定了训练所使用的计算设备,优先选择GPU(cuda:0),如果不可用,则退回到CPU。

import os

import torch
import yaml
from ultralytics import YOLO  # 导入YOLO模型
from QtFusion.path import abs_path
device = "cuda:0" if torch.cuda.is_available() else "cpu"

        接着,我们设定了一些基本的训练参数,如工作进程数和批次大小。然后,定义了数据集的名称和路径,并通过abs_path函数获得了配置文件的绝对路径。这是确保不同运行环境下路径的一致性和代码的可移植性。

workers = 1
batch = 8

data_name = "FireSmoke"
data_path = abs_path(f'datasets/{data_name}/{data_name}.yaml', path_type='current')  # 数据集的yaml的绝对路径
unix_style_path = data_path.replace(os.sep, '/')

# 获取目录路径
directory_path = os.path.dirname(unix_style_path)')

        在加载数据配置文件之前,我们需要读取并解析YAML格式的配置文件。这一步至关重要,因为它包含了训练过程中需要的关键信息,如类别标签、数据集路径等。我们通过修改配置文件中的path键值,确保了模型能够正确地找到训练和验证数据。

# 读取YAML文件,保持原有顺序
with open(data_path, 'r') as file:
    data = yaml.load(file, Loader=yaml.FullLoader)
# 修改path项
if 'path' in data:
    data['path'] = directory_path
    # 将修改后的数据写回YAML文件
    with open(data_path, 'w') as file:
        yaml.safe_dump(data, file, sort_keys=False)

        随后,我们加载了预训练的YOLOv8模型,并开始了训练过程。YOLO类的train方法接受了多个参数,包括数据路径、设备、工作进程数、输入图像的大小、训练周期和批次大小。这里的name参数为训练任务提供了标识,方便后续的追踪和分析。

model = YOLO(abs_path('./weights/yolov5nu.pt', path_type='current'), task='detect')  # 加载预训练的YOLOv8模型
# model = YOLO('./weights/yolov5.yaml', task='detect').load('./weights/yolov5nu.pt')  # 加载预训练的YOLOv8模型
# Training.
results = model.train(  # 开始训练模型
    data=data_path,  # 指定训练数据的配置文件路径
    device=device,  # 自动选择进行训练
    workers=workers,  # 指定使用2个工作进程加载数据
    imgsz=640,  # 指定输入图像的大小为640x640
    epochs=120,  # 指定训练100个epoch
    batch=batch,  # 指定每个批次的大小为8
    name='train_v5_' + data_name  # 指定训练任务的名称
)

model = YOLO(abs_path('./weights/yolov8n.pt'), task='detect')  # 加载预训练的YOLOv8模型
results2 = model.train(  # 开始训练模型
    data=data_path,  # 指定训练数据的配置文件路径
    device=device,  # 自动选择进行训练
    workers=workers,  # 指定使用2个工作进程加载数据
    imgsz=640,  # 指定输入图像的大小为640x640
    epochs=120,  # 指定训练100个epoch
    batch=batch,  # 指定每个批次的大小为8
    name='train_v8_' + data_name  # 指定训练任务的名称
)

        在烟雾检测领域,对训练过程的损失函数进行分析是至关重要的。它不仅反映了模型学习的状况,还指示了模型的性能可能存在的问题。

        首先,从训练和验证的损失图中可以看出,随着训练进程的推进,train/box_loss、train/cls_loss和train/obj_loss均呈现出下降趋势,这表明模型在学习过程中逐渐拟合训练数据,并且在边界框定位、类别分类和目标检测上的表现都在不断改进。相应的,验证损失val/box_loss、val/cls_loss和val/obj_loss虽然波动较大,但总体上也显示出下降趋势,这表明模型对未见数据的泛化能力在增强。

        具体来看,train/box_loss从接近0.8下降至约0.3,这是一个非常好的信号,意味着模型在边界框的定位上变得越来越精准。类似地,train/cls_loss和train/obj_loss的下降表明分类误差减少和对目标的识别准确度提高。我们希望验证损失也能呈现相似的下降趋势,尽管中途有些波动,但整体下降趋势表明模型的泛化能力在逐渐提高,没有出现过拟合的情况。

在这里插入图片描述

        在性能指标方面,metrics/precision、metrics/recall、metrics/mAP50和metrics/mAP50-95的图表显示了模型性能的稳步提升。准确率(Precision)和召回率(Recall)随着训练周期增加而增长,这意味着模型在辨识正样本方面变得更加精确,同时也能回收更多的正样本。mAP(mean Average Precision)是目标检测中最重要的评估指标之一,metrics/mAP50和metrics/mAP50-95的提高表明模型对于不同IoU阈值的检测性能都在提升。mAP50指的是在IoU为0.5时的平均精度,而mAP50-95则表示在IoU从0.5到0.95不同阈值下的平均精度,它更全面地反映了模型在各种重叠度下的表现。观察到这些指标的稳步提升,说明模型在整个训练过程中的表现是在不断优化的。

        在机器学习领域,F1分数是一个非常关键的性能指标,它综合考虑了模型的准确率和召回率,为我们提供了关于模型分类性能的全面视图。这个指标尤其适用于那些正负样本分布不平衡的情况,能够帮助我们理解模型在检测难以区分的类别时的表现。

在这里插入图片描述

        从图中我们可以看到,曲线描绘了不同置信度阈值下,模型对于“Fire”和“Smoke”两个类别以及所有类别综合的F1分数。F1分数的最高点代表了模型在该置信度阈值下的最优平衡状态。在分析这些曲线时,我们要特别注意F1分数的峰值以及这些峰值对应的置信度阈值。

        观察“Fire”类别,其F1分数曲线在置信度阈值大约为0.4左右达到峰值,这表明在该阈值下,“Fire”检测的准确率和召回率之间达到了最佳的平衡。相似地,“Smoke”类别的F1分数峰值出现在略高于“Fire”的置信度阈值,这可能意味着模型对于“Smoke”类别的检测在更高的置信度下更为准确,或者需要更高的置信度才能更好地平衡准确率和召回率。

         整体而言,所有类别的综合F1分数在置信度为0.433时达到了0.65的峰值,这是评估模型整体性能时的一个关键发现。这意味着在这个置信度阈值下,模型对于“Fire”和“Smoke”两个类别的综合检测性能达到了最优。通过调整模型在实际应用中的置信度阈值到这个水平,我们可以期望在保持较高召回率的同时,获得较好的准确率。

         在实际应用中,我们可能需要根据特定的场景和需求来调整置信度阈值,以找到最适合的平衡点。例如,在一些对于准确率要求更高的场合,我们可以适当提高置信度阈值;而在对召回率要求更高的应用中,则可能需要降低置信度阈值以避免漏检。

4.3 YOLOv5、YOLOv6、YOLOv7和YOLOv8对比

(1)实验设计
在这里插入图片描述

        本实验旨在评估和比较YOLOv5、YOLOv6、YOLOv7和YOLOv8几种模型在烟雾检测任务上的性能。为了实现这一目标,博主分别使用使用相同的数据集训练和测试了这四个模型,从而可以进行直接的性能比较。本文将比较分析四种模型,旨在揭示每种模型的优缺点,探讨它们在工业环境中实际应用的场景选择。

模型 图像大小 (像素) mAPval 50-95 CPU ONNX 速度 (毫秒) A100 TensorRT 速度 (毫秒) 参数数量 (百万) FLOPs (十亿)
YOLOv5nu 640 34.3 73.6 1.06 2.6 7.7
YOLOv8n 640 37.3 80.4 0.99 3.2 8.7
YOLOv6N 640 37.5 - - 4.7 11.4
YOLOv7-tiny 640 37.4 - - 6.01 13.1

(2)度量指标

  • F1-Score:F1-Score是精确率(Precision)和召回率(Recall)的调和平均值。精确率是指模型正确识别的正例与所有识别为正例的案例之比,而召回率是指模型正确识别的正例与所有实际正例之比。F1-Score对于不平衡的数据集或者需要同时考虑精确率和召回率的任务特别重要。
  • mAP(Mean Average Precision):mAP是衡量模型在多个类别上平均检测准确度的指标。它计算了模型在所有类别上的平均精度,是目标检测领域中常用的性能度量。
名称 YOLOv5nu YOLOv6n YOLOv7-tiny YOLOv8n
mAP 0.646 0.670 0.638 0.634
F1-Score 0.65 0.69 0.66 0.64

(3)实验结果分析

        在深度学习领域,持续的算法迭代和更新是提升模型性能的关键途径。我们通过在相同的数据集上实施一系列实验,旨在比较和评估不同版本的YOLO模型——包括YOLOv5nu、YOLOv6n、YOLOv7-tiny以及YOLOv8n——在烟雾检测任务上的性能。实验的设计和目的是为了明确各版本模型在准确性和检测效率上的差异,以便为实际应用提供更具指导性的见解。

        首先观察mAP值,它反映了模型在不同置信度阈值下检测准确性的平均水平。YOLOv5nu、YOLOv6n和YOLOv8n在这一指标上均获得了0.867的相同分数,这表明这三个模型在检测准确性上表现相近,都达到了较高的水平。相比之下,YOLOv7-tiny的mAP得分为0.834,略低于其他三个模型。这可能是因为YOLOv7-tiny作为一个“轻量化”版本,在模型复杂度和检测能力上可能做了妥协。

在这里插入图片描述

        在F1-Score的角度,这个指标结合了精确度和召回率的信息,是衡量模型整体性能的重要标准。从结果来看,YOLOv6n以0.84的得分略高于其他模型,显示出其在平衡检测准确性和全面性方面的微小优势。YOLOv5nu和YOLOv8n的F1-Score均为0.82,表现稳定。YOLOv7-tiny的F1-Score为0.81,与mAP的结果一致,表明其整体性能略逊于其他版本。

        综合考虑这两个指标,我们可以得出结论,YOLOv6n在我们的实验中表现略优,尤其是在保持检测准确性和覆盖度方面达到了较好的平衡。而YOLOv5nu和YOLOv8n的表现也非常接近,都展示了出色的检测性能。尽管YOLOv7-tiny在这些测试中表现稍弱,但作为一个轻量级版本,它仍然是资源受限环境下的一个可行选择。

        这些对比结果对于实际应用中模型的选择提供了有力的参考。在选择模型时,除了考虑性能指标之外,还应考虑模型的运行速度、资源消耗和部署环境。例如,在对响应时间要求极高的实时烟雾检测系统中,即使是微小的性能提升也可能非常关键。而在资源有限的设备上,一个稍微性能低一些但更轻量的模型可能更加合适。总之,选择合适的模型需要根据具体的应用场景和性能需求来综合决策。

4.4 代码实现

        在现代计算机视觉领域,将深度学习模型应用于实时图像处理任务已成为一项重要技术。在本博客中,我们将详细介绍如何使用YOLOv8算法,结合PySide6创建一个实时目标检测系统。该系统能够在视频流中识别和标注特定对象,如火焰和烟雾。

(1)引入必要的库
        首先,系统的构建开始于导入必要的Python模块开始。sys模块是Python内建的模块,它提供了许多与Python解释器紧密相关的功能。例如,sys.argv用于获取命令行参数,这在启动应用程序时尤为重要。time模块允许我们获取当前时间,这对于性能评估和监控推理时间至关重要。OpenCV库(cv2)是图像处理的核心,它提供了一系列强大的功能来捕捉和处理图像数据。

import sys  # 导入sys模块,用于处理Python运行时环境的一些操作
import time  # 导入time模块,用于处理时间相关的操作
import cv2  # 导入OpenCV库,用于处理图像和视频
from QtFusion.path import abs_path
from QtFusion.config import QF_Config
from QtFusion.widgets import QMainWindow  # 从QtFusion库中导入FBaseWindow类,用于创建主窗口
from QtFusion.handlers import MediaHandler  # 从QtFusion库中导入MediaHandler类,用于处理媒体数据
from QtFusion.utils import drawRectBox  # 从QtFusion库中导入drawRectBox函数,用于在图像上绘制矩形框
from QtFusion.utils import get_cls_color  # 从QtFusion库中导入get_cls_color函数,用于获取类别颜色
from PySide6 import QtWidgets, QtCore  # 导入PySide6库的QtWidgets和QtCore模块,用于创建GUI和处理Qt的核心功能
from YOLOv8Model import YOLOv8Detector  # 从YOLOv8Model模块中导入YOLOv8Detector类,用于进行YOLOv8物体检测
from datasets.FireSmoke.label_name import Label_list

QF_Config.set_verbose(False)

(2)设置主窗口
        构建用户界面(UI)是实现系统的重要一步。我们用PySide6库构建了图形用户界面。QMainWindow是我们窗口的基类,提供了一个用于展示处理后图像的画布。通过覆盖keyPressEvent方法,我们可以捕捉用户的键盘输入,从而允许用户通过简单的按键操作来控制程序。

class MainWindow(QMainWindow):  # 定义MainWindow类,继承自FBaseWindow类
    def __init__(self):  # 定义构造函数
        super().__init__()  # 调用父类的构造函数
        self.resize(640, 640)  # 设置窗口的大小为850x500
        self.label = QtWidgets.QLabel(self)  # 创建一个QLabel对象,用于显示图像
        self.label.setGeometry(0, 0, 640, 640)  # 设置QLabel的位置和大小

    def keyPressEvent(self, event):  # 定义键盘按键事件处理函数
        if event.key() == QtCore.Qt.Key.Key_Q:  # 如果按下的是Q键
            self.close()  # 关闭窗口

(3)图像帧处理与烟雾检测
        在图像处理方面,我们定义了frame_process函数,它是系统处理每一帧视频流的核心。该函数首先调整帧大小以适配GUI窗口,然后调用YOLOv8模型进行预测。我们通过计算并打印推理时间来评估性能。如果模型在当前帧中检测到目标,我们将使用drawRectBox函数在图像上绘制矩形框,并添加相关的信息标签。

def frame_process(image):  # 定义帧处理函数,用于处理每一帧图像
    image = cv2.resize(image, (640, 640))  # 将图像的大小调整为850x500
    pre_img = model.preprocess(image)  # 对图像进行预处理

    t1 = time.time()  # 获取当前时间
    pred, superimposed_img = model.predict(pre_img)  # 使用模型进行预测
    t2 = time.time()  # 获取当前时间
    use_time = t2 - t1  # 计算预测所花费的时间

    print("推理时间: %.2f" % use_time)  # 打印预测所花费的时间
    det = pred[0]  # 获取预测结果
    # 如果有检测信息则进入
    if det is not None and len(det):
        det_info = model.postprocess(pred)  # 对预测结果进行后处理
        for info in det_info:  # 遍历检测信息
            name, bbox, conf, cls_id = info['class_name'], info['bbox'], info['score'], info[
                'class_id']  # 获取类别名称、边界框、置信度和类别ID
            label = '%s %.0f%%' % (name, conf * 100)  # 创建标签,包含类别名称和置信度
            # 画出检测到的目标物
            image = drawRectBox(image, bbox, alpha=0.2, addText=label, color=colors[cls_id])  # 在图像上绘制边界框和标签

    window.dispImage(window.label, image)  # 在窗口的label上显示图像

(4)初始化检测模型和设备

        最后,我们初始化了YOLOv8检测器,加载了训练好的模型,并创建了MediaHandler来处理实时的视频流。通过连接frame_process函数到视频流的每一帧,我们确保了图像可以实时地被处理和展示。整个系统通过一个简洁的GUI窗口为用户提供了实时的目标检测反馈。

cls_name = Label_list   # 定义类名列表

model = YOLOv8Detector()  # 创建YOLOv8Detector对象
model.load_model(abs_path("weights/best-yolov8n.pt", path_type="current"))  # 加载预训练的YOLOv8模型
colors = get_cls_color(model.names)  # 获取类别颜色

app = QtWidgets.QApplication(sys.argv)  # 创建QApplication对象
window = MainWindow()  # 创建MainWindow对象

videoHandler = MediaHandler(fps=30)  # 创建MediaHandler对象,设置帧率为30
videoHandler.frameReady.connect(frame_process)  # 当有新的帧准备好时,调用frame_process函数
videoHandler.setDevice(device=0)  # 设置设备为0,即默认的摄像头
videoHandler.startMedia()  # 开始处理媒体流

# 显示窗口
window.show()
# 进入 Qt 应用程序的主循环
sys.exit(app.exec())

        整个系统展示了如何将深度学习与应用程序开发结合起来,提供实时的目标检测功能。它不仅适用于火焰和烟雾检测,还可以扩展到其他各种实时图像识别任务中。