基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的交通信号灯识别系统(深度学习+UI界面+训练数据集+Python代码)

news2024/11/24 13:07:52

摘要:本研究详细介绍了一种采用深度学习技术交通信号灯识别系统,该系统集成了最新的YOLOv8算法,并与YOLOv7YOLOv6YOLOv5等早期算法进行了性能评估对比。该系统能够在各种媒介——包括图像视频文件实时视频流批量文件中——准确地识别交通信号灯。文章深入阐述了YOLOv8算法的机理,并附带了Python语言的实现代码、所需训练数据集,以及基于PySide6框架构建的用户界面(UI)。此外,系统还融合了SQLite数据库的用户管理功能,实现了一键切换YOLOv5/v6/v7/v8模型的便捷操作,以及提供了界面的自定义修改选项。本文目的是为交通信号灯识别领域的研究人员以及深度学习初学者提供实用指导和资源。完整的代码库和数据集可通过文末提供的链接进行下载。本文结构如下:

文章目录

  • 前言
  • 1.数据集介绍
  • 2. 系统界面效果
  • 3. YOLOv8算法原理
  • 4. 代码简介
    • 4.1 模型预测
    • 4.2 模型训练
    • 4.3 YOLOv5、YOLOv6、YOLOv7和YOLOv8对比
    • 4.4 代码实现
  • 5. 交通信号灯识别系统实现
    • 5.1 系统设计思路
    • 5.2 登录与账户管理
  • 下载链接
  • 6. 总结与展望
  • 结束语

➷点击跳转至文末所有涉及的完整代码文件下载页☇

基于YOLOv8/v7/v6/v5的交通信号灯识别系统演示与介绍(深度学习模型+PySide6界面+训练数据集)


前言

        在当今快速发展的智能交通系统中,交通信号灯识别技术扮演着至关重要的角色。随着城市交通流量的不断增加,传统的交通管理方法已经无法满足现代社会的需求,这使得交通信号灯识别系统成为了提高道路安全、优化交通流量管理的关键技术之一。交通信号灯识别不仅可以帮助自动驾驶汽车正确理解交通信号,从而做出合理的驾驶决策,也可以辅助交通监控系统对违规行为进行识别,进一步提高交通管理的智能化水平。

        研究交通信号灯识别系统的意义不仅仅体现在促进交通安全和提高交通效率上,它还有助于推动自动驾驶技术的发展。随着人工智能技术的不断进步,自动驾驶汽车已经成为了未来交通发展的重要趋势。在这样的背景下,高效准确的交通信号灯识别系统对于确保自动驾驶汽车能够安全行驶在复杂的城市交通环境中至关重要。

在这里插入图片描述

        近年来,交通信号灯识别领域的研究快速发展,众多研究者通过深度学习技术,尤其是卷积神经网络(CNN),实现了在复杂环境下对交通信号灯的高效识别。基于YOLO算法的研究尤其活跃,由于其出色的速度和准确性,YOLO系列在交通信号灯识别系统中得到了广泛的应用。以下是基于最新研究的几个重要发现和进展。

        首先,YOLOv5自推出以来,在交通信号灯识别领域已经展示了显著的性能提升1。YOLOv5通过优化模型结构和训练策略,不仅提高了识别的准确率,还保持了较高的处理速度,使其在实时交通信号灯识别系统中得到了有效应用。此外,YOLOv5的轻量化设计也使得它能够在计算资源有限的设备上运行,为边缘计算设备提供了技术支持。随后,YOLOv6和YOLOv7的发布,分别引入了新的网络架构和训练技巧,进一步提高了在交通信号灯识别任务上的表现23。特别是YOLOv7在处理复杂场景下的信号灯识别时,通过改进的注意力机制和数据增强方法,有效提高了模型的泛化能力和鲁棒性。最新的YOLOv8算法,引入了更为高效的特征提取和目标检测机制,不仅在速度上有所提升,更在准确性上设置了新的标杆4。YOLOv8通过优化网络结构和引入创新的损失函数,显著提高了对小目标和在复杂背景下目标的检测能力,这对于交通信号灯识别尤其重要,因为信号灯在整个交通场景中通常占据的像素很少。此外,除了YOLO系列之外,还有研究通过融合多种传感器数据,如雷达和摄像头,来提高交通信号灯识别的准确性和可靠性5。这种多模态方法能够有效应对不同光照和天气条件下的识别挑战,提高系统在实际应用中的稳定性。

        与此同时,数据集的发展也是支撑这些技术进步的关键因素。早期的研究多依赖于小规模、特定场景的数据集,限制了模型的泛化能力和实用性。近年来,随着大规模、多样化的数据集的发布,如COCO、Cityscapes和Berkeley DeepDrive (BDD100K),研究者们得以在更加复杂多变的实际场景中训练和测试他们的模型,这些数据集的多样性和规模的扩大极大推动了识别算法的进步和优化。

        本文通过综合运用最新的目标检测技术和界面设计工具,详尽地探讨了构建高效、用户友好的交通信号灯识别系统的全过程。主要贡献可总结如下:

  1. 采用最先进的YOLOv8算法进行交通信号灯识别:本文不仅介绍了如何使用YOLOv8算法进行高效的交通信号灯识别,还通过与YOLOv7、YOLOv6、YOLOv5等早期版本的比较,展现了YOLOv8在效率和精确度上的显著优势。这为交通信号灯识别领域的研究者和实践者提供了一种新的、更高效的研究方法和实践工具。
  2. 利用PySide6实现用户友好的交通信号灯识别系统界面:通过Python的PySide6库,本文展示了如何开发出具有良好用户交互界面的交通信号灯识别系统。该系统的设计不仅便于用户操作,同时也促进了YOLOv8算法的广泛应用,为推动交通信号灯识别技术的实际部署和应用打下了基础。
  3. 系统集成登录管理功能:通过引入登录管理功能,本文提升了系统的安全性,并为将来引入更多个性化功能奠定了基础。这一设计思路有助于构建更加安全、可扩展的应用系统,满足不同用户的需求。
  4. 对YOLOv8模型进行深入研究:本文不仅应用了YOLOv8算法进行交通信号灯识别,还对算法的性能进行了全面的研究。通过对模型精确度、召回率等关键性能指标的细致评估,以及在不同环境和条件下的表现分析,为进一步优化和改进YOLOv8算法提供了坚实的基础。
  5. 提供完整的数据集和代码资源包:为了便于读者更好地理解和应用YOLOv8及其前版本算法在交通信号灯识别中的操作,本文提供了详细的数据集和完整的代码资源包。这些资源使读者能够直接复现本文的实验结果,并在此基础上进行自己的研究和开发工作。

