我有一个25 fps的12秒视频。当我在opencv中以25 fps播放视频时,视频变为16秒。我通过使用获得fps fps = get(cv2.CAP_PROP_FPS),然后我设置了waitKey(1000 / fps),但是视频播放缓慢...
import numpy as np
import cv2
import time
start = time.time()
cap = cv2.VideoCapture("hackerman.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
print(fps)
while True:
# Capture frame-by-frame
ret, frame = cap.read()
if ret == True:
frame_new = frame
else:
end = time.time()
# frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # turn video gray
# Display the resulting frame
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
cv2.imshow('frame', frame_new)
k = cv2.waitKey(int(round(1000/fps))) & 0xFF
if k == 27: # wait for ESC key to exit
break
elif cv2.getWindowProperty("frame", 0) == -1:
break
print(end-start)
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
答案 0 :(得分:1)
看来cap.read()的读取速度并非不是比帧速率快,如果处理帧而不是显示帧,这是非常可取的-因此在应用程序中,您需要使用例如time.sleep()
或您的情况下waitKey()
,必须将其计算为达到25fps的帧率。
对于最精确的25fps,将下一帧结束的时间基于总体开始时间,如下所示(未测试):
frameref_ms = int(time.time()*1000)
frametime_ms = int(1000/fps)
while True:
# update frameref to end frame period from now (regardless of how long reading and displaying the frame takes)
frameref_ms += frametime_ms
# Capture frame-by-frame
ret, frame = cap.read()
if ret == True:
frame_new = frame
else:
end = time.time()
# frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # turn video gray
# Display the resulting frame
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
cv2.imshow('frame', frame_new)
# wait for a keypress or the time needed to finish the frame duration
k = cv2.waitKey(frameref_ms-int(time.time()*1000)) & 0xFF
if k == 27: # wait for ESC key to exit
break
elif cv2.getWindowProperty("frame", 0) == -1:
break
这种具有绝对时间来完成显示/读取下一帧的技术意味着帧速率将是精确的,只要这些其他任务不需要占用太多CPU即可自动补偿其他OS任务的多任务处理代码很难运行,如果遇到这个问题,我想您必须增加Python的优先级,这会使其他程序变慢。我在定时采样中使用这种方法进行温度/振动测量,并且效果很好。在我的答案之一Inaccurate while loop timing in Python
中看到相同的技术如果您非常小心/悲观,则还应检查在帧读取+显示花费的时间长于帧周期的情况下,waitKey()
是否没有受到负延迟。