有一个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帧,否则它将以正常速度播放。任何人都可以找出问题所在吗?
答案 0 :(得分:1)
您被锁定在while True:
循环中,直到您按Escape键。 while
具有正常显示视频,连续读取和显示帧的代码。但是,当您按Escape键时,代码存在于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