1.数据集介绍

        在智能交通系统和自动驾驶技术的发展过程中,交通信号灯识别系统扮演着极其重要的角色。本文介绍的数据集是为了进一步提升交通信号灯识别技术而精心构建的,它总共包含20841张图像,这些图像被分为18207张训练集图片、1755张验证集图片以及879张测试集图片。这种划分确保了模型在训练期间能接触到大量的样本,同时也能在验证和测试阶段对模型的泛化能力进行准确的评估。

        在数据预处理的阶段,我们对图像进行了一系列的标准化操作,以确保输入到模型中的图像数据具有一致性。这包括了调整图像尺寸、规范化像素值到一定的范围,以及进行必要的图像剪裁或填充,以符合模型输入的要求。这一步骤是为了减少由于图像大小或者摄像头硬件差异而引起的偏差,提高模型训练的效率。

在这里插入图片描述

        我们的数据集还经过了严格的图像增强处理,以提升模型在各种环境条件下的鲁棒性。这些增强包括但不限于随机旋转、翻转、缩放、颜色抖动等技术,这些操作通过模拟真实世界中的变化,比如不同的光照条件、天气状况和复杂背景,从而提高了模型对于这些变化的适应性。

        数据集的标注过程中,我们细致地标记了不同类型的交通信号灯和相关标志,涵盖了从常见的限速标志到特殊指令如“Give way”、“Parking”等的详细标注。为了训练出能够精准检测目标的模型,每一张图像都配备了精确的边界框标注。这些标注对于模型的学习过程至关重要,它们直接影响到后续的检测精度。

        然而,数据集分布图显示了一些挑战,例如“Give way”和“Parking”类别的样本量远多于其他类别,而“Stop”和“Roundabout”等类别的样本较少,这可能会导致模型对样本量多的类别有更好的识别效果,对样本量少的类别效果较差。为了解决这一不平衡问题,可能需要采用数据重采样或增强技术来提高那些代表性不足类别的样本数量。

        此外,边界框的尺寸分布图揭示了标志在图像中的相对尺寸和中心位置分布,大多数目标都集中在图像的中心区域。这一发现对于模型训练意义重大,因为它表明我们可以在模型训练时特别关注这一区域,或者使用特定的数据增强技术来模拟标志出现在图像边缘的情况。

在这里插入图片描述

        每张图像都有相应的标签和类别,这些标签为模型提供了必要的监督信息,以确保学习过程的有效性。类别信息可能包括不同颜色的交通信号灯(如红、黄、绿)、不同状态的指示(比如直行、左转、右转)和各种交通标志。这样详细的分类不仅有利于训练出更精准的模型,还能让模型更好地理解和预测各种交通场景,从而在实际应用中提供精确的辅助信息。博主使用的类别代码如下:

Chinese_name = {'green': "绿灯", 'red': "红灯", "yellow": "黄灯"}

        总的来说,本文介绍的这一数据集在数量和质量上都能够很好地支撑起交通信号灯识别模型的训练需求。其多样化的环境条件、全面的标注信息以及经过深思熟虑的预处理和增强操作,共同保证了该数据集在交通信号灯识别技术研究和应用中的实用性和有效性。通过对这些数据的分析和使用,我们能够在智能交通系统领域进一步推动识别技术的进步,为自动驾驶技术的安全和有效性提供坚实的数据支撑。


2. 系统界面效果

        系统以PySide6作为GUI库,提供了一套直观且友好的用户界面。下面,我将详细介绍各个主要界面的功能和设计。

(1)系统提供了基于SQLite的注册登录管理功能。用户在首次使用时需要通过注册界面进行注册,输入用户名和密码后,系统会将这些信息存储在SQLite数据库中。注册成功后,用户可以通过登录界面输入用户名和密码进行登录。这个设计可以确保系统的安全性,也为后续添加更多个性化功能提供了可能性。

在这里插入图片描述

(2)在主界面上,系统提供了支持图片、视频、实时摄像头和批量文件输入的功能。用户可以通过点击相应的按钮,选择要进行交通信号灯识别的图片或视频,或者启动摄像头进行实时检测。在进行交通信号灯识别时,系统会实时显示检测结果,并将检测记录存储在数据库中。

在这里插入图片描述

(3)此外,系统还提供了一键更换YOLOv8/v5模型的功能。用户可以通过点击界面上的"更换模型"按钮,选择不同的YOLOv8模型进行检测。与此同时,系统附带的数据集也可以用于重新训练模型,以满足用户在不同场景下的检测需求。

