opencv pyqt视频正常帧速率

时间:2017-04-15 01:04:27

标签: python-3.x pyqt5 opencv3.0

我正在使用OpenCV3和ffmepg在Python 3.6中创建一个专用视频播放器,用于处理图像和在Windows环境中使用PyQt5。我之所以选择这种软件包,是因为ffmpeg处理的代码集比QtMultimedia更广泛。

我遇到了一个问题。我的播放器不能以常规速度播放 - 它的播放速度约为正常速度的3/4。我使用QTimer.timer以1 /帧速率循环显示引擎(nextFrameSlot)。

有关如何以常规速度播放视频的任何建议?这是一组缩写代码,用于演示我的问题。

import sys
from PyQt5.QtWidgets import QWidget, QLabel, QFormLayout, QPushButton, QMainWindow
from PyQt5.QtWidgets import QAction, QMessageBox, QApplication, QFileDialog
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QTimer
import cv2


class VideoCapture(QWidget):
    def __init__(self, filename, parent):
        super(QWidget, self).__init__()
        self.cap = cv2.VideoCapture(str(filename[0]))
        self.length = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT))
        self.frame_rate = self.cap.get(cv2.CAP_PROP_FPS)
        #self.codec = self.cap.get(cv2.CAP_PROP_FOURCC)
        self.video_frame = QLabel()
        parent.layout.addWidget(self.video_frame)

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

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

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

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

class VideoDisplayWidget(QWidget):
    def __init__(self,parent):
        super(VideoDisplayWidget, self).__init__(parent)
        self.layout = QFormLayout(self)
        self.startButton = QPushButton('Start', parent)
        self.startButton.clicked.connect(parent.startCapture)
        self.startButton.setFixedWidth(50)
        self.pauseButton = QPushButton('Pause', parent)
        self.pauseButton.setFixedWidth(50)
        self.layout.addRow(self.startButton, self.pauseButton)
        self.setLayout(self.layout)

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

        self.capture = None

        self.isVideoFileLoaded = False

        self.quitAction = QAction("&Exit", self)
        self.quitAction.setShortcut("Ctrl+Q")
        self.quitAction.triggered.connect(self.closeApplication)

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

        self.mainMenu = self.menuBar()
        self.fileMenu = self.mainMenu.addMenu('&File')
        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.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 loadVideoFile(self):
        try:
            self.videoFileName = QFileDialog.getOpenFileName(self, 'Select a Video File')
            self.isVideoFileLoaded = True
        except:
            print ("Please Select a Video File")

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

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

1 个答案:

答案 0 :(得分:0)

已解决 - 我需要在函数string term = //this is the part i want to store text from default.aspx string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|mydb.mdb"; DataTable results = new DataTable(); using (OleDbConnection conn = new OleDbConnection(connString)) { OleDbCommand cmd = new OleDbCommand("SELECT title FROM news WHERE title LIKE '%'"+term+"'% ' ",conn); conn.Open(); OleDbDataAdapter adapter = new OleDbDataAdapter(cmd); adapter.Fill(results); if (results.Rows.Count != 0) { using (OleDbDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { terms = reader[0].ToString(); searchbox.InnerText = terms; } } } } 中的语句self.timer.setTimerType(Qt.PreciseTimer)之后指定self.timer = QTimer()。默认情况下,QTimer()使用粗略计时器。对于Windows,粗略时间间隔为15.6毫秒。