import matplotlib.pyploy as plt
import cv2
def getFrame(cap):
frameRate = 25
frameId = cap.get(cv2.CAP_PROP_POS_FRAMES)
ret, frame = cap.read()
if not ret:
return None
print frameId
if frameId < 0:
return None
if not (frameId % int(frameRate)):
cap.set(cv2.CAP_PROP_POS_FRAMES, frameId + frameRate)
return frame
return None
videoFile = 'filename.webm'
cap = cv2.VideoCapture(videoFile,cv2.CAP_FFMPEG)
image = getFrame(cap)
plt.imshow(image)
cap.set(cv2.CAP_PROP_POS_FRAMES,4000.0)
image = getFrame(cap)
while(image is not None):
plt.imshow(image)
image = getFrame(cap)
cap.release()
我在while循环中运行上面的代码并显示图像。似乎在大约4250帧之后,返回的帧将与开始时的帧相同。此循环在另一个4250帧之后继续。
我正在阅读的文件是mp4和webm文件。两种类型的文件的行为都是相同的。 videoCapture正在使用FFMPEG后端。 Opencv version = 3.4.1,python 2.7。
另一个值得注意的行为是,随着帧的增加,帧的读取速度变慢,然后在4250帧之后再次恢复快速。
编辑:
我编辑了代码。我想你可以试着用mp4 / webm文件运行这个时间超过5分钟。由于隐私原因,我无法上传视频,因为它是在办公室录制的。
当我仅使用cap.read()修改代码时,错误消失。我怀疑这与cap.set()
有关答案 0 :(得分:0)
使用cap.set(cv2.cv.CV_CAP_PROP_FPS,25)代替跳过帧并在代码中设置帧编号。
在设置cv2.CAP_PROP_POS_FRAMES,frameId + frameRate之前,您的代码不会检查视频的大小。
您可以使用cap.get(cv2.CAP_PROP_FRAME_COUNT)检查帧的大小。
答案 1 :(得分:0)
def getNextFrame(cap):
frameRate = 25
for i in range(frameRate-1):
cap.grab()
ret, frame = cap.read()
return ret, frame
我找到了解决方法。我使用grab()来跳过24帧,然后只读取()我需要的帧。
我不确定这是不是最好的方法,但我会把它放在这里。我仍然会接受其他答案。