目录
[5.1 Pyside6](#5.1 Pyside6)
[5.2 界面设计](#5.2 界面设计)
[5.3 程序设计](#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 模型进行推理,并将原图和检测结果分别显示在两个窗口中。


完整程序代码:
python
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_image
self.pushButton_2.clicked.connect(self.open_video) # "视频检测"按钮点击触发 open_video
self.timer.timeout.connect(self.video_pred) # 定时器超时触发 video_pred(用于视频帧处理)
# -----------------------------
# 主程序入口
# -----------------------------
if __name__ == "__main__":
app = QApplication(sys.argv) # 创建应用实例
window = Mainwindow() # 创建主窗口
window.show() # 显示窗口
app.exec() # 启动事件循环(等待用户操作)
运行结果:
