使用 PyQT 逐帧加载 opencv 视频

2024-04-03

我正在尝试加载一个 mat 文件(具有被跟踪对象的位置坐标)并加载一个视频文件。为了加载视频文件,我使用 opencv。我制作了一个 GUI 来加载它们。一旦有人按下开始按钮,视频就会开始播放,暂停会停止播放。

这是它的 GUI:

这是我遇到的两个问题:

  1. 视频被加载到另一个窗口中。我希望它出现在带有“开始”和“暂停”按钮的主窗口中
  2. 我想添加 2 个按钮(“下一帧”和“上一帧”),它们允许我逐帧浏览视频。下一帧按钮移动到下一帧,上一帧按钮将视频移动到上一帧。

这是代码:

import sys
import scipy.io as sio
from PyQt4 import QtGui, QtCore
import cv2

class QtCapture(QtGui.QWidget):
    def __init__(self, filename):
        super(QtGui.QWidget, self).__init__()

        self.cap = cv2.VideoCapture(str(filename))

        self.video_frame = QtGui.QLabel()
        lay = QtGui.QVBoxLayout()
        lay.setMargin(0)
        lay.addWidget(self.video_frame)
        self.setLayout(lay)

    def nextFrameSlot(self):
        ret, frame = self.cap.read()
        # My webcam yields frames in BGR format
        frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2RGB)
        img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)
        pix = QtGui.QPixmap.fromImage(img)
        self.video_frame.setPixmap(pix)

    def start(self):
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.nextFrameSlot)
        self.timer.start(1000./30)

    def pause(self):
        self.timer.stop()

    def deleteLater(self):
        self.cap.release()
        super(QtGui.QWidget, self).deleteLater()

class ControlWindow(QtGui.QMainWindow):
    def __init__(self):
        super(ControlWindow, self).__init__()
        self.setGeometry(50, 50, 800, 600)
        self.setWindowTitle("PyTrack")

        self.capture = None

    self.matPosFileName = None
    self.videoFileName = None
    self.positionData = None
        self.updatedPositionData  = {'red_x':[], 'red_y':[], 'green_x':[], 'green_y': [], 'distance': []}
    self.updatedMatPosFileName = None

    self.isVideoFileLoaded = False
    self.isPositionFileLoaded = False

        self.quitAction = QtGui.QAction("&Exit", self)
        self.quitAction.setShortcut("Ctrl+Q")
        self.quitAction.setStatusTip('Close The App')
        self.quitAction.triggered.connect(self.closeApplication)

        self.openMatFile = QtGui.QAction("&Open Position File", self)
        self.openMatFile.setShortcut("Ctrl+Shift+T")
        self.openMatFile.setStatusTip('Open .mat File')
        self.openMatFile.triggered.connect(self.loadPosMatFile)

    self.openVideoFile = QtGui.QAction("&Open Video File", self)
        self.openVideoFile.setShortcut("Ctrl+Shift+V")
        self.openVideoFile.setStatusTip('Open .h264 File')
        self.openVideoFile.triggered.connect(self.loadVideoFile)

        self.mainMenu = self.menuBar()

        self.fileMenu = self.mainMenu.addMenu('&File')
    self.fileMenu.addAction(self.openMatFile)
    self.fileMenu.addAction(self.openVideoFile)
        self.fileMenu.addAction(self.quitAction)

    self.imageCaptureWindow = QtGui.QWidget(self)
        self.start_button = QtGui.QPushButton('Start', self.imageCaptureWindow)
        self.start_button.clicked.connect(self.startCapture)
    self.start_button.setGeometry(0,10,40,30)
        self.pause_button = QtGui.QPushButton('Pause', self.imageCaptureWindow)
    self.pause_button.setGeometry(50,10,40,30)

        self.setCentralWidget(self.imageCaptureWindow)

        self.show()

    def startCapture(self):
        if not self.capture and self.isPositionFileLoaded and self.isVideoFileLoaded:
            self.capture = QtCapture(self.videoFileName)
            self.pause_button.clicked.connect(self.capture.pause)
            self.capture.setParent(self)
            self.capture.setWindowFlags(QtCore.Qt.Tool)
        self.capture.start()
        self.capture.show()

    def endCapture(self):
        self.capture.deleteLater()
        self.capture = None

    def loadPosMatFile(self):
    try:
            self.matPosFileName = str(QtGui.QFileDialog.getOpenFileName(self, 'Select .mat position File'))
            self.positionData = sio.loadmat(self.matPosFileName)
        self.isPositionFileLoaded = True
    except:
        print "Please select a .mat file"

    def loadVideoFile(self):
    try:
            self.videoFileName = QtGui.QFileDialog.getOpenFileName(self, 'Select .h264 Video File')
        self.isVideoFileLoaded = True
    except:
        print "Please select a .h264 file"

    def closeApplication(self):
        choice = QtGui.QMessageBox.question(self, 'Message','Do you really want to exit?',QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
        if choice == QtGui.QMessageBox.Yes:
            print("Closing....")
            sys.exit()
        else:
            pass


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

我应该怎样做呢?谢谢您的帮助!


这是上述问题的解决方案:

import sys
import scipy.io as sio
from PyQt4 import QtGui, QtCore
import cv2


class VideoCapture(QtGui.QWidget):
    def __init__(self, filename, parent):
        super(QtGui.QWidget, self).__init__()
        self.cap = cv2.VideoCapture(str(filename))
        self.video_frame = QtGui.QLabel()
        parent.layout.addWidget(self.video_frame)

    def nextFrameSlot(self):
        ret, frame = self.cap.read()
        frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2RGB)
        img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)
        pix = QtGui.QPixmap.fromImage(img)
        self.video_frame.setPixmap(pix)

    def start(self):
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.nextFrameSlot)
        self.timer.start(1000.0/30)

    def pause(self):
        self.timer.stop()

    def deleteLater(self):
        self.cap.release()
        super(QtGui.QWidget, self).deleteLater()


