【发布时间】:2017-05-08 10:45:34
【问题描述】:
我正在使用 Python 3.6、OpenCV3 和 PyQT5 在 Windows 中编写专门的视频播放器。但是,播放以每秒 30.0 帧录制的视频文件(从我的笔记本电脑网络摄像头录制)时,播放速度很慢。
我将我的应用程序剥离到播放视频的最简单部分。然后,我将应用程序中的播放循环从每帧 15 毫秒更改为每帧 34 毫秒,并记录了每个循环时间。接下来,我计算了每个循环速度下 232 帧播放的平均循环时间。结果令人费解。对于 15 毫秒到 19 毫秒的循环,应用程序的行为与预期一样,但当应用程序指定循环为 20 毫秒到 31 毫秒时,应用程序的行为是稳定的 31.2 毫秒。然后,当应用程序指定的循环慢于 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()
【问题讨论】:
-
31.2ms 的值有点可疑,因为 Windows 的默认计时器分辨率是 15.6ms。您是否尝试将
QTimer的TimerType属性设置为PreciseTimer? -
PreciseTimer 解决了这个问题。谢谢!现在效果很好。
标签: python loops opencv video pyqt