PyQt5学习笔记--摄像头实时视频展示、多线程处理、视频编解码
创始人
2024-02-20 15:13:41

目录

1--前言

2--基于Qt Designer设计ui文件

3--视频的编解码操作

4--完整代码

5--结果展示

6--存在的问题

7--参考


1--前言

① 创建两个线程,主线程为ui线程,子线程用于读取摄像头视频,将处理后的图像帧数据(处理操作可以人为添加)返回到主线程进行可视化;

② 子线程向主线程传递视频帧数据集涉及图像的编码操作,主线程接收子线程的数据时涉及图像的解码操作;

2--基于Qt Designer设计ui文件

3--视频的编解码操作

① 编码操作:

# 图像编码函数
def Encoder(self, img):retval, buffer = cv2.imencode('.jpg', img)jpg_as_bytes = base64.b64encode(buffer)jpg_as_str = jpg_as_bytes.decode('ascii')json_object = json.dumps({'img_str': jpg_as_str})return json_object

注:img 为 opencv 读取图像的格式(默认uint8, BGR);  编码后的数据 json_object 可以直接通过signal.emit(json_object) 进行发送。

② 解码操作:

# 图片解码函数
def Decoder(self, img_json):jpg_as_str = json.loads(img_json)['img_str']jpg_as_bytes = jpg_as_str.encode('ascii')jpg_original = base64.b64decode(jpg_as_bytes)jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)img = cv2.imdecode(jpg_as_np, flags=1)return img

注:输入的 img_json 与编码函数生成的 json_object 格式相同;解码生成的 img 可以通过cv2.imshow("window_name", img) cv2.waitKey(0)进行显示。

4--完整代码

import sys
import timeimport json
import cv2
import base64
import numpy as npfrom PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5 import uic# 子线程1:打开摄像头,返回当前帧图像到主线程
class Open_Cam(QThread):Open_Cam_signal = pyqtSignal(str)  # 接受来自主线程的信号def __init__(self, main_signal):super().__init__()# 信号绑定槽函数self.Open_Cam_signal.connect(self.Open_Cam)self.opencam_complete_signal = main_signal  # 返回主线程的信号def Open_Cam(self, Cam):# 将json字符串转换Cam_index = json.loads(Cam)  # 0cap = cv2.VideoCapture(Cam_index)fps = cap.get(cv2.CAP_PROP_FPS)while True:ret, self.frame = cap.read()'''这里你可以添加对图像进行处理的操作'''json_object = self.Encoder(self.frame)  # 对图片进行编码self.opencam_complete_signal.emit(json_object)  # 发送编码到主线程cv2.waitKey(int((1 / fps) * 1000))# 图像编码函数def Encoder(self, img):retval, buffer = cv2.imencode('.jpg', img)jpg_as_bytes = base64.b64encode(buffer)jpg_as_str = jpg_as_bytes.decode('ascii')json_object = json.dumps({'img_str': jpg_as_str})return json_objectdef run(self):while True:  # 让子线程一直运行,等待主线程(ui线程)下发的任务print("子线程1正在等待执行....")time.sleep(2)class MyWindow(QWidget):opencam_complete_signal = pyqtSignal(str)  # 子线程返回摄像头图像到主线程的信号def __init__(self):super().__init__()self.init_ui()self.cam_idx = 0def init_ui(self):self.ui = uic.loadUi("./Cam.ui")  # 加载由Qt Designer设计的ui文件# 加载控件self.open_cam_btn = self.ui.pushButtonself.cam_view = self.ui.graphicsView# 绑定槽函数self.open_cam_btn.clicked.connect(self.open_cam)self.opencam_complete_signal.connect(self.view_cam)self.Opencam_Thread = Open_Cam(self.opencam_complete_signal)  # 子线程1self.Opencam_Thread.start()  # 子线程1运行,等待下发任务def open_cam(self):  # 给子线程1发送打开摄像头的信号self.Opencam_Thread.Open_Cam_signal.emit(json.dumps(self.cam_idx))def view_cam(self, img_json):  # 接受来自子线程1返回的摄像头数据self.img_json = img_jsonimg = self.Decoder(self.img_json)frame = QImage(img, img.shape[1], img.shape[0], img.strides[0], QImage.Format_RGB888).rgbSwapped()pix = QPixmap.fromImage(frame)item = QGraphicsPixmapItem(pix)  # 创建像素图元scene = QGraphicsScene()  # 创建场景scene.addItem(item)self.cam_view.setScene(scene)  # 将场景添加至视图self.cam_view.fitInView(item)  # 自适应大小# 图片解码函数def Decoder(self, img_json):jpg_as_str = json.loads(img_json)['img_str']jpg_as_bytes = jpg_as_str.encode('ascii')jpg_original = base64.b64decode(jpg_as_bytes)jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)img = cv2.imdecode(jpg_as_np, flags=1)return imgif __name__ == '__main__':app = QApplication(sys.argv)  # 创建对象w = MyWindow()# 展示窗口w.ui.show()# 程序进行循环等待状态app.exec_()

5--结果展示

6--存在的问题

上述代码存在当关闭ui窗口时,子线程不会自动结束的问题,后续将补充如何解决这个问题的方案。

7--参考

使用python将opencv中读取的numpy矩阵json序列化

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...