如何通过OpenCV和Python按索引从视频中获取帧?

17

我需要通过帧索引访问视频中的帧。到目前为止,我使用的代码类似于:

video = cv2.VideoCapture(video_path)
status, frame = video.read()

代码读取第一帧。如果我多次使用该代码,我将得到下一帧。但是如何通过索引直接访问任何帧?

换句话说,如果我想要第二帧,如何直接访问第二帧,而不必调用read()两次?


类似于https://dev59.com/AW0NtIcB2Jgan1znFyV7的问题,我需要将一个MP4视频中的一个随机帧提取出来。 - NDAYISABA Charles
2个回答

30

使用VideoCapture::set()函数,对属性ID为CAP_PROP_POS_FRAMES的帧位置进行设置,以便读取该帧。

myFrameNumber = 50
cap = cv2.VideoCapture("video.mp4")

# get total number of frames
totalFrames = cap.get(cv2.CAP_PROP_FRAME_COUNT)

# check for valid frame number
if myFrameNumber >= 0 & myFrameNumber <= totalFrames:
    # set frame position
    cap.set(cv2.CAP_PROP_POS_FRAMES,myFrameNumber)

while True:
    ret, frame = cap.read()
    cv2.imshow("Video", frame)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

1
在Python 3中需要使用cap.set(1, myFrameNumber)。 - msch
感谢@zindarod的帮助! 在cv2.destroyAllWindows()之前添加cap.release()也是推荐的。 - Volkov Maxim

1
import os
folder= 'frames'
os.mkdir(folder)
import cv2
vidcap = cv2.VideoCapture('four.mp4')
def getFrame(sec):
    vidcap.set(cv2.CAP_PROP_POS_MSEC,sec*1000)
    hasFrames,image = vidcap.read()
    if hasFrames:
        cv2.imwrite("image"+str(count)+".jpg", image)     # save frame as JPG file
    return hasFrames
sec = 0
frameRate = 0.5 #//it will capture image in each 0.5 second
count=1
success = getFrame(sec)
while success:
    count = count + 1
    sec = sec + frameRate
    sec = round(sec, 2)
    success = getFrame(sec)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,