s59_60r
s59_60r

Reputation: 1

How can i create a slideshow of some selected frames from a video in Python?

I have a video. In that video, there are some frames which i call Key Frames. I want to select those frames and make an separate video out of them, maybe with FPS 10, and i want to do this as efficiently as i can

This is what im doing right now.

I keep a list of frame numbers which i wanna extract. Then I use the following code to save the frames as image, using OpenCV

myFrameNumber = frame_no
cap = cv2.VideoCapture(VIDEO_FILE)
totalFrames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
if myFrameNumber >= 0 & myFrameNumber <= totalFrames:
    cap.set(1,myFrameNumber)
ret, frame = cap.read()
plt.imshow(frame)
plt.savefig(f'{RESULT_FOLDER}/{frame_no}.png')
plt.close()

After this i have around 200-300 images in a result folder, now i use skvideo to combine those images into a video, using the following code.

frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape
out_video =  np.empty([len(images), height, width, 3], dtype = np.uint8)
out_video =  out_video.astype(np.uint8)
for i in range(0,len(images)):
    img = cv2.imread(image_folder+'/'+images[i])
    out_video[i] = img
skvideo.io.vwrite(video_name, out_video, inputdict={'-r':str(BASE_FPS)})

but this whole process is rather slow, and i feel it can be done better. Any suggestion? The goal is to do this thing fast and efficient

Upvotes: 0

Views: 436

Answers (1)

TzviLederer
TzviLederer

Reputation: 137

it depends on how many frames you want to save and where are they in the original video. But maybe it can work:

import cv2

frame_idx_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
video_name = 'video_name.mp4'
out_filename = 'out.mp4'
fps = 10

cap = cv2.VideoCapture(video_name)

h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter(out_filename, fourcc=fourcc, fps=fps, frameSize=(w, h))

i = 0
while frame_idx_list:
    ret, frame = cap.read()
    if not ret:
        break
    if i in frame_idx_list:
        writer.write(frame)
        frame_idx_list.remove(i)
    i += 1

writer.release()

if the number of frames is not large and the original video is huge, and if the frames you want to save are relatively at the end of the video, you should use the cap.set() method.

Upvotes: 1

Related Questions