为了账号安全,请及时绑定邮箱和手机立即绑定

pycapture2 视频捕获和线程

pycapture2 视频捕获和线程

POPMUISE 2021-07-25 20:47:04
我已经使用 pycapture2 和 PyQt5 制作了一个视频捕获程序。它似乎有效,但控制台显示错误:QObject::killTimer: Timers cannot be stopped from another threadQBasicTimer::stop: Failed. Possibly trying to stop from a different thread我通过使用 QTimer 解决了这个问题,但速度很慢(2 帧/秒)。我想使用QThread,如何解决这个问题?# -*- coding: utf-8 -*-from PyQt5 import QtCore, QtGui, QtWidgetsfrom PyQt5.QtCore import QThreadimport cv2import PyCapture2import numpy as npclass Ui_MainWindow(object):    def __init__(self, parent=None):        MainWindow.setObjectName("MainWindow")        MainWindow.resize(600, 400)        self.centralwidget = QtWidgets.QWidget(MainWindow)        self.centralwidget.setObjectName("centralwidget")        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)        self.graphicsView.setGeometry(QtCore.QRect(150, 20, 400, 300))        self.graphicsView.setObjectName("graphicsView")        MainWindow.setCentralWidget(self.centralwidget)        self.Thread = CapThread()        self.Thread.start()     class CapThread(QThread):    def __init__(self):        QThread.__init__(self)    def run(QMainWindow):        bus = PyCapture2.BusManager()        uid = bus.getCameraFromIndex(0)        c = PyCapture2.Camera()        c.connect(uid)                 while True:            c.startCapture()            img = c.retrieveBuffer()            c.stopCapture()            cv_img1 = np.array(img.getData(), dtype="uint8").reshape((img.getRows(), img.getCols()));            cv_img = cv2.cvtColor(cv_img1, cv2.COLOR_BAYER_BG2BGR)            cv_img = cv2.resize(cv_img,(380,270))            height, width, dim = cv_img.shape            bytesPerLine = dim * width            image = QtGui.QImage(cv_img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)            item = QtWidgets.QGraphicsPixmapItem(QtGui.QPixmap.fromImage(image))            scene = QtWidgets.QGraphicsScene()            scene.addItem(item)            ui.graphicsView.setScene(scene)
查看完整描述

1 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

您的代码没有逻辑,例如因为run()将 QMainWinodw 作为参数,理论上您每次获取图像时都会尝试创建一个场景,这是不正确的,因为您的程序将不必要地消耗内存,解决方案是重用项目。最后但并非最不重要的是,GUI 不能在另一个线程中更新,Qt 指出它必须通过信号发送到 GUI 线程并在那里进行更新:


# -*- coding: utf-8 -*-

from PyQt5 import QtCore, QtGui, QtWidgets

import cv2

import PyCapture2

import numpy as np



class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, parent=None):

        super(MainWindow, self).__init__(parent)

        self.resize(600, 400)

        scene = QtWidgets.QGraphicsScene()

        graphicsView = QtWidgets.QGraphicsView(scene)

        self.setCentralWidget(graphicsView)

        self._item = QtWidgets.QGraphicsPixmapItem()

        scene.addItem(self._item)

        thread = CapThread(self)

        thread.imageChanged.connect(self.on_imageChanged)

        thread.start()     


    @QtCore.pyqtSlot(QtGui.QImage)

    def on_imageChanged(self, image):

        pixmap = QtGui.QPixmap.fromImage(image)

        self._item.setPixmap(pixmap)



class CapThread(QtCore.QThread):

    imageChanged = QtCore.pyqtSignal(QtGui.QImage)


    def run(self):

        bus = PyCapture2.BusManager()

        uid = bus.getCameraFromIndex(0)

        c = PyCapture2.Camera()

        c.connect(uid)        


        while True:

            c.startCapture()

            img = c.retrieveBuffer()

            c.stopCapture()


            cv_img1 = np.array(img.getData(), dtype="uint8").reshape((img.getRows(), img.getCols()))

            cv_img = cv2.cvtColor(cv_img1, cv2.COLOR_BAYER_BG2BGR)

            cv_img = cv2.resize(cv_img, (380,270))


            height, width, dim = cv_img.shape

            bytesPerLine = dim * width

            image = QtGui.QImage(cv_img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)

            self.imageChanged.emit(image)



if __name__ == "__main__":

    import sys

    app = QtWidgets.QApplication(sys.argv)

    w = MainWindow()

    w.show()

    sys.exit(app.exec_())


查看完整回答
反对 回复 2021-08-03
  • 1 回答
  • 0 关注
  • 385 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信