Reputation: 1
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
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