gpt4 book ai didi

python - 使用 PyQT 逐帧加载 opencv 视频

转载 作者:太空宇宙 更新时间:2023-11-03 21:21:43 25 4
gpt4 key购买 nike

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

这是它的图形用户界面:

enter image description here

这是我遇到的两个问题:

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

关于python - 使用 PyQT 逐帧加载 opencv 视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39303008/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com