1. 通过指定frame_interval来确定帧间隔;
2. 使用了joblib来加快处理速度。
代码如下所示:
- import os
- import cv2
- import torchvision.transforms as T
- from PIL import Image
- from tqdm import tqdm
- from torchvision.utils import save_image
- from joblib import Parallel, delayed
-
- preprocess = T.Compose([T.Resize(256), T.CenterCrop(256), T.ToTensor()])
-
- def process_one_video(video_file, input_video_folder, target_fold, frame_interval=5):
- input_video_path = os.path.join(input_video_folder, video_file)
- video_id = os.path.splitext(video_file)[0]
-
- vidcap = cv2.VideoCapture(input_video_path)
- fps = vidcap.get(cv2.CAP_PROP_FPS)
- total_frame_num = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
-
- images_folder = os.path.join(target_fold, video_id)
- os.makedirs(images_folder, exist_ok=True)
-
- for i in range(0, total_frame_num, frame_interval):
- vidcap.set(cv2.CAP_PROP_POS_FRAMES, i)
- _, frame = vidcap.read()
- cv2_im = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
- pil_im = Image.fromarray(cv2_im)
- image_tensor = preprocess(pil_im)
-
- save_image(image_tensor, os.path.join(images_folder, '{:06d}.jpg'.format(i)))
-
- # Handle the last frames if they are less than frame_interval
- last_frame_index = total_frame_num - 1
-
- if last_frame_index % frame_interval != 0:
- vidcap.set(cv2.CAP_PROP_POS_FRAMES, last_frame_index)
- _, last_frame = vidcap.read()
- cv2_im_last = cv2.cvtColor(last_frame, cv2.COLOR_BGR2RGB)
- pil_im_last = Image.fromarray(cv2_im_last)
- image_tensor_last = preprocess(pil_im_last)
- save_image(image_tensor_last, os.path.join(images_folder, '{:06d}.jpg'.format(last_frame_index)))
-
- print("Video {} has been processed. Total frames: {}".format(video_id, total_frame_num))
-
- #-----------------------------------#
- # 对视频进行并行处理
- #-----------------------------------#
- def extract_frames_parallel(input_video_folder, target_fold, frame_interval=5):
- video_files = [f for f in os.listdir(input_video_folder) if f.endswith('.mp4')]
-
- Parallel(n_jobs=256)(delayed(process_one_video)(video_file, input_video_folder, target_fold, frame_interval) for video_file in tqdm(video_files))
-
- if __name__ == "__main__":
- from argparse import ArgumentParser
- parser = ArgumentParser(description="Python script to extract frames from videos in a folder and save as jpgs.")
- parser.add_argument("-input_video_folder", type=str, default='/you/input/', help="The folder containing input videos.")
- parser.add_argument("-target_fold", type=str, default='/you/output/', help="The place to store the video frames.")
- parser.add_argument("-frame_interval", type=int, default=5, help="Interval between frames to extract.")
- args = parser.parse_args()
-
- extract_frames_parallel(args.input_video_folder, args.target_fold, args.frame_interval)