【问题标题】:OpenCV Video Capture with PyQt4使用 PyQt4 进行 OpenCV 视频捕获
【发布时间】:2014-01-16 18:26:59
【问题描述】:

我一直在尝试使用 PyQt4 GUI 和 OpenCV 捕获视频。我创建了一些按钮,如“开始”、“结束”等来控制捕获。开始很好,但我无法停止捕获。要停止捕获,我需要在下面的 startCapture() 函数中打破 while 循环,但我无法实现。

目前,endCapture() 会破坏窗口,但 startCapture while 循环 只是创建它并继续捕获。唯一的选择就是打破这个循环。

下面是我使用的代码:

import cv2
import numpy as np
from PyQt4 import QtGui, QtCore

def startCapture(cap):
    print "pressed start"
    while(True):
        ret, frame = cap.read()
        cv2.imshow("Capture", frame)
        cv2.waitKey(5)
    cv2.destroyAllWindows() 

def endCapture(cap):
    print "pressed End"
    cv2.destroyAllWindows()

def quitCapture(cap):
    print "pressed Quit"
    cv2.destroyAllWindows()
    cap.release()
    QtCore.QCoreApplication.quit()

class Window(QtGui.QWidget):
    def __init__(self):

        c = cv2.VideoCapture(0)

        QtGui.QWidget.__init__(self)
        self.setWindowTitle('Control Panel')

        self.start_button = QtGui.QPushButton('Start',self)
        self.start_button.clicked.connect(lambda : startCapture(c, True))

        self.end_button = QtGui.QPushButton('End',self)
        self.end_button.clicked.connect(lambda : endCapture(c))

        self.quit_button = QtGui.QPushButton('Quit',self)
        self.quit_button.clicked.connect(lambda : quit(c))

        vbox = QtGui.QVBoxLayout(self)
        vbox.addWidget(self.start_button)
        vbox.addWidget(self.end_button)
        vbox.addWidget(self.quit_button)

        self.setLayout(vbox)
        self.setGeometry(100,100,200,200)
        self.show()

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    sys.exit(app.exec_())

谁能建议如何打破这个循环并退出捕获?

【问题讨论】:

  • 创建某种在 startCapture 循环中检查的类或全局变量。并在调用 endCapture 时更改
  • @Abid,它有效吗?我有同样的问题。您是如何解决这个问题的?

标签: python opencv user-interface pyqt pyqt4


【解决方案1】:
class Capture():
    def __init__(self):
        self.capturing = False
        self.c = cv2.VideoCapture(0)

    def startCapture(self):
        print "pressed start"
        self.capturing = True
        cap = self.c
        while(self.capturing):
            ret, frame = cap.read()
            cv2.imshow("Capture", frame)
            cv2.waitKey(5)
        cv2.destroyAllWindows()

    def endCapture(self):
        print "pressed End"
        self.capturing = False
        # cv2.destroyAllWindows()

    def quitCapture(self):
        print "pressed Quit"
        cap = self.c
        cv2.destroyAllWindows()
        cap.release()
        QtCore.QCoreApplication.quit()

在窗口中:

self.capture = Capture()
self.start_button = QtGui.QPushButton('Start',self)
self.start_button.clicked.connect(self.capture.startCapture)

self.end_button = QtGui.QPushButton('End',self)
self.end_button.clicked.connect(self.capture.endCapture)

self.quit_button = QtGui.QPushButton('Quit',self)
self.quit_button.clicked.connect(self.capture.quitCapture)

【讨论】:

  • quitCapture(self) 类中存在一个错误:在 quit 期间未停止捕获新帧导致错误,请在 cap = self.c 后添加 self.capturing = False
  • 我运行这段代码,按“开始”按钮“结束”和“退出”后不起作用。
【解决方案2】:

上面的答案很好,但是对于像我这样的初学者来说,很难看出“窗口中”的部分应该去哪里以及应该保留多少原始代码。以下是基于上述信息的完整工作代码:

import cv2
from PyQt4 import QtGui, QtCore


class Capture():
    def __init__(self):
        self.capturing = False
        self.c = cv2.VideoCapture(0)

    def startCapture(self):
        print "pressed start"
        self.capturing = True
        cap = self.c
        while(self.capturing):
            ret, frame = cap.read()
            cv2.imshow("Capture", frame)
            cv2.waitKey(5)
        cv2.destroyAllWindows()

    def endCapture(self):
        print "pressed End"
        self.capturing = False

    def quitCapture(self):
        print "pressed Quit"
        cap = self.c
        cv2.destroyAllWindows()
        cap.release()
        QtCore.QCoreApplication.quit()


class Window(QtGui.QWidget):
    def __init__(self):

        QtGui.QWidget.__init__(self)
        self.setWindowTitle('Control Panel')

        self.capture = Capture()
        self.start_button = QtGui.QPushButton('Start',self)
        self.start_button.clicked.connect(self.capture.startCapture)

        self.end_button = QtGui.QPushButton('End',self)
        self.end_button.clicked.connect(self.capture.endCapture)

        self.quit_button = QtGui.QPushButton('Quit',self)
        self.quit_button.clicked.connect(self.capture.quitCapture)

        vbox = QtGui.QVBoxLayout(self)
        vbox.addWidget(self.start_button)
        vbox.addWidget(self.end_button)
        vbox.addWidget(self.quit_button)

        self.setLayout(vbox)
        self.setGeometry(100,100,200,200)
        self.show()


if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    sys.exit(app.exec_())

【讨论】:

  • quitCapture(self) 类中存在一个错误:在 quit 期间未停止捕获新帧导致错误,请在 cap = self.c 后添加 self.capturing = False
  • 很棒的程序,谢谢。不幸的是,当按下“退出”时,它并没有用三个按钮关闭窗口,即使在添加 bastelflp 的评论内容时也是如此。
猜你喜欢
  • 1970-01-01
  • 2011-11-18
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多