第五节 Pyside6可视化界面
目录
5.1 Pyside6
5.2 界面设计
5.3 程序设计
完整程序代码:
运行结果:
5.1 Pyside6
PySide6是Qt for Python项目的一部分,它提供了对Qt 6.0的官方Python绑定。Qt是一个跨平台的C++应用程序开发框架,以其丰富的UI组件、优秀的性能和跨平台能力而闻名。PySide6继承了Qt的这些优点,同时结合了Python的简洁性和开发效率。
博客:【Python学习日记:PySide6】【持续更新】-CSDN博客
【Python桌面应用】PySide6 界面开发完全指南_pyside6中文手册-CSDN博客
Pyside6 安装指令: pip install pyside6
如何找到qtdesiger?
先输入指令: where python
这是当前环境下,能找到的python.exe。找到yolov5虚拟环境的路径:D:\miniconda\envs\yolov5\python.exe。在其路径下找/Libs/site-packages/PySide6/designer.exe。并右击创建快捷方式。
由于designer.exe最后生成的文件是后缀是.ui,还不是python的编译文件,还需要下载qt来进行将文件转为可编译文件。
下面是在vscode安装qt for python
5.2 界面设计
(1)、先设计好界面。
(2)Ctrl+s将文件保存到yolov5-7.0中。
(3)、将.ui文件转化成.py文件,找到.ui文件,右键找到Compile Qt UI File并点击,就可以将文件进行转化了。
5.3 程序设计
程序功能描述:用户选择任意一张图片或一段视频(如荔枝品种图),程序自动调用训练好的 YOLOv5 模型进行推理,并将原图和检测结果分别显示在两个窗口中。
完整程序代码:
import sys
from PySide6.QtWidgets import QMainWindow, QApplication, QFileDialog # 导入 Qt 核心组件
from main_window_ui import Ui_MainWindow # UI 设计文件(由 Qt Designer 生成)
from PySide6.QtGui import QPixmap, QImage # 用于图像显示
import torch # 加载 YOLOv5 模型
from PySide6.QtCore import QTimer # 控制视频帧刷新频率
import cv2 # OpenCV 处理图像和视频# -----------------------------
# 工具函数:将 OpenCV 图像转换为 QImage(供 Qt 显示)
# -----------------------------
def convert2QImage(img):"""将 OpenCV 的 BGR 图像(numpy 数组)转换为 Qt 的 QImage注意:OpenCV 默认是 BGR 格式,需要转成 RGB 才能正确显示"""height, width, channel = img.shape # 获取图像尺寸和通道数return QImage(img, width, height, width * channel, QImage.Format_RGB888)# -----------------------------
# 主窗口类:继承 QMainWindow 和 UI 界面
# -----------------------------
class Mainwindow(QMainWindow, Ui_MainWindow):def __init__(self):super(Mainwindow, self).__init__()self.setupUi(self) # 初始化 UI 界面(从 .ui 文件加载)# 创建定时器,用于视频逐帧处理self.timer = QTimer()self.timer.setInterval(1) # 设置间隔为 1ms(实际帧率由视频源决定)# 加载本地训练好的 YOLOv5 模型(路径需与训练时一致)self.model = torch.hub.load("./", "custom", path="runs/train/exp5/weights/best.pt", source="local")# 绑定按钮事件(信号槽连接)self.bind_slots()# -----------------------------# 图像预测函数:对单张图片进行推理并返回结果图像# -----------------------------def image_pred(self, file_path):"""输入:图片路径(字符串)输出:YOLOv5 推理后的图像(QImage)"""results = self.model(file_path) # 使用模型进行推理(返回结果对象)image = results.render()[0] # render() 返回一个包含原始图+框的 numpy 数组([0] 取第一张图)return convert2QImage(image) # 转换为 QImage 供 Qt 显示# -----------------------------# 打开图片并执行检测# -----------------------------def open_image(self):print("点击了图片检测") # 日志输出,方便调试self.timer.stop() # 停止视频定时器(避免干扰)# 弹出文件选择对话框(默认目录:train 图片文件夹,支持 JPG/PNG/JPEG)file_path = QFileDialog.getOpenFileName(self,caption="选择图片",dir="./datasets/images/train", # 默认打开目录filter="*.jpg;*.png;*.jpeg" # 支持的文件格式)if file_path[0]: # 如果用户选择了文件(file_path 是元组:(路径, 过滤器)file_path = file_path[0] # 提取路径字符串# 执行图像检测并获取结果图像qimage = self.image_pred(file_path)# 显示原始图片到输入区域self.input.setPixmap(QPixmap(file_path))# 显示检测结果到输出区域self.output.setPixmap(QPixmap.fromImage(qimage))# -----------------------------# 视频帧预测函数:逐帧处理视频流# -----------------------------def video_pred(self):"""每次调用都会读取一帧视频,进行推理并更新界面"""ret, frame = self.video.read() # 读取下一帧(ret=True 表示成功读取)if not ret: # 如果视频结束或读取失败self.timer.stop() # 停止定时器self.video.release() # 释放摄像头资源self.video = None # 清空视频对象引用return# 关键修复:OpenCV 默认是 BGR 格式,Qt 需要 RGB,必须转换frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 转换颜色空间# 显示当前帧到输入区域(原始视频画面)self.input.setPixmap(QPixmap.fromImage(convert2QImage(frame)))# 对当前帧进行目标检测results = self.model(frame)image = results.render()[0] # 获取渲染后的图像(带边界框)# 显示检测结果到输出区域self.output.setPixmap(QPixmap.fromImage(convert2QImage(image)))# -----------------------------# 打开视频文件并开始播放# -----------------------------def open_video(self):print("点击视频检测")self.timer.stop() # 停止之前可能正在运行的定时器# 弹出文件选择对话框(只允许选择 MP4 文件)file_path = QFileDialog.getOpenFileName(self,caption="选择视频",dir="./datasets", # 默认打开 datasets 目录filter="*.mp4" # 只允许选择 mp4 视频文件(注意:这里原来是 *.mp4,不是 *.mpg))if file_path[0]: # 用户选择了文件file_path = file_path[0]self.video = cv2.VideoCapture(file_path) # 打开视频文件self.timer.start() # 启动定时器,每隔 1ms 调用一次 video_pred()# -----------------------------# 绑定按钮事件(信号 -> slot)# -----------------------------def bind_slots(self):self.det_image.clicked.connect(self.open_image) # “图片检测”按钮点击触发 open_imageself.pushButton_2.clicked.connect(self.open_video) # “视频检测”按钮点击触发 open_videoself.timer.timeout.connect(self.video_pred) # 定时器超时触发 video_pred(用于视频帧处理)# -----------------------------
# 主程序入口
# -----------------------------
if __name__ == "__main__":app = QApplication(sys.argv) # 创建应用实例window = Mainwindow() # 创建主窗口window.show() # 显示窗口app.exec() # 启动事件循环(等待用户操作)