在这里插入图片描述

(4)为了提供更个性化的使用体验,这里系统支持界面修改,用户可以自定义图标、文字等界面元素。例如,用户可以根据自己的喜好,选择不同风格的图标,也可以修改界面的文字描述。

在这里插入图片描述


3. YOLOv8算法原理

        YOLOv8算法是目前先进的目标检测框架之一,其设计理念在于通过高效的网络结构实现快速而精准的目标检测。YOLOv8的网络架构采用了Neck和Head的分离设计,这意味着特征提取(Backbone)和目标检测(Head)两个过程被明确区分,从而优化了每个部分的性能。

在这里插入图片描述

         在特征提取阶段,YOLOv8继承并发展了YOLOv5和YOLOv7的设计思想,采用CSPNet结构作为其Backbone,CSPNet的优势在于减少计算重复性,同时保持了丰富的渐进式特征。这种结构通过跨阶段部分网络(CSP)的方式,降低了计算量并改进了特征传播效率。这一点在处理大量图像数据时特别重要,因为它能够有效地减少计算资源消耗,同时保持或提升检测性能。

        YOLOv8的Neck部分采用了SPP(Spatial Pyramid Pooling)和FPN(Feature Pyramid Networks)的结合,这在多尺度目标检测中尤为关键。SPP能够在不同尺度下提取有效的上下文信息,而FPN通过多尺度特征融合增强了模型对不同大小目标的检测能力。SPP通过最大池化操作捕获不同尺度的特征,而FPN则通过自顶向下和自底向上的路径加强了特征之间的连接。

        在Head部分,YOLOv8采取了一种被称为Decoupled-Head的方法,这种方法将分类和定位两个任务分开处理,有助于提升模型在这两个方面的专注度和准确性。相较于传统的设计,Decoupled-Head的方法通过分离这两个任务来减少它们之间的相互干扰,从而提高了整体的检测性能。

        YOLOv8还引入了Anchor-Free的机制,这是目标检测领域中的一项创新。与传统依赖Anchor Box的方法不同,Anchor-Free机制允许模型直接预测目标的中心点和边界框,减少了对先验框的依赖,这使得模型更加灵活,也简化了训练过程。

        此外,YOLOv8在损失函数上也进行了创新,采用了Distribution Focal Loss和CIoU Loss。Distribution Focal Loss对于不平衡数据分布具有更好的鲁棒性,它能够减少易分样本对损失函数的贡献,更专注于难以识别的样本。CIoU Loss则更加关注边界框的几何精度,不仅考虑了预测框和实际框的重叠面积,还考虑了它们的中心点距离和形状相似度,这有助于在边界框回归任务中获得更高的精度。


4. 代码简介

        在本节中,我们将详细介绍如何使用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/test.png")
image = cv_imread(img_path) 

        在读取了图像文件之后,就可以使用加载的模型对图像进行预测了。下图为预测结果。

pred, superimposed_img = model.predict(pre_img)

在这里插入图片描述

4.2 模型训练

        这里我们开始训练和测试自己的数据集,在cmd终端或pycharm中运行run_train_model.py进行训练,以下是训练过程中的结果截图。YOLOv8的损失函数是其性能的关键部分,它指导模型学习如何准确地检测和分类对象。

        以下表格详细介绍了YOLOv8模型训练中使用的一些重要超参数及其设置:

