2017-05-08 953 views
1

我使用Python 3.6,OpenCV3和PyQT5在Windows中編寫專門的視頻播放器。但是,播放以每秒30.0幀記錄的視頻文件時播放較慢(從我的筆記本電腦攝像頭錄製)。視頻播放速度很慢 - Python 3.6,OpenCV 3,PyQT 5

我將我的應用程序剝離到播放視頻的最佳部分。然後,我將應用程序中的回放循環從每幀15毫秒變爲每幀34毫秒,並記錄每個循環時間。接下來,我計算了每個循環速度下232幀播放的平均循環時間。結果令人費解。應用程序的行爲與15 ms到19 ms的循環相同,但當應用程序指定循環的時間爲20 ms到31 ms時,應用程序的性能保持穩定31.2 ms。然後,當應用程序指定的循環慢於31毫秒時,循環時間再次跳轉。

Application = 15msec, Average Result = 15.0msec, Difference = 0.0msec 
Application = 16msec, Average Result = 16.0msec, Difference = 0.0msec 
Application = 17msec, Average Result = 17.0msec, Difference = 0.0msec 
Application = 18msec, Average Result = 18.0msec, Difference = 0.0msec 
Application = 19msec, Average Result = 19.0msec, Difference = 0.0msec 
Application = 20msec, Average Result = 31.2msec, Difference = 11.2msec 
Application = 21msec, Average Result = 31.2msec, Difference = 10.2msec 
Application = 22msec, Average Result = 31.2msec, Difference = 9.2msec 
Application = 23msec, Average Result = 31.2msec, Difference = 8.2msec 
Application = 24msec, Average Result = 31.2msec, Difference = 7.2msec 
Application = 25msec, Average Result = 31.2msec, Difference = 6.2msec 
Application = 26msec, Average Result = 31.2msec, Difference = 5.2msec 
Application = 27msec, Average Result = 31.2msec, Difference = 4.2msec 
Application = 28msec, Average Result = 31.2msec, Difference = 3.2msec 
Application = 29msec, Average Result = 31.2msec, Difference = 2.2msec 
Application = 30msec, Average Result = 31.2msec, Difference = 1.2msec 
Application = 31msec, Average Result = 31.2msec, Difference = 0.2msec 
Application = 32msec, Average Result = 39.1msec, Difference = 7.1msec 
Application = 33msec, Average Result = 46.8msec, Difference = 13.8msec 
Application = 34msec, Average Result = 46.8msec, Difference = 12.8msec 

我還計算了執行nextFrameSlot(self)方法需要多長時間。它需要平均6毫秒的執行時間,所以它不應該導致循環延遲。

我希望播放速度爲真正的速率,這應該是1 /(幀速率)。

有沒有人有任何建議,爲什麼發生這種情況?這是代碼。 (我沒有包含pydesigner創建的GUI代碼)。

from PyQt5.QtWidgets import QApplication, QMainWindow 
from PyQt5.QtGui import QImage, QPixmap 
from PyQt5.QtCore import QTimer 
from time import time 
import sys 
import cv2 
import vidtest  # GUI Module created by pydesigner 

class VideoCapture(QMainWindow, vidtest.Ui_MainWindow): 
    def __init__(self): 
     super(self.__class__, self).__init__() 
     self.setupUi(self) # This is defined in design.py file automatically 
     self.btnLoadFile.clicked.connect(self.loadVideoFile) 
     self.btnStartPlay.clicked.connect(self.start) 
     self.btnStop.clicked.connect(self.closeApplication) 
     self.durations = [] 

    def nextFrameSlot(self): 
     ret, frame = self.cap.read() 
     frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 
     x = frame.shape[1] 
     y = frame.shape[0] 
     img = QImage(frame, x, y, QImage.Format_RGB888) 
     pix = QPixmap.fromImage(img) 
     self.vidWindow.setPixmap(pix) 
     a = time() # Used to record loop time 
     self.durations.append(a) # Used to record loop time 

    def start(self): 
     self.timer = QTimer() 
     print("Rate = ", self.vid_rate) 
     self.timer.timeout.connect(self.nextFrameSlot) 
     self.timer.start(self.vid_rate) 

    def loadVideoFile(self): 
     self.videoFileName = "stopwatch.avi" 
     self.cap = cv2.VideoCapture(str(self.videoFileName)) 
     self.frame_rate = self.cap.get(cv2.CAP_PROP_FPS) 
     self.vid_rate = 34  # reset this integer from 15 through 34 
     self.nextFrameSlot()  

    def closeApplication(self): 
     for i in self.durations: 
      print (i) 
     self.cap.release() 
     sys.exit(0) 

def main(): 
    app = QApplication(sys.argv) 
    form = VideoCapture() 
    form.show() 
    app.exec_() 

if __name__ == '__main__': 
    main() 
+0

鑑於Windows的默認計時器分辨率爲15.6ms,31.2ms的值有點可疑。你有沒有嘗試將'QTimer'的['TimerType'](https://doc.qt.io/qt-5/qtimer.html#timerType-prop)屬性設置爲'PreciseTimer'? – user3419537

+0

PreciseTimer修復了這個問題。謝謝!它現在效果很好。 – slalomchip

回答

1

謝謝,user3419537!你的建議奏效了。

我需要在函數start(self)中的語句self.timer = QTimer()之後指定self.timer.setTimerType(Qt.PreciseTimer)。默認情況下,QTimer()使用一個粗略的定時器。