目录
① 创建两个线程,主线程为ui线程,子线程用于读取摄像头视频,将处理后的图像帧数据(处理操作可以人为添加)返回到主线程进行可视化;
② 子线程向主线程传递视频帧数据集涉及图像的编码操作,主线程接收子线程的数据时涉及图像的解码操作;

① 编码操作:
# 图像编码函数
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)进行显示。
import sys
import time
import json
import cv2
import base64
import numpy as np
from 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) # 0
cap = 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_object
def 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 = 0
def init_ui(self):
self.ui = uic.loadUi("./Cam.ui") # 加载由Qt Designer设计的ui文件
# 加载控件
self.open_cam_btn = self.ui.pushButton
self.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) # 子线程1
self.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_json
img = 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 img
if __name__ == '__main__':
app = QApplication(sys.argv) # 创建对象
w = MyWindow()
# 展示窗口
w.ui.show()
# 程序进行循环等待状态
app.exec_()

上述代码存在当关闭ui窗口时,子线程不会自动结束的问题,后续将补充如何解决这个问题的方案。
1130补充:上述问题的原因在于我把读视频的while true循环写在了run函数外,为了避免这个问题可以采用定时器读取视频流的方法,可以参考博主的一个学习笔记。
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
我是ruby的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or