Python QT5 - Multiprocess OpenCV Webcam & Requests.Get



我是多处理的新手,我正在尝试在 PyQT5 中并行查看我的网络摄像头,同时发出请求.get。 当前的结果是每次发出 get 请求时视频都会卡顿 - 这似乎没什么大不了的,但重要的是每秒以流畅的视频发出此请求。对于更复杂的 Post 请求(最多需要 5 秒才能获得响应(,视频看起来基本上是冻结的。

因此,预期的结果是,我拥有黄油般流畅的视频,而每秒并行发出一个get请求。

我知道这与我根据此链接调用进程的方式有关:

p1 = Process(target=self.start_webcam())
p2 = Process(target=self.start_web_req())

它应该是:

p1 = Process(target=self.start_webcam)
p2 = Process(target=self.start_web_req)

但我收到此错误:

TypeError: cannot pickle 'Ui_MainWindow' object

这是我下面的代码。

您是否有任何想法,建议,答案来确保视频在提出get请求时流畅?

提前谢谢你!

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget,QTableWidgetItem, QDialog
import pandas as pd
from PyQt5.QtCore import QTimer, QSize
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.uic import loadUi
import PIL
from PIL import Image
import requests
import sys
import cv2
import numpy as np
class Ui_MainWindow(QWidget):        
def setupUi(self, MainWindow):
MainWindow.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
MainWindow.setGeometry(0, 30, 800, 480) # x,y,w,h
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
# Camera Label
self.imgLabel = QtWidgets.QLabel(self.centralwidget)
self.imgLabel.setGeometry(QtCore.QRect(0, 0, 600, 480))
self.imgLabel.setFrameShape(QtWidgets.QFrame.Box)
self.imgLabel.setObjectName("imgLabel")
MainWindow.setCentralWidget(self.centralwidget)
# Initiate start_webcam
p1 = Process(target=self.start_webcam())
p1.start()
# Initiate start_web_req
p2 = Process(target=self.start_web_req())
p2.start()
def start_webcam(self):
self.capture=cv2.VideoCapture(0)
self.capture.set(cv2.CAP_PROP_FRAME_WIDTH,600)
self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT,480)
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_frame)
self.timer.start(5)
def update_frame(self):
ret,frame=self.capture.read()
self.cv2_im=frame
self.pil_im = Image.fromarray(self.cv2_im)
self.processedImage=self.cv2_im
self.display_image(1)
def display_image(self, window=1):
qformat = QImage.Format_Indexed8
if len(self.processedImage.shape) == 3:  # rows[0],cols[1],channels[2]
if (self.processedImage.shape[2]) == 4:
qformat = QImage.Format_RGBA8888
else:
qformat = QImage.Format_RGB888
img = QImage(self.processedImage, self.processedImage.shape[1], self.processedImage.shape[0],
self.processedImage.strides[0], qformat)
# BGR > RGB
img = img.rgbSwapped()
if window == 1:
self.imgLabel.setPixmap(QPixmap.fromImage(img))
self.imgLabel.setScaledContents(True)
if window == 2:
self.processedLabel.setPixmap(QPixmap.fromImage(img))
self.processedLabel.setScaledContents(True)

def start_web_req(self):
self.timer = QTimer(self)
self.timer.timeout.connect(self.web_req)
self.timer.start(1000)        
def web_req(self):
res = requests.get('https://www.google.com.au')
print(res)
def appExec(self):
app.exec_()
self.timer.stop()
self.capture.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
app = QApplication.instance()
if app is None:
app = QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(ui.appExec())

在eyllanesc的帮助下,我解决了它。

问题出在 start_webcam(( 和 start_web_req(( 中 - 我在那里有 QTimers 分别调用 update_frame(( 和 web_req((。我删除了那些启动函数并放置了线程。计时器直接在 update_frame(( 和 web_req(( 内部,解决了我断断续续的视频问题。

完整代码如下。

from multiprocessing import Process
import threading
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget,QTableWidgetItem, QDialog
import pandas as pd
from PyQt5.QtCore import QTimer, QSize
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.uic import loadUi
import PIL
from PIL import Image
import requests
import sys
import cv2
import numpy as np
class Ui_MainWindow(QWidget):        
def setupUi(self, MainWindow):
MainWindow.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
MainWindow.setGeometry(0, 30, 800, 480) # x,y,w,h
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
# Camera Label
self.imgLabel = QtWidgets.QLabel(self.centralwidget)
self.imgLabel.setGeometry(QtCore.QRect(0, 0, 600, 480))
self.imgLabel.setFrameShape(QtWidgets.QFrame.Box)
self.imgLabel.setObjectName("imgLabel")
MainWindow.setCentralWidget(self.centralwidget)
self.capture=cv2.VideoCapture(1)
self.capture.set(cv2.CAP_PROP_FRAME_WIDTH,600)
self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT,480)
# Initiate start_webcam
p1 = Process(target=self.update_frame())
p1.start()
# Initiate start_web_req
p2 = Process(target=self.web_req())
p2.start()
def update_frame(self):
self.t1 = threading.Timer(0.01, self.update_frame).start()
ret,frame=self.capture.read()
self.cv2_im=frame
self.pil_im = Image.fromarray(self.cv2_im)
self.processedImage=self.cv2_im
self.display_image(1)
def display_image(self, window=1):
qformat = QImage.Format_Indexed8
if len(self.processedImage.shape) == 3:  # rows[0],cols[1],channels[2]
if (self.processedImage.shape[2]) == 4:
qformat = QImage.Format_RGBA8888
else:
qformat = QImage.Format_RGB888
img = QImage(self.processedImage, self.processedImage.shape[1], self.processedImage.shape[0],
self.processedImage.strides[0], qformat)
# BGR > RGB
img = img.rgbSwapped()
if window == 1:
self.imgLabel.setPixmap(QPixmap.fromImage(img))
self.imgLabel.setScaledContents(True)
if window == 2:
self.processedLabel.setPixmap(QPixmap.fromImage(img))
self.processedLabel.setScaledContents(True)        
def web_req(self):
self.t2 = threading.Timer(1.0, self.web_req).start()
res = requests.get('https://www.google.com.au')
print(res)
def appExec(self):
app.exec_()
self.t1 = None
self.t2 = None
self.capture.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
app = QApplication.instance()
if app is None:
app = QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(ui.appExec())

相关内容

  • 没有找到相关文章

最新更新