PYQT reads the camera display video (Qtimer way)

build interface

Use qtdesigner to design a basic playback video interface
insert image description here
Use PYUIC to generate the corresponding code file, as follows:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Test_UI.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(883, 637)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton_start = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_start.setGeometry(QtCore.QRect(160, 480, 141, 51))
        self.pushButton_start.setObjectName("pushButton_start")
        self.label_show = QtWidgets.QLabel(self.centralwidget)
        self.label_show.setGeometry(QtCore.QRect(150, 60, 541, 371))
        self.label_show.setStyleSheet("background-color: rgb(0, 0, 0);")
        self.label_show.setText("")
        self.label_show.setObjectName("label_show")
        self.pushButton_end = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_end.setGeometry(QtCore.QRect(550, 480, 141, 51))
        self.pushButton_end.setObjectName("pushButton_end")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 883, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton_start.setText(_translate("MainWindow", "开始"))
        self.pushButton_end.setText(_translate("MainWindow", "结束"))

main function

The core function that needs to be realized is to press the button to turn on the camera for reading, and then turn off the camera

Realized by QTimer

This can be implemented relatively simply, that is, when the timer expires, a new frame will be read

from PyQt5 import QtWidgets,QtCore
from PyQt5.QtWidgets import QMainWindow,QApplication
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
import cv2

import Test_UI

import threading


# 注意:ui界面文件是个MainWindow,那么MyApp就必须继承 QMainWindow
# 类似的,若ui界面文件是个对话框,那么MyApp就必须继承 QDialog
class Test_window(QtWidgets.QMainWindow,Test_UI.Ui_MainWindow):
    def __init__(self,parent=None):
        super(Test_window,self).__init__(parent)
        self.setupUi(self)
        self.CAM_NUM = 0
        self.cap = cv2.VideoCapture()

        self.timer = QTimer()
        self.timer.timeout.connect(self.show_pic)

        # 文件选择按钮
        self.pushButton_start.clicked.connect(self.open_camera)
        self.pushButton_end.clicked.connect(self.close_camera)

        self.pushButton_start.setEnabled(True)
        # 初始状态不能关闭摄像头
        self.pushButton_end.setEnabled(False)

    def open_camera(self):
        # 检测该设备是否能打开
        flag = self.cap.open(self.CAM_NUM)
        print(flag)
        if flag is False:
            QMessageBox.information(self, "警告", "该设备未正常连接", QMessageBox.Ok)
        else:
            # 幕布可以播放
            self.label_show.setEnabled(True)
            # 打开摄像头按钮不能点击
            self.pushButton_start.setEnabled(False)
            # 关闭摄像头按钮可以点击
            self.pushButton_end.setEnabled(True)
            self.timer.start()
            print("beginning!")

    # 关闭相机
    def close_camera(self):
        self.cap.release()
        self.pushButton_start.setEnabled(True)
        self.pushButton_end.setEnabled(False)
        self.timer.stop()

    #   显示视频图像
    def show_pic(self):
        ret, img = self.cap.read()
        if ret:
            cur_frame = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            # 视频流的长和宽
            height, width = cur_frame.shape[:2]
            pixmap = QImage(cur_frame.data, width, height, QImage.Format_RGB888)
            pixmap = QPixmap.fromImage(pixmap)
            # # 获取是视频流和label窗口的长宽比值的最大值,适应label窗口播放,不然显示不全
            # ratio = max(width / self.label.width(), height / self.label.height())
            # pixmap.setDevicePixelRatio(ratio)
            # print("here")
            # # 视频流置于label中间部分播放
            # self.label_show.setAlignment(Qt.AlignCenter)
            self.label_show.setPixmap(pixmap)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mytest = Test_window()
    mytest.show()
    app.exec_()

plus image processing

For example, I add here that for gesture recognition, it seems that multi-threading is not required, and it is enough to perform image reasoning directly in the image display function, and it does not have much impact.

from PyQt5 import QtWidgets,QtCore
from PyQt5.QtWidgets import QMainWindow,QApplication
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
import cv2

import Test_UI

import threading

import Gesture_Model


# 注意:ui界面文件是个MainWindow,那么MyApp就必须继承 QMainWindow
# 类似的,若ui界面文件是个对话框,那么MyApp就必须继承 QDialog
class Test_window(QtWidgets.QMainWindow,Test_UI.Ui_MainWindow):
    def __init__(self,parent=None):
        super(Test_window,self).__init__(parent)
        self.setupUi(self)
        self.CAM_NUM = 0
        self.cap = cv2.VideoCapture()

        self.geture_model = Gesture_Model.Gesture()

        self.timer = QTimer()
        self.timer.timeout.connect(self.show_pic)

        # 文件选择按钮
        self.pushButton_start.clicked.connect(self.open_camera)
        self.pushButton_end.clicked.connect(self.close_camera)

        self.pushButton_start.setEnabled(True)
        # 初始状态不能关闭摄像头
        self.pushButton_end.setEnabled(False)

    def open_camera(self):
        # 检测该设备是否能打开
        # flag = self.cap.open(self.CAM_NUM)
        flag = self.cap.open('./test/002.mp4')
        print(flag)
        if flag is False:
            QMessageBox.information(self, "警告", "该设备未正常连接", QMessageBox.Ok)
        else:
            # 幕布可以播放
            self.label_show.setEnabled(True)
            # 打开摄像头按钮不能点击
            self.pushButton_start.setEnabled(False)
            # 关闭摄像头按钮可以点击
            self.pushButton_end.setEnabled(True)
            self.timer.start()
            print("beginning!")

    # 关闭相机
    def close_camera(self):
        self.cap.release()
        self.pushButton_start.setEnabled(True)
        self.pushButton_end.setEnabled(False)
        self.timer.stop()

    #   显示视频图像
    def show_pic(self):
        ret, img = self.cap.read()
        if ret:
            cur_frame = self.geture_model.pred(img)
            cur_frame = cv2.cvtColor(cur_frame, cv2.COLOR_BGR2RGB)
            # 视频流的长和宽
            height, width = cur_frame.shape[:2]
            pixmap = QImage(cur_frame.data, width, height, QImage.Format_RGB888)
            pixmap = QPixmap.fromImage(pixmap).scaled(self.label_show.width(), self.label_show.height())
            self.label_show.setPixmap(pixmap)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mytest = Test_window()
    mytest.show()
    app.exec_()

Guess you like

Origin blog.csdn.net/qin_liang/article/details/131824972