超参数设置说明
学习率(lr00.01决定了模型权重调整的步长大小,在训练初期有助于快速收敛。
学习率衰减(lrf0.01控制训练过程中学习率的降低速度,有助于模型在训练后期细致调整。
动量(momentum0.937加速模型在正确方向上的学习,并减少震荡,加快收敛速度。
权重衰减(weight_decay0.0005防止过拟合,通过在损失函数中添加正则项减少模型复杂度。
热身训练周期(warmup_epochs3.0初始几个周期内以较低的学习率开始训练,逐渐增加到预定学习率。
批量大小(batch16每次迭代训练中输入模型的样本数,影响GPU内存使用和模型性能。
输入图像大小(imgsz640模型接受的输入图像的尺寸,影响模型的识别能力和计算负担。

        在本节,我们将深入探讨如何使用YOLOv8算法训练一个高效的交通信号灯识别系统。我将分享实际的代码实现过程,并对关键步骤进行详细的分析。

        首先,我们从导入必要的库开始。使用Python的os和yaml库来处理文件路径和配置文件,并引入YOLO模型,这是我们训练过程中的核心。

import os
import yaml
from ultralytics import YOLO  # 导入YOLO模型
from QtFusion.path import abs_path

        然后,我们设置了数据集的路径,这通过abs_path函数完成,它将相对路径转换为绝对路径,确保无论我们在哪里运行代码,路径都是正确的。这对于跨平台的项目至关重要,因为不同操作系统的文件路径表示方式可能不同。

data_path = abs_path('datasets/VehicleType/vehicle.yaml', path_type='current')  # 数据集的yaml的绝对路径
unix_style_path = data_path.replace(os.sep, '/')

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

        接下来,我们读取了配置文件中的内容,并根据需要对其进行了修改。这一步是为了确保配置文件中的path键正确地指向了我们的数据集路径。

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)

        然后,我们使用YOLO类来加载预训练的YOLO模型。这里我们加载了YOLOv5nu的权重,这一步骤是为了使用这些预训练的权重作为我们训练的起点,这可以大大加快训练速度并提高最终模型的性能。

workers = 1
batch = 8
data_name = "TrafficLight"
data_path = abs_path(f'datasets/{data_name}/{data_name}.yaml', path_type='current')  # 数据集的yaml的绝对路径
results = model.train(  # 开始训练模型
    data=data_path,  # 指定训练数据的配置文件路径
    device='cpu',  # 指定使用CPU进行训练
    workers=workers,  # 指定使用2个工作进程加载数据
    imgsz=640,  # 指定输入图像的大小为640x640
    epochs=100,  # 指定训练100个epoch
    batch=batch,  # 指定每个批次的大小为8
    name='train_v5_' + data_name  # 指定训练任务的名称
)

        在准备好数据和模型之后,我们开始了训练过程。train方法被用来指定了许多重要的训练参数,如数据集路径、计算设备、工作进程数、输入图像的尺寸、批次大小以及训练周期数。

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

        最后,我们重复了相同的训练步骤,但这次使用YOLOv8的权重。代码展示了如何加载另一个预训练模型YOLOv8并进行训练,这显示了如何灵活地在不同版本的YOLO模型之间进行切换。

        在对YOLOv8模型进行训练的过程中,我们通过监控不同的损失函数和性能指标来评估模型的学习进度和性能。损失函数的变化趋势和最终的精确度评估对于理解模型的性能至关重要。本文将对训练过程中损失函数和性能指标的变化进行深入分析。

在这里插入图片描述

        首先,我们注意到所有的损失函数曲线—包括训练的边框损失(train/box_loss)、分类损失(train/cls_loss)和目标损失(train/obj_loss)—都显示了随着迭代次数增加而持续下降的趋势,这表明模型在训练过程中逐渐学习到了更精确的特征表示和目标定位能力。损失曲线的平滑版本(橙色虚线)进一步验证了这一下降趋势的稳定性。这些损失函数是优化算法的核心,它们指导模型不断调整参数以更好地预测目标类别和位置。

        相对应地,验证集的损失曲线(val/box_loss、val/cls_loss、val/obj_loss)也表现出了类似的下降趋势,这是一个积极的信号,意味着模型没有发生过拟合,即在未见过的数据上也能保持较好的性能。

        接下来,评价指标部分显示了模型准确性的几个关键指标:精确度(precision)、召回率(recall)、平均精确度均值(mAP@0.5)和严格的平均精确度均值(mAP@0.5-0.95)。在训练过程中,精确度和召回率都表现出了逐渐上升并趋于稳定的趋势,说明模型能够以较高的可靠性正确识别和定位目标对象。特别是召回率的提高表示模型能够找到更多的正样本。

        而mAP(平均精确度均值)是评估目标检测模型性能的标准指标,mAP@0.5和mAP@0.5-0.95分别表示在IOU(交并比)阈值为0.5和0.5到0.95这个范围内,模型的平均精确度。从图表中我们可以看出,这两个指标在训练过程中稳步上升,并在后期趋于稳定。这表明模型对于不同尺寸的目标都有着较好的识别能力,并且在不同的阈值下都能保持较高的检测性能。

        在评估机器学习模型,尤其是目标检测模型的性能时,F1分数是一个重要指标,因为它综合考虑了模型的精确度和召回率。F1分数是精确度和召回率的调和平均,能够平衡两者之间的关系。理想的情况是,模型能够同时拥有高精确度和高召回率,但在实际情况中,通常需要在两者之间做出权衡。

在这里插入图片描述

         首先,值得注意的是,在某个置信度阈值点(大约为0.364),所有类别的综合F1分数达到了0.94,这是一个非常高的分数,表明模型在这个置信度阈值下取得了很好的平衡,能够以较高的精度和召回率识别信号灯。通常情况下,一个较高的F1分数意味着模型在区分正类和负类上做得非常出色,即正确识别出的交通信号灯数量远大于错误识别和遗漏的数量。

         每条曲线的起始点都非常接近1.0的F1分数,随后随着置信度阈值的提高,F1分数开始下降。这通常表明在较低置信度阈值时,模型能够以较高召回率检测出大多数正类,但随着置信度阈值提高,模型开始更加谨慎,只有当它对检测结果更加自信时才会将其标记为正类,这可能会导致召回率下降,但同时精确度会有所提高。

        进一步观察,可以发现绿色信号灯的F1曲线表现最好,紧随其后的是黄色和红色信号灯。这表明模型在识别绿色信号灯时可能有更好的性能,这可能是由于数据集中绿色信号灯样本的质量和数量、或者绿色信号灯在实际交通场景中的特性。

        整体而言,这样的F1分数曲线表明了模型具有很好的性能,但同时也揭示了在置信度阈值设定上的重要性。为了实现最佳的模型性能,研究人员和工程师需要仔细选择一个合适的置信度阈值,这个阈值既能保证高精度又能维持合理的召回率。实际应用中,这个阈值的选择可能会根据具体场景和对精确度与召回率的特定需求来调整。

        总体而言,这些图表显示出YOLOv8模型在训练过程中的性能稳步提升,表明了良好的学习效果和模型的泛化能力。损失函数的下降以及评价指标的上升均表明了模型在交通信号灯识别任务上的有效性。当然,在部署模型之前,仍需在更多复杂的真实世界场景中对模型进行彻底的测试,以确保其鲁棒性和准确性。此外,进一步的调优,如调整学习率策略、扩展训练数据集或使用更加复杂的数据增强技术,可能会进一步提升模型的性能。通过对这些训练过程中的关键指标进行深入分析,研究者和工程师可以继续改进模型。

4.3 YOLOv5、YOLOv6、YOLOv7和YOLOv8对比

(1)实验设计

在这里插入图片描述

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

模型图像大小 (像素)mAPval 50-95CPU ONNX 速度 (毫秒)A100 TensorRT 速度 (毫秒)参数数量 (百万)FLOPs (十亿)
YOLOv5nu64034.373.61.062.67.7
YOLOv8n64037.380.40.993.28.7
YOLOv6N64037.5--4.711.4
YOLOv7-tiny64037.4--6.0113.1

(2)度量指标

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

(3)实验结果分析

        在此实验中,我们将对四个版本的YOLO算法进行性能对比,它们在相同的数据集上进行训练和测试。这些版本分别是YOLOv5nu、YOLOv6n、YOLOv7-tiny以及YOLOv8n。我们选用了两个关键的性能指标:平均精度均值(mean Average Precision, mAP)和F1-Score,这两个指标共同衡量了模型在目标检测任务上的准确性和可靠性。

        从实验数据中我们可以看到,YOLOv5nu、YOLOv6n和YOLOv8n在mAP指标上表现一致,均达到了0.975的高分,显示了它们在综合精度上具有较高的水平。而YOLOv7-tiny略低一些,为0.969,虽然只是略微差距,但这可能意味着在处理该数据集时,YOLOv7-tiny在某些情况下的识别效果可能不如其他三个版本。

在这里插入图片描述

       在F1-Score指标上,我们注意到YOLOv5nu、YOLOv6n和YOLOv7-tiny都保持了0.95的高分,而YOLOv8n稍低一点,为0.94。F1-Score是精确度和召回率的调和平均,一个高的F1-Score意味着模型在保持较低误检率的同时,也能保持较高的检测率。因此,YOLOv5nu、YOLOv6n和YOLOv7-tiny在这方面的平衡性略优于YOLOv8n。

       综合来看,这四个版本的YOLO算法都展现了强大的目标检测性能,它们在两个重要的性能指标上得分相近,这表明在相同条件下它们的性能差异不大。尽管如此,在实际应用中,即使是微小的性能差异也可能会对最终结果产生影响,特别是在那些对于精度要求极高的应用场景中。

4.4 代码实现

        在这篇博客中,我们将探讨如何结合YOLOv8检测器和PySide6框架,实现一个交通信号灯识别系统。这个系统能够处理视频流,并实时展示检测到的交通信号灯,为用户提供直观的视觉反馈。现在,让我们深入理解实现这一功能的代码逻辑。

(1)导入必要的模块和配置
        首先,系统必须导入必要的模块:sys模块让我们能够与Python解释器交互,time模块帮助我们记录处理每一帧所用的时间,而cv2模块是OpenCV库的核心,为我们提供了一系列强大的图像处理功能。此外,QtWidgets和QtCore模块是PySide6库的一部分,它们使得创建交互式的图形用户界面(GUI)成为可能。

import sys  # 导入sys模块,用于访问与Python解释器相关的变量和函数
import time  # 导入time模块,用于获取当前时间

import cv2  # 导入OpenCV库,用于图像处理
from QtFusion.widgets import QMainWindow  # 从QtFusion库导入FBaseWindow类,用于创建主窗口
from QtFusion.handlers import MediaHandler  # 从QtFusion库导入MediaHandler类,用于处理媒体流
from QtFusion.utils import drawRectBox, get_cls_color  # 从QtFusion库导入drawRectBox函数,用于在图像上绘制矩形框
from PySide6 import QtWidgets, QtCore  # 导入PySide6库的QtWidgets和QtCore模块,用于创建GUI
from QtFusion.path import abs_path
from QtFusion.config import QF_Config
from YOLOv8Model import YOLOv8Detector  # 从YOLOv8Model模块导入YOLOv8Detector类,用于物体检测
from datasets.TrafficLight.label_name import Label_list

QF_Config.set_verbose(False)

(2)定义类别和模型
        YOLOv8模型是实现交通信号灯识别的关键,我们通过实例化YOLOv8Detector并加载预训练权重来准备模型。这一步骤对于确保我们的检测系统能够准确地识别各种交通信号灯至关重要。为了在图像上区分不同的车辆类型,我们通过get_cls_color函数为每一类车辆分配一个颜色。这样,在最终的输出图像中,用户可以通过颜色轻松区分不同的车辆类型。

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)  # 获取类别颜色

(3)创建主窗口
        接下来,我们定义了MainWindow类,它作为我们应用程序的主窗口。在该类中,我们通过resize方法设置窗口大小,并创建了一个QLabel对象作为图像显示的画布。键盘事件处理函数keyPressEvent允许用户通过按下Q键退出应用程序。

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

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

(4)主程序流程

        接着,定义frame_process函数处理从视频流中捕获的每一帧图像。该函数首先调整图像大小以适应GUI窗口,然后使用预训练的YOLOv8模型进行物体检测。通过记录前后时间,我们能够打印出每一帧的推理时间,这对于评估系统的实时性能至关重要。

def frame_process(image):  # 定义frame_process函数,用于处理每一帧图像
    image = cv2.resize(image, (850, 500))  # 调整图像的大小
    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控件上显示图像

        随后,我们创建了QApplication和MainWindow对象,设置了视频流处理的帧率,并连接了新帧的处理函数。通过启动媒体处理并显示窗口,我们完成了从摄像头捕获视频、实时处理图像到图形界面呈现的整个流程。

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())

        最后,我们创建了YOLOv8Detector对象并加载预训练模型。在MediaHandler对象的帮助下,我们设定了视频流的帧率,并将新帧的处理连接到了frame_process函数。随后,我们启动了媒体流处理并展示了主窗口,使得整个应用程序进入了Qt的事件循环。


5. 交通信号灯识别系统实现

        在构建我们的交互式交通信号灯识别系统时,不仅需要快速准确地处理视频流中的图像数据,还需要提供一个清晰易用的界面,让用户能够无缝地与之交互。我们的设计思路遵循了将复杂的功能模块化和简化的原则,通过将界面设计、媒体处理和深度学习模型融为一体,我们实现了这一目标。

5.1 系统设计思路

        在我们的系统设计中,我们的设计理念是构建一个高效、直观且用户友好的界面,使用户能够无缝地与系统交互。整个系统被设计为一个紧密集成的框架,其中每个组件都旨在提升整体性能和用户体验。
(1)架构设计
        系统设计采用的是一个层次化、模块化的架构,以提升整体的灵活性和可维护性。通过精心设计的MainWindow类,我们将用户交互、媒体流处理和深度学习模型有效地融合在一个统一的应用程序中。此外,为了增强各模块间的协作性能,系统特别采用了信号和槽机制来处理模块间的通信,这在Qt框架中是实现事件驱动编程的核心。

在这里插入图片描述

  • 处理层(Processing Layer):由深度学习的核心组成,即YOLOv8Detector类,这个类封装了预训练的YOLOv8模型以及图像处理和预测的相关方法。它负责接收原始图像帧,执行对象检测任务,并输出识别结果。通过高效的算法优化和GPU加速(如果可用),这一层确保了交通信号灯识别的速度和精度。
  • 界面层(UI Layer):界面层作为用户与系统互动的接口,通过Qt设计而成,它包含了各种可视化元素。例如,QLabel用于显示处理后的图像,QPushButton可能用于控制视频流的开始和停止。界面的直观设计对于用户来说非常重要,因为它直接关系到用户的操作体验。
  • 控制层(Control Layer):控制层则是协调整个系统运作的指挥中心。MainWindow类中的槽函数响应用户的交互,并根据用户的操作指示处理层进行图像的处理。此外,控制层还负责将处理结果反馈给用户界面,如实时显示检测结果,以及更新界面上的信息。

        总而言之,本系统的设计将高性能的交通信号灯检测模型与用户友好的交互界面相结合,为用户提供了一个高效、可靠且易于使用的交互式交通信号灯识别系统。它不仅展示了深度学习在交通信号识别领域的应用潜力,也为未来在该领域的研究与开发奠定了坚实的基础。

(2)系统流程

        在本博客中,我们将讲述设计一个交互式交通信号灯识别系统的全过程。本系统的核心设计理念是用户友好性,高效整合前沿的YOLOv8目标检测技术和直观的用户界面,以确保即使是非专业用户也能轻松使用该系统。在系统的设计中,我们特别强调了处理层、界面层和控制层的分离,旨在实现高效的模块间交互和数据流管理。

        我们的系统首先通过MainWindow类的实例初始化,它不仅为用户提供了一个操作界面,还负责配置整个应用程序的相关参数。这样的设计使得用户能够通过一个清晰的界面来选择数据输入源,无论是实时的摄像头捕获、视频文件还是静态图像,都能够轻松接入并处理。

在这里插入图片描述

  1. 当用户启动应用程序时,系统立即实例化MainWindow类。这个关键步骤会激活用户界面,加载必要的模型参数,并准备接收用户输入。该实例成为用户与应用程序交互的桥梁,负责将用户命令转换为具体的操作。

  2. 一旦用户选择了输入源,系统便通过媒体处理器开始对数据进行精确的处理。对于实时摄像头输入,系统可能需要进行配置,如调整分辨率和帧速率,以确保输入与模型的要求相匹配。而对于视频文件和图像文件,系统则需要执行读取和加载操作。

  3. 随后进入的是系统的核心处理循环。在预处理阶段,系统对捕获的每一帧图像进行调整和归一化处理,确保它们能够被YOLOv8模型正确分析。这个阶段是成功检测的前提,因为它直接影响到模型的识别结果。

  4. 进入检测与识别阶段,预处理后的图像送入YOLOv8模型,模型将检测出图像中的交通信号灯并进行识别。模型的输出不仅仅是信号灯的位置,还有相应的状态,如红、绿或黄灯。

  5. 每次检测完成后,用户界面将立即更新,以直观地展示每个信号灯的检测框。同时,系统将提供实时反馈,如识别出的信号灯状态和其他统计信息,这些都将动态显示在界面上。

  6. 最后,媒体控制也是用户体验的一个重要部分。用户可以随时开始或停止媒体流,无论是暂停摄像头的实时捕捉,还是停止视频文件的播放。这种控制为用户提供了操作上的灵活性,允许他们根据需要来调整系统的运行。

        总体而言,本系统的设计思路以用户为中心,不仅在技术层面实现了高效的交通信号灯识别,同时也在用户操作层面提供了高度的便利性和直观性。这种结合使得系统不仅对技术人员友好,对于普通用户同样易于上手,真正实现了科技为人服务的理念。

5.2 登录与账户管理

        在本节中,我们将讨论一个综合性的交通信号灯识别系统,该系统不仅在技术层面上实现了先进的多物体检测,而且在用户体验方面也进行了深入的设计。一个特别值得注意的特性是系统集成了一个完整的用户账户管理功能,旨在为用户提供一个安全、个性化的使用环境。

在这里插入图片描述

        首先,通过PySide6框架搭建的用户登录界面不仅美观现代,同时也与SQLite数据库无缝集成,确保了账户信息的安全存储和管理。用户首次使用系统时,可以方便地进行账户注册,设置自己的用户名和密码。除了基本的登录功能,系统还支持密码修改和头像设置,使用户能够根据个人喜好定制自己的账户。这些功能的实现采用了现代软件开发的最佳实践,注重保护用户的隐私和安全。

        账户管理的深度集成也意味着,一旦用户完成注册并登录,他们将进入一个独立的操作空间。在这个空间里,用户可以保存自己的检测结果和偏好设置,不必担心与其他用户的数据混淆。例如,用户可以保存特定的视频监控结果,甚至自定义检测参数,这些个性化设置会被关联到用户的账户中,随时可供调用和修改。

        当用户需要退出系统时,账户注销功能确保了用户的会话结束,所有个性化设置和临时数据都会被保留,待下一次用户登录时恢复。若用户忘记密码,系统还提供了重置密码的功能,保障用户能够轻松恢复对账户的访问。

        此外,登录模块的设计考虑到了用户的便捷性。简洁直观的用户界面设计使得注册、登录和账户管理操作变得非常直接。这样的设计不仅提升了用户体验,也降低了用户面对复杂系统时的学习成本。

在这里插入图片描述
        通过以上的设计思路和实现细节,本交通信号灯识别系统不仅提供了强大的多物体识别和实时检测功能,还通过用户登录界面提供了一系列个性化服务。无论是对于图像、视频文件、实时摄像头流的处理,还是对于批量文件输入的处理,用户都能在一个安全和个性化的环境中使用系统,实现真正意义上的“私人定制”。这样的系统设计不仅符合当前软件开发的趋势,更为用户在复杂的实时目标检测场景下提供了所需的一切便利和安全保障。


下载链接

    若您想获得博文中涉及的实现完整全部资源文件(包括测试图片、视频,py, UI文件,训练数据集、训练代码、界面代码等),这里已打包上传至博主的面包多平台,见可参考博客与视频,已将所有涉及的文件同时打包到里面,点击即可运行,完整文件截图如下:

在这里插入图片描述

完整资源中包含数据集及训练代码,环境配置与界面中文字、图片、logo等的修改方法请见视频,项目完整文件下载请见演示与介绍视频的简介处给出:➷➷➷

演示与介绍视频:https://www.bilibili.com/video/BV1FF4m157ic/
在这里插入图片描述

    在文件夹下的资源显示如下,下面的链接中也给出了Python的离线依赖包,读者可在正确安装Anaconda和Pycharm软件后,复制离线依赖包至项目目录下进行安装,另外有详细安装教程:(1)Pycharm软件安装教程;(2)Anaconda软件安装教程;(3)Python环境配置教程;

离线依赖安装教程:https://www.bilibili.com/video/BV1hv421C7g8/
离线依赖库下载链接:https://pan.baidu.com/s/1y6vqa9CtRmC72SQYPh1ZCg?pwd=33z5 (提取码:33z5)

6. 总结与展望

        在本博客中,我们详细介绍了一个基于YOLOv8模型的交通信号灯识别系统,还实验了YOLOv7、YOLOv6、YOLOv5等模型。系统以模块化的方式设计,充分采用了合理的架构设计,带来良好的可维护性和可扩展性。其用户界面友好,能够提供实时的交通信号灯识别结果展示,同时支持用户账户管理,以便于保存和管理检测结果和设置。

        该系统支持摄像头、视频、图像和批量文件等多种输入源,能够满足用户在不同场景下的需求。在后面可以添加更多预训练模型,增加检测和识别的种类;优化用户界面,增强个性化设置;并积极聆听用户反馈,以期不断改进系统,以更好地满足用户的需求。


结束语

        由于博主能力有限,博文中提及的方法即使经过试验,也难免会有疏漏之处。希望您能热心指出其中的错误,以便下次修改时能以一个更完美更严谨的样子,呈现在大家面前。同时如果有更好的实现方法也请您不吝赐教。


  1. Fang W, Wang L, Ren P. Tinier-YOLO: A real-time object detection method for constrained environments[J]. IEEE Access, 2019, 8: 1935-1944. ↩︎

  2. Redmon J, Divvala S, Girshick R, et al. You only look once: Unified, real-time object detection[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2016: 779-788. ↩︎

  3. Redmon J, Farhadi A. YOLO9000: better, faster, stronger[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2017: 7263-7271. ↩︎

  4. Bochkovskiy A, Wang C Y, Liao H Y M. Yolov4: Optimal speed and accuracy of object detection[J]. arXiv preprint arXiv:2004.10934, 2020. ↩︎

  5. Li C, Li L, Jiang H, et al. YOLOv6: A single-stage object detection framework for industrial applications[J]. arXiv preprint arXiv:2209.02976, 2022. ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1512424.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

execl/python读取数据库( Access、MySQL)

目录 一 、读取access数据库 (一)execl读取数据库 1.搜索ODBC(注意自己的execl是64位还是32位) 2.安装数据源的驱动程序 3.打开execl 4. 补充:选择数据源时,也可以直接在execl中选择数据源 &#xff…

YOLOv5涨点优化:backbone改进 | TransXNet:聚合全局和局部信息的全新CNN-Transformer视觉主干| CVPR2024

💡💡💡本文独家改进:CVPR2024 TransXNet助力检测,代替YOLOv5 Backbone 改进结构图如下: 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/category_12511931.html 💡💡💡全网独家首发创新(原创),适合paper !!! 💡💡💡 2024年计算…

最优学习率寻找

https://github.com/vmbbc/pytorch-lr-finderhttps://github.com/vmbbc/pytorch-lr-finder Keras 实现最优学习率寻找(LR Range Test) - 知乎深度神经网络使用随机梯度下降和可微分的误差向后传递更新神经网络中所有的可训参数 (trainable parameters \theta ),从而学到一个…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的自动驾驶目标检测系统详解(深度学习+Python代码+PySide6界面+训练数据集)

摘要:开发自动驾驶目标检测系统对于提高车辆的安全性和智能化水平具有至关重要的作用。本篇博客详细介绍了如何运用深度学习构建一个自动驾驶目标检测系统,并提供了完整的实现代码。该系统基于强大的YOLOv8算法,并对比了YOLOv7、YOLOv6、YOLO…

Trust Region Policy Optimization (TRPO)

Trust Region Policy Optimization (TRPO) 是一种强化学习算法,专门设计来改善策略梯度方法在稳定性和效率方面的表现。由 John Schulman 等人在 2015 年提出,TRPO 的核心思想是在策略优化过程中引入一个信任区域(trust region)&a…

探索TikTok云手机在社交媒体营销的作用

近年来,TikTok作为全球短视频平台之一,其用户基数呈现持续增长的趋势。伴随社交媒体的蓬勃发展,企业和个人纷纷涌入TikTok平台,追求更广泛的曝光和用户互动。为满足这一需求,TikTok云手机应运而生。本文将深度剖析TikT…

13、设计模式之模板模式(Template)

一、什么是模板模式 模板模式是一种基于继承实现的设计模式,它是行为型的模式。 主要思想是将定义的算法抽象成一组步骤,在抽象类种定义算法的骨架,把具体的操作留给子类来实现。 通俗地说,模板模式就是将某一行为制定一个框架&…

Selenium操作浏览器,弹出文件选择框,实现自动选定“目标文件”

前言 本文是该专栏的第20篇,后面会持续分享python爬虫干货知识,记得关注。 我们在使用selenium操作目标页面的时候,可能会遇到如下图所示的情景。 在用selenium操作并点击页面元素的时候,会弹出一个文件选择框,需要我们选择目标文件,并点击确认按钮,目标文件才能上传成…

三防手机与普通手机的区别在哪里?

一、三防手机和普通手机主要的区别在于其防护性能,它们是针对不同环境和使用场景设计的。三防手机一般包括防水、防尘和防摔三个方面的特点,而普通手机则往往没有这些特点。 防水性能。三防手机的防水性能通常比普通手机更强大。三防手机可以在一定程度上…

C#四部曲(知识补充)

Unity跨平台原理 .Net相关 只要编写的时候遵循.NET的这些规则,就能在.NET平台下通用 各种源码→根据.NET规范编写→(虚拟机)生成CIL中间码(保存在程序集中)→转成操作系统原代码 跨语言← 跨平台↓ Unity跨平台原理(Mono) c#脚本→MonoC#编…

Stream-JDK8

Stream概念 代码示例 package com.zz.stream;import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors;/*** 使用Stream流* 找出姓张并且是三个字的名字*/ public class Test {public static void main(Stri…

《向量数据库指南》——Milvus Cloud BYOC:为数据安全而生?

最近,整个硅谷都在关注 OpenAI 和 Anthropic 的动态。先是 Anthropic 发布了 Claude 3,剑指 GPT-4,被媒体认为“打破了 OpenAI 不可战胜的神话”。这也点燃了整个科技圈的热情,纷纷期待 OpenAI 放出 GPT-5 应战。随后(美东时间 3 月 5 日),OpenAI 发布一则官方公告,主题…

Linux认识与学习BASH

Linux认识与学习BASH 认识BASH这个Shellshell是什么系统的合法shell与/etc/shells功能Bash Shell的功能查询命令是否为Bash shell 的内置命令(type)命令的执行与快速编辑按钮 shell的变量功能什么是变量?变量的使用与设置:echo、变量设置规则、unset环境…

1.6数组

一.序言 数组是一组类型相同类型元素的集合,数组的定长的(数组的长度一旦被定义,长度不可改变)。 数组在内存当中是一块连续的空间,可以保存相同类型的多个元素。 二.一维数组 2.1.数组的创建 int arr1[10]; …

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的吸烟检测系统(深度学习+Python代码+PySide6界面+训练数据集)

摘要:本文详细说明了如何利用深度学习开发一个用于监测吸烟行为的系统,并分享了完整的代码实现。该系统采用了先进的YOLOv8算法,同时还使用YOLOv7、YOLOv6、YOLOv5算法,并对它们进行了性能比较,呈现了不同模型的性能指…

bpmn-js系列之Palette

前边写了四篇文章介绍了bpmn.js的基本使用,最近陆续有小伙伴加我催更,感谢对我这个半吊子前端的信任,接着更新bpmn.js的一些高级用法,本篇介绍对左侧工具栏Palette的隐藏和自定义修改 隐藏shape 左侧工具栏Palette有些图标我用不…

NIFI从Oracle11G同步数据到Mysql_亲测可用_解决数据重复_数据跟源表不一致的问题---大数据之Nifi工作笔记0065

首先来看一下整体的流程: 可以看到了用到了上面的这些处理器,然后我们主要看看,这里之前 同步的时候,总是出现重复的数据,奇怪. 比如源表中只有166条数据,但是同步过去以后变成了11万条数据了. ${db.table.name:equals(table1):or(${db.table.name:equals(table2)})} 可以看…

LeetCode169. 多数元素(Java)

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums [3,2,3] 输出:3 示例 …

C++(3/12)

自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和 #include <iostream>using name…

设计模式-行为型模式-模版方法模式

模板方法模式&#xff0c;定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。[DP] 模板方法模式是通过把不变行为搬移到超类&#xff0c;去除子类中的重复代码来体现它的优势。 //首…