class VideoDisplayWidget(QtGui.QWidget):
    def __init__(self,parent):
        super(VideoDisplayWidget, self).__init__(parent)

    self.layout = QtGui.QFormLayout(self)

        self.startButton = QtGui.QPushButton('Start', parent)
        self.startButton.clicked.connect(parent.startCapture)
        self.startButton.setFixedWidth(50)
        self.pauseButton = QtGui.QPushButton('Pause', parent)
        self.pauseButton.setFixedWidth(50)
        self.layout.addRow(self.startButton, self.pauseButton)

        self.setLayout(self.layout)


class ControlWindow(QtGui.QMainWindow):
    def __init__(self):
        super(ControlWindow, self).__init__()
        self.setGeometry(50, 50, 800, 600)
        self.setWindowTitle("PyTrack")

        self.capture = None

        self.matPosFileName = None
        self.videoFileName = None
        self.positionData = None
        self.updatedPositionData  = {'red_x':[], 'red_y':[], 'green_x':[], 'green_y': [], 'distance': []}
        self.updatedMatPosFileName = None

            self.isVideoFileLoaded = False
        self.isPositionFileLoaded = False

        self.quitAction = QtGui.QAction("&Exit", self)
        self.quitAction.setShortcut("Ctrl+Q")
        self.quitAction.setStatusTip('Close The App')
        self.quitAction.triggered.connect(self.closeApplication)

        self.openMatFile = QtGui.QAction("&Open Position File", self)
        self.openMatFile.setShortcut("Ctrl+Shift+T")
        self.openMatFile.setStatusTip('Open .mat File')
        self.openMatFile.triggered.connect(self.loadPosMatFile)

        self.openVideoFile = QtGui.QAction("&Open Video File", self)
        self.openVideoFile.setShortcut("Ctrl+Shift+V")
        self.openVideoFile.setStatusTip('Open .h264 File')
        self.openVideoFile.triggered.connect(self.loadVideoFile)

        self.mainMenu = self.menuBar()
        self.fileMenu = self.mainMenu.addMenu('&File')
        self.fileMenu.addAction(self.openMatFile)
        self.fileMenu.addAction(self.openVideoFile)
        self.fileMenu.addAction(self.quitAction)

        self.videoDisplayWidget = VideoDisplayWidget(self)
        self.setCentralWidget(self.videoDisplayWidget)

    def startCapture(self):
        if not self.capture and self.isPositionFileLoaded and self.isVideoFileLoaded:
            self.capture = VideoCapture(self.videoFileName, self.videoDisplayWidget)
            self.videoDisplayWidget.pauseButton.clicked.connect(self.capture.pause)
        self.capture.start()

    def endCapture(self):
        self.capture.deleteLater()
        self.capture = None

    def loadPosMatFile(self):
        try:
            self.matPosFileName = str(QtGui.QFileDialog.getOpenFileName(self, 'Select .mat position File'))
            self.positionData = sio.loadmat(self.matPosFileName)
            self.isPositionFileLoaded = True
        except:
            print "Please select a .mat file"

    def loadVideoFile(self):
        try:
            self.videoFileName = QtGui.QFileDialog.getOpenFileName(self, 'Select .h264 Video File')
            self.isVideoFileLoaded = True
        except:
            print "Please select a .h264 file"

    def closeApplication(self):
        choice = QtGui.QMessageBox.question(self, 'Message','Do you really want to exit?',QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
        if choice == QtGui.QMessageBox.Yes:
            print("Closing....")
            sys.exit()
        else:
            pass


if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = ControlWindow()
    window.show()
    sys.exit(app.exec_())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 PyQT 逐帧加载 opencv 视频 的相关文章

随机推荐

  • PHP 提交表单后保持复选框选中状态

    大家好 我有一份联系表格和验证码 我希望在提交表格后保持检查状态 我发布了文本框值 它显示正确 但复选框不起作用 这是我的代码
  • Pandas 将列类型从列表转换为 np.array

    我正在尝试将一个函数应用于 pandas 数据框 这样的函数需要两个 np array 作为输入 并且它使用定义良好的模型来拟合它们 关键是我无法从选定的列开始应用此函数 因为它们的 行 包含从 JSON 文件读取的列表 而不是 np ar
  • 如何将节点检查器与“npm start”一起用于我的应用程序?

    我在用npm start启动我的 MEAN 堆栈应用程序 但我想使用节点检查器来调试一些 Mongoose 我知道我可以启动节点检查器node inspector 但是我可以用什么来代替node debug app js与 使npm sta
  • Delphi - 从静态链接的 MSVC++ 编译的 DLL 捕获 stdout 和 stderr 输出

    我一直在努力捕捉stdout and stderr我的 Delphi 应用程序静态链接到的 MSVC 中编译的 DLL 的输出 但到目前为止尚未成功 procedure Test var fs TFileStream begin fs TF
  • 从另一个 git 存储库链接单个文件

    你如何链接一个单个文件从另一个 git 存储库到您自己的存储库 我不需要完整的存储库 只需要一个文件 使用git submodule看似正确的路线 但它想要抓住整个事情 考虑到 git 的工作单元是一个存储库 或者更准确地说是一个存储库 c
  • 禁用 JavaFX 图表背景图像的缓存

    我有一个简单的折线图 按下按钮即可在新窗口中打开 该折线图使用存储在硬盘上的图像作为背景 如果我关闭计算折线图的窗口 更改图像文件 或删除它 并重新打开窗口 则会再次加载旧图像 我在场景生成器和代码中禁用了折线图的缓存 但这没有帮助 有人能
  • 返回 false 不起作用

    我创建了一种带有动态创建复选框的表单 我使用了一个 j 查询脚本来检查天气用户是否选中了至少一个复选框 如果没有 那么它会发出错误消息警报 HTML 代码 print
  • android:应用程序不支持设备 - 为什么?

    我目前正在开发一个相机应用程序 现在 一位用户抱怨他的设备不受支持 它是宏碁A200 http www specsbox com 819 acer iconia a200 tablet html 我不明白为什么 android market
  • 如何从Qt调用evaluateJavaScript()函数?

    我无法从 QT 调用 javascript 函数 我正在使用下面的代码 QT代码 QWebFrame frame m d gt m webView gt page gt mainFrame frame gt evaluateJavaScri
  • Acumatica 实时动态下拉列表

    我有以下用例 Acumatica 组合框 下拉列表 可以有 8 个左右的值 其选择决定了用于在组合框 下拉列表中呈现的表 DAC e g 如果当前StatusProfileID WO1 和Status WCMP WCMP 是当前版本User
  • jQuery 选择器检查元素是否动画隐藏

    有没有办法判断一个元素是否被隐藏或当前正在隐藏 通过动画 我能想到的唯一方法是将标志存储在元素的data你打电话时show or hide 但我想知道是否还有其他方法 你能为它做一个自定义的 jQuery 选择器吗 function var
  • 可达性 - 奇怪的问题

    Reachability r Reachability reachabilityWithHostName www google com 这条线在设备上工作正常 但在模拟器上我崩溃了 由于未捕获的异常 NSInvalidArgumentExc
  • 如何在 jQuery 中读取绑定的悬停回调函数

    我使用 jQuery 为页面上的元素设置悬停回调 我现在正在编写一个模块 需要临时为某些元素设置新的悬停行为 新模块无法访问悬停功能的原始代码 我想在设置新的悬停功能之前存储旧的悬停功能 以便在完成临时悬停行为后可以恢复它们 我认为这些可以
  • 从 bash 在默认编辑器中打开文件

    如何使用 bash 打开使用默认 GUI 编辑器生成的脚本生成的文件 在 OS X 上有命令open 但据我所知 linux 上不存在 什么是好的跨平台替代方案 执行open somefile ext在 OS X 上 效果与我在 Finde
  • 无法在 ASP.NET 中纠正 VeraCode CWE ID 918 - (SSRF)

    长话短说 无论我如何尝试 VeraCode 都会继续将我的 8 行代码标记为 CWE 918 缺陷 这是旧代码 所以我不确定为什么它突然被标记 这是一个示例 offending 方法 其中标记行以粗体显示 public virtual as
  • ItemTouchHelper startSwipe 不起作用

    我尝试在适配器内使用 startSwipe 但似乎不起作用 奇怪的是 当我尝试用手指手动滑动它时 它起作用了 只是当我单击支架内的按钮时 startSwipe 不起作用 需要这方面的帮助 这是我调用 startSwipe 的地方 在 onC
  • Intellij+Springboot+Thymeleaf+gradle - 自动重新加载html资源

    我正在使用 IntelliJ Ultimate Spring Boot 和 Thymeleaf 我想启用 HTML 自动重新加载 而无需重新启动服务器 也无需使用 CTRL F9 我已经阅读了以下内容 我认为它应该有效 但事实并非如此 ht
  • 自定义适配器不显示任何项目

    这是先前问题的后续 ListView android 行中的 ImageButton 不工作 https stackoverflow com questions 29819256 imagebutton within row of list
  • Google 地图路线 API - 到达时间?

    我使用 Google Directions API 来计算两个地点之间所需的时间 API 给了我一个选择departure time 我可以在其中传递出发时间 或 现在 的时间戳 那么答案就是duration in traffic 这真的很
  • 使用 PyQT 逐帧加载 opencv 视频

    我正在尝试加载一个 mat 文件 具有被跟踪对象的位置坐标 并加载一个视频文件 为了加载视频文件 我使用 opencv 我制作了一个 GUI 来加载它们 一旦有人按下开始按钮 视频就会开始播放 暂停会停止播放 这是它的 GUI 这是我遇到的