视频中的帧速率不正确
frame rate not correct in videos
我有一个 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()
看来 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
这种有绝对时间完成 display/read 下一帧的技术意味着帧速率将是准确的,自动补偿其他 OS 任务的多任务任务不会占用太多 CPU 以致于您的代码几乎无法运行,如果您遇到该问题,我想您将不得不提高 Python 的优先级,这会减慢其他程序的速度。我已经在 temperature/vibration 测量的定时采样中使用了这种方法,并且效果很好。在我的一个答案中看到相同的技术
如果你真的 careful/pessimistic 你也会检查 waitKey()
在帧读取+显示花费的时间长于帧周期的情况下没有被给予负延迟。
我有一个 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()
看来 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
这种有绝对时间完成 display/read 下一帧的技术意味着帧速率将是准确的,自动补偿其他 OS 任务的多任务任务不会占用太多 CPU 以致于您的代码几乎无法运行,如果您遇到该问题,我想您将不得不提高 Python 的优先级,这会减慢其他程序的速度。我已经在 temperature/vibration 测量的定时采样中使用了这种方法,并且效果很好。在我的一个答案中看到相同的技术
如果你真的 careful/pessimistic 你也会检查 waitKey()
在帧读取+显示花费的时间长于帧周期的情况下没有被给予负延迟。