有一个 30fps 的视频,播放时间为 2 小时。我只需要每秒播放一帧。我可以通过以下方式执行以下操作 -
cap = cv2.VideoCapture('vid.avi')
count = 0
while(True):
ret, frame = cap.read()
if count%30==0:
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
count = count+1
cv2.destroyAllWindows()
但是提到的方法非常缓慢且不可行。我正在尝试做一些事情,以列出要显示的帧号(每个第 30 帧 = 30,90,120,150,.....(,然后只访问这些帧并播放。我写了以下代码 -
import cv2
# read the video and extract info about it
cap = cv2.VideoCapture('vid.avi')
# get total number of frames and generate a list with each 30 th frame
totalFrames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
x = [i for i in range (1, totalFrames) if divmod(i, int(30))[1]==0]
for myFrameNumber in x:
cap.set(cv2.CAP_PROP_POS_FRAMES,myFrameNumber)
while True:
ret, frame = cap.read()
cv2.imshow("video", frame)
# something wrong in the following three line
ch = 0xFF & cv2.waitKey(1)
if ch == 27:
break
cv2.destroyAllWindows()
代码仅在按下"esc"按钮时播放第 30 帧,否则以正常速度播放。任何人都可以找出问题所在吗?
你被锁定在while True:
循环中,直到你按 esc 键。while
具有正常显示视频的代码,连续读取和显示帧。但是当你按 esc 时,代码存在于for myFrameNumber in x:
块中,该块使用帧号设置数组中的下一帧。
应删除While
循环,以便仅读取和显示set
的帧。要实现第二次延迟,您可以增加等待时间(以waitKey
为单位((以毫秒为单位(
for myFrameNumber in x:
#set which frame to read
cap.set(cv2.CAP_PROP_POS_FRAMES,myFrameNumber)
# read frame
ret, frame = cap.read()
# display frame
cv2.imshow("video", frame)
# wait one second, exit loop if escape is pressed
ch = 0xFF & cv2.waitKey(1000)
if ch == 27:
break