简体   繁体   English

Python QT5 - 多进程 OpenCV 网络摄像头和请求.Get

[英]Python QT5 - Multiprocess OpenCV Webcam & Requests.Get

I'm new to multiprocessing and I'm trying to view my webcam in parallel to making a requests.get, in PyQT5.我是多处理的新手,我正在尝试在 PyQT5 中同时查看我的网络摄像头并发出 requests.get。 The current result is the video stutters each time the get request is made - it doesn't seem like a big deal but it's important that this request is made every second with smooth video.当前的结果是每次发出 get 请求时视频都会卡顿 - 这似乎没什么大不了的,但重要的是每秒都会发出流畅的视频。 For more complex Post requests that take up to 5 seconds for a response, the video looks essentially frozen.对于需要最多 5 秒响应的更复杂的 Post 请求,视频看起来基本上是冻结的。

So the expected result is that I have buttery smooth video while a get request is being made in parallel every second.所以预期的结果是我有黄油般流畅的视频,而每秒都在并行发出一个获取请求。

I know this has something to do with the way I'm calling my processes as per this link :我知道这与我按照此链接调用流程的方式有关:

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

it should be:它应该是:

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

but I get this error:但我收到此错误:

TypeError: cannot pickle 'Ui_MainWindow' object

This is my code below.这是我下面的代码。

Do you have any ideas, advice, answers to making sure the video is smooth whilst making a get request?你有什么想法、建议和答案来确保视频流畅,同时提出获取请求吗?

Thank you in advanced!提前谢谢你!

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())

With help from eyllanesc, I solved it.在 eyllanesc 的帮助下,我解决了它。

The problem was in start_webcam() and start_web_req() - I had QTimers in there to call update_frame() and web_req() respectively.问题出在 start_webcam() 和 start_web_req() - 我有 QTimers 分别调用 update_frame() 和 web_req()。 I removed those start functions and put threading.Timer directly inside update_frame() and web_req() which solved my choppy video problem.我删除了那些启动函数并将 threading.Timer 直接放在 update_frame() 和 web_req() 中,这解决了我的视频断断续续的问题。

Full code below.完整代码如下。

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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM