1、准备界面
界面和前面的基本一致,为了不犯错这里还是展示了一下。
2、编写函数
2.1、初始化
初始化部分主要是,一是初始化信号槽,二是初始化视频捕获函数和Qt定时器,还有摄像头编号。
self.cap = cv2.VideoCapture()
self.timer = QtCore.QTimer(self)
#摄像头编号,默认为0,电脑内置摄像头
self.camera_id = 0
self.init_slot()
绑定信号槽
def init_slot(self):
#开始绑定信号和槽
self.ui.open.clicked.connect(self.open_camera)
self.timer.timeout.connect(self.show_camera)
self.ui.clear.clicked.connect(self.clear)
pass
2.2、打开摄像头函数
详细内容看注释。
def open_camera(self):
#摄像头未打开,打开摄像头,定时器开始倒计时
if self.timer.isActive() == False:
flag = self.cap.open(self.camera_id,cv2.CAP_DSHOW)
#读取失败报错
if flag == False:
QMessageBox.warning(self,'warning','请检查摄像头是否连接正确',
QMessageBox.Ok)
#否则显示
else:
self.timer.start(30)
self.ui.open.setText("关闭摄像头")
#摄像头打开,计时器停止,释放资源
else:
self.timer.stop()
self.cap.release()
self.clear()
self.ui.open.setText("打开摄像头")
pass
2.3、摄像头数据展示函数
def show_camera(self):
ret,frame = self.cap.read()
if ret:
#读取成功
frame = cv2.flip(frame,1)
self.show_img(frame,self.ui.label)
#否则报错
else:
QMessageBox.information(self,"警告","摄像头读取错误",QMessageBox.Ok)
2.4、图片显示
这个函数基本没有变化,因为视频的每一帧都可以看作一张图片。
def show_img(self,im,label):
try:
#获取高和宽
ih,iw ,_ = im.shape
#获取标签的长和高
w = label.geometry().width()
h = label.geometry().height()
#上述的目的是为了保持原始的纵横比
if iw/w >ih/h:
scal = w/iw
nw = w
nh = int(scal * ih)
im_new = cv2.resize(im,(nw,nh))
else:
scal = w/iw
nw = int(scal*iw)
nh = h
im_new = cv2.resize(im,(nw,nh))
frame = cv2.cvtColor(im_new,cv2.COLOR_BGR2RGB)
im = QImage(frame.data,frame.shape[1],frame.shape[0],frame.shape[2] * frame.shape[1],
QImage.Format_RGB888)
label.setPixmap(QPixmap.fromImage(im))
except Exception as e:
print(repr(e))
2.5、清空
清空图片并释放资源。
def clear(self):
self.ui.label.clear()
self.timer.stop()
self.cap.release()
self.ui.open.setText("打开摄像头")
pass
2.6、完整代码
from PySide6.QtWidgets import QApplication,QMainWindow,QMessageBox
from PySide6 import QtWidgets,QtCore
from PySide6.QtGui import QImage,QPixmap
from ui.Ui_mainwin import Ui_MainWindow
import sys
import cv2
import warnings
warnings.filterwarnings('ignore')
class MainWin(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.show()
self.cap = cv2.VideoCapture()
self.timer = QtCore.QTimer(self)
#摄像头编号,默认为0,电脑内置摄像头
self.camera_id = 0
self.init_slot()
def init_slot(self):
#开始绑定信号和槽
self.ui.open.clicked.connect(self.open_camera)
self.timer.timeout.connect(self.show_camera)
self.ui.clear.clicked.connect(self.clear)
pass
def open_camera(self):
#摄像头未打开,打开摄像头,定时器开始倒计时
if self.timer.isActive() == False:
flag = self.cap.open(self.camera_id,cv2.CAP_DSHOW)
#读取失败报错
if flag == False:
QMessageBox.warning(self,'warning','请检查摄像头是否连接正确',
QMessageBox.Ok)
#否则显示
else:
self.timer.start(30)
self.ui.open.setText("关闭摄像头")
#摄像头打开,计时器停止,释放资源
else:
self.timer.stop()
self.cap.release()
self.clear()
self.ui.open.setText("打开摄像头")
pass
def show_camera(self):
ret,frame = self.cap.read()
if ret:
#读取成功
frame = cv2.flip(frame,1)
self.show_img(frame,self.ui.label)
#否则报错
else:
QMessageBox.information(self,"警告","摄像头读取错误",QMessageBox.Ok)
def show_img(self,im,label):
try:
#获取高和宽
ih,iw ,_ = im.shape
#获取标签的长和高
w = label.geometry().width()
h = label.geometry().height()
#上述的目的是为了保持原始的纵横比
if iw/w >ih/h:
scal = w/iw
nw = w
nh = int(scal * ih)
im_new = cv2.resize(im,(nw,nh))
else:
scal = w/iw
nw = int(scal*iw)
nh = h
im_new = cv2.resize(im,(nw,nh))
frame = cv2.cvtColor(im_new,cv2.COLOR_BGR2RGB)
im = QImage(frame.data,frame.shape[1],frame.shape[0],frame.shape[2] * frame.shape[1],
QImage.Format_RGB888)
label.setPixmap(QPixmap.fromImage(im))
except Exception as e:
print(repr(e))
def clear(self):
self.ui.label.clear()
self.timer.stop()
self.cap.release()
self.ui.open.setText("打开摄像头")
pass
if __name__=='__main__':
app = QApplication(sys.argv)
window = MainWin()
sys.exit(app.exec())
3、视频教程
4、相关内容
【PySide6】PySide6安装及VSCode配置PySide6环境
【PySide6】登录和注册信号绑定以及代码实现
【PySide6】实现登录界面向主界面跳转
【PySide6】在QLabel上显示一张图片
【PySide6】QLabel显示视频流