首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当试图显示opencv视频流时,Pyqt崩溃

当试图显示opencv视频流时,Pyqt崩溃
EN

Stack Overflow用户
提问于 2019-03-22 19:33:22
回答 1查看 1K关注 0票数 0

我尝试了this答案中的代码,过了一段时间(2-10秒),它出现了Process finished with exit code -1073740771 (0xC000041D)错误。有时还有0xC0000005。如果我试图拖动窗口,它就会立即崩溃。然而,当我将time.sleep(0.1)放在run中时,它工作得很好。如果我用小于0.1的睡眠时间,它会再次崩溃。

代码语言:javascript
复制
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QLabel,QMessageBox
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot, Qt
import cv2
import sys
import time

class CamThread(QThread):
    changemap = pyqtSignal('QImage')

    def run(self):
        cap = cv2.VideoCapture(0)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

        while True:
            ret, img_rgb = cap.read()
            if ret:
                self.rgb = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2RGB)
                self.convert = QImage(self.rgb.data, self.rgb.shape[1], self.rgb.shape[0], QImage.Format_RGB888)
                self.p = self.convert.scaled(640, 480, Qt.KeepAspectRatio)
                self.changemap.emit(self.p)
                #time.sleep(0.1)


class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'webcam'

        self.initUI()

    @pyqtSlot('QImage')
    def setImage(self, image):
        self.label.setPixmap(QPixmap.fromImage(image))

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(100, 100, 640, 480)
        self.resize(640, 480)
        self.label = QLabel(self)
        self.label.resize(640, 480)
        thr = CamThread(self)
        thr.changemap.connect(self.setImage)
        thr.start()

app = QApplication(sys.argv)
win = App()
#win.setAttribute(Qt.WA_DeleteOnClose, True)
win.show()
app.exit(app.exec_())

我认为问题出在信号/插槽的某个地方,但没有找到任何相关的东西。

  • Windows 10
  • Python - 3.7
  • Pyqt - 5.12
  • OpenCV - 3.4.5.20
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-23 18:41:25

修正了使用QMutexQWaitCondition来防止主线程已经更新时的更新调用。很明显,问题就在这里面。eyllanesc,正如你所看到的,我是新来的,我应该用原来的线程来回答吗?

代码语言:javascript
复制
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QLabel, QMessageBox
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot, Qt, QMutex, QWaitCondition
import cv2
import sys
import time


class CamThread(QThread):
    changemap = pyqtSignal('QImage')

    def __init__(self, mutex, condition):
        super().__init__()
        self.mutex = mutex
        self.condition = condition

    def run(self):
        cap = cv2.VideoCapture(0)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
        while True:
            try:
                ret, img_rgb = cap.read()
                if ret:
                    rgb = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2RGB)

                    #any other image processing here

                    convert = QImage(rgb.data, rgb.shape[1], rgb.shape[0], QImage.Format_RGB888)
                    p = convert.scaled(640, 480, Qt.KeepAspectRatio)
                    self.changemap.emit(p)
                    self.condition.wait(self.mutex)

            except:
                print('error')


class App(QWidget):
    time = 0

    def __init__(self):
        super().__init__()
        self.title = 'webcam'
        self.mutex = QMutex()
        self.condition = QWaitCondition()
        self.initUI()

    @pyqtSlot('QImage')
    def setImage(self, image):
        self.mutex.lock()
        try:
            self.label.setPixmap(QPixmap.fromImage(image))
        finally:
            self.mutex.unlock()
            self.condition.wakeAll()

    def initUI(self):
        self.mutex.lock()
        self.setWindowTitle(self.title)
        self.setGeometry(100, 100, 640, 480)
        self.resize(640, 480)
        self.label = QLabel(self)
        self.label.resize(640, 480)
        self.thr = CamThread(mutex = self.mutex,condition=self.condition)
        self.thr.changemap.connect(self.setImage)
        self.thr.start()


app = QApplication(sys.argv)
win = App()
win.show()
app.exit(app.exec_())

注:在本例中,您仍然需要正确地停止线程和关闭摄像机连接。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55306673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档