在 Python GUI 开发领域,PyQt5 凭借强大的功能和跨平台特性成为首选框架之一,结合 OpenCV 的计算机视觉能力,我们可以快速实现具备实用功能的摄像头监控工具。本文将详细拆解如何从零构建一个支持摄像头开关、帧率调节的实时监控界面,帮助新手理解 PyQt5 与 OpenCV 的协同工作原理。

一、代码结构与核心模块解析

1.模块导入

# PyQt5核心模块:构建界面与核心功能
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QFileDialog, QMainWindow, QMessageBox

# UI界面文件:由Qt Designer生成的界面布局类
from untitled import Ui_MainWindow  

# 系统与第三方库
import sys   # 程序运行与退出管理
import cv2    # 摄像头操作与图像处理

untitled.py是通过 Qt Designer 设计界面后,用pyuic5工具转换生成的 UI 文件,包含窗口、按钮、标签等控件的布局定义。

2.主窗口类

核心类PyQtMainEntry继承了QMainWindow(PyQt5 主窗口基类)和Ui_MainWindow(自定义界面类),是整个程序的核心载体:

class PyQtMainEntry(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()  # 初始化父类
        self.setupUi(self)  # 加载Qt Designer设计的界面
        # 摄像头初始化
        self.camera1 = cv2.VideoCapture(0)  # 0表示默认摄像头
        self.is_camera_opened = False  # 摄像头状态标志
        # 定时器初始化:控制画面刷新频率
        self._timer = QtCore.QTimer(self)
        self._timer.timeout.connect(self._queryFrame)  # 绑定定时触发函数
        self.i = 30  # 初始帧率(毫秒级间隔,30ms≈33帧/秒)
        self._timer.setInterval(self.i)
  • cv2.VideoCapture(0):打开电脑默认摄像头(若有多个摄像头,可修改索引为 1、2 等)

  • QTimer:PyQt5 的定时器组件,通过timeout信号绑定画面刷新函数,setInterval设置触发间隔(单位:毫秒)

  • is_camera_opened:布尔标志,用于记录摄像头当前状态,避免重复操作

3.摄像头控制

通过按钮点击触发的槽函数slot1,实现摄像头的开关切换:

def slot1(self):
    self.is_camera_opened = not self.is_camera_opened
    if self.is_camera_opened:
        self.pushButton.setText("关闭")
        self._timer.start()  # 启动定时器,开始刷新画面
    else:
        self.pushButton.setText("打开")
        self._timer.stop()   # 停止定时器,终止画面刷新
  • 点击按钮时反转is_camera_opened状态

  • 开启状态下启动定时器,触发_queryFrame函数读取摄像头画面

  • 关闭状态下停止定时器,同时更新按钮文本提示用户。

4.画面刷新

_queryFrame是实现画面实时显示的核心函数,完成 “读取摄像头画面→格式转换→界面显示” 的全流程:

def _queryFrame(self):
    # 读取摄像头一帧画面
    ret1,self.frame1 = self.camera1.read()
    # 调整画面尺寸为640x480,适配界面显示
    self.frame11 = cv2.resize(self.frame1,(640,480))
    if ret1:  # 确保画面读取成功
        # 格式转换:OpenCV的BGR → PyQt5的RGB
        qimage = cv2.cvtColor(self.frame11,cv2.COLOR_BGR2RGB)
        # 创建QImage对象(PyQt5可识别的图像格式)
        qimage = QtGui.QImage(qimage.data, qimage.shape[1], qimage.shape[0],
        QtGui.QImage.Format_RGB888)
        # 转换为QPixmap,用于在QLabel上显示
        pixmap = QtGui.QPixmap.fromImage(qimage)
        self.label.setPixmap(pixmap)  # 在标签控件中显示画面
  • cv2.read()返回两个值:ret1(是否读取成功)和frame1(画面数据),需先判断ret1避免空数据报错

  • OpenCV 默认图像格式为 BGR,而 PyQt5 的 QImage 使用 RGB 格式,必须通过cv2.COLOR_BGR2RGB转换

  • QLabel是 PyQt5 中用于显示文本 / 图像的控件,需将 QImage 转换为 QPixmap 后才能设置显示。

5.帧率调节

通过两个函数实现画面刷新速度的调节(加速 / 减速):

def jiasu(self):
    # 加速:减少定时器间隔(最小建议保留10ms,避免数值为负)
    if self.i > 10:
        self.i -= 10
        self._timer.setInterval(self.i)

def jisu(self):
    # 减速:增加定时器间隔
    self.i += 10
    self._timer.setInterval(self.i)

6.程序入口

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)  # 创建应用程序实例
    window = PyQtMainEntry()  # 创建主窗口
    window.show()  # 显示窗口
    sys.exit(app.exec_())  # 进入事件循环,保证程序持续运行
  • QApplication(sys.argv):处理命令行参数,是 PyQt5 程序的必要组件

  • app.exec_():启动事件循环,监听用户操作(如按钮点击、定时器触发),程序退出时返回状态码

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