建立界面
使用qtdesigner设计一个基本的播放视频界面
使用PYUIC生成对应代码文件,如下:
# -*- 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", "结束"))
主函数
核心需要实现的功能就是按下按钮打开摄像头进行读取,然后关闭摄像头
通过QTimer实现
这样可以比较简单的实现,就是timer计时到了就新读取一帧
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_()
加上对于图像的处理
比如我这里加上对于姿态识别,好像不用到多线程也行,就直接在图片显示函数里,进行图片的推理就行了,没什么太大的影响。
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_()