ZH ·
🌏 English 使用 PySide6 在 Python 中实现 OpenCV 视频流显示的最简指南
深度学习算法(尤其是图像处理领域)的应用,通常需要直观的可视化界面。虽然 OpenCV 自带的 imshow 方法简单易用,但在扩展性和可维护性方面存在明显不足。
Qt 是一个成熟的 UI 框架,起源于 C/C++,现已完美支持 Python。在 Python 生态中,PyQt 是社区维护的版本,而 PySide 则是 Qt 官方提供的版本。本文将采用官方的 PySide6 来构建界面。
通常,图像数据由 OpenCV 的 Mat 格式封装。我们的工作流程如下:通过摄像头或视频文件捕获原始帧,将其解码为 OpenCV Mat,传给算法进行处理,最后由 Qt 负责在界面上显示结果。
导入必要的库
import sys # PySide6所需
from PySide6 import QtWidgets
from PySide6 import QtGui, QtCore
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import QFileDialog, QMainWindow, QMessageBox
from generated_files.uic.mainwindow import Ui_MainWindow
import cv2
import numpy as np # cv2 mat由numpy包装
创建主窗口类
从 Qt QMainWindow 继承并创建主窗口类:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
编写主程序入口
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
运行上述代码,即可看到一个空白窗口。
使用 Qt Designer 设计界面
- 使用 Designer 创建 UI 文件:

- 在窗口中添加 Label 控件:

- 清除 Label 中的默认文本,并将控件的对象名称修改为
image_label:
添加数据捕获逻辑
我们使用 OpenCV 打开摄像头,并通过定时器(QTimer)周期性地获取图像。定义 display_video_stream 方法读取相机画面,并将其连接到定时器,每 30 毫秒触发一次。
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.timer = QTimer()
self.timer.timeout.connect(self.display_video_stream)
self.cap = cv2.VideoCapture(0) # 调用默认相机设备
self.timer.start(30) # 每30ms触发一次
def display_video_stream(self):
'''从USB相机显示视频流'''
ret, frame = self.cap.read() # 获取读取状态和帧数据
if ret:
self.display(frame)
图像格式转换
OpenCV 获取的图像数据需要转换为 Qt 可识别的 QImage 格式,才能在 QLabel 上正确显示。
def display(self, frame):
'''将OpenCV帧显示在Qt控件上'''
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = QImage(frame, frame.shape[1], frame.shape[0],
frame.strides[0], QImage.Format_RGB888)
self.ui.image_label.setPixmap(QPixmap.fromImage(image))
完整代码
import sys
from PySide6 import QtWidgets
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import QMainWindow
from generated_files.uic.mainwindow import Ui_MainWindow
import cv2
import numpy as np
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.timer = QTimer()
self.timer.timeout.connect(self.display_video_stream)
self.cap = cv2.VideoCapture(0)
self.timer.start(30)
def display(self, frame):
'''将OpenCV帧显示在Qt控件上'''
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = QImage(frame, frame.shape[1], frame.shape[0],
frame.strides[0], QImage.Format_RGB888)
self.ui.image_label.setPixmap(QPixmap.fromImage(image))
def display_video_stream(self):
'''从USB相机显示视频流'''
ret, frame = self.cap.read()
if ret:
self.display(frame)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
实现过程非常简单。😊
完整项目代码请参考 GitHub 仓库:https://github.com/BigBookPlus/PythonQtWithOpenCV.git。