CV2视频剪辑,从一个长视频中截取多个视频片段

前言

最近在项目中遇到了这样一个需求,要求读取视频,根据视频帧数剪辑出多个时长相对固定的视频片段(如第100、575、920帧的前后50帧)。该需求通过cv2实现,前后大约修改过三次:
  1、第一种方法是通过多次重复读取视频,每次截取相应的帧数片段,这种方法最为简单但显然效率极其低下,在较长视频处理的场景下是不可接受的;
  2、第二种方法是读取视频,将需要截取的视频图像保存到列表中,再通过videowriter将图像写入,这种方法处理短时长视频可以接受,在处理较长且分辨率大的视频时有内存溢出风险;
  3、第三种方法为创建多个videowriter,本文主要介绍该方法,代码如下

`

多个视频片段生成

import cv2
import datetime

def video_cut(frame_list,video_path,save_path):
    '''
    :param frame_list: 需要剪辑视频的帧数定位列表,如需要剪辑100,500,800的前60帧后40帧,输入[100,500,800]
    :param video_path: 待剪辑视频路径
    :param save_path:  视频片段保存路径
    '''
    cap = cv2.VideoCapture(video_path)
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    #FPS = 20  # int(round(cap.get(cv2.CAP_PROP_FPS)))
    frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    output_list = []
    frame_id = 0
    for i in range(len(frame_list)):
        img_pre_fix = '_%s' % datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
        output_list.append(cv2.VideoWriter(
            save_path + '/' + 'video' + '_' + str(frame_list[i]) + img_pre_fix + '.mp4',fourcc, 20,(frame_width, frame_height)))
    print('video cut generate')
    while True:
        ret,frame = cap.read()
        if not ret:
            break
        frame_id += 1
        #print(frame_id)
        for num,id in enumerate(frame_list):
            if id-60 <=frame_id<=id+40:     # 设置为定位frame的前60帧后40帧
                output_list[num].write(frame)
    cap.release()

if __name__ == '__main__':
    frame_list = [100,420,650]   # 定位帧数frame id
    video_path = r'E:\test.mp4'  # 视频路径
    save_path = r'F:\save_path'  # 存储路径
    video_cut(frame_list=frame_list,video_path=video_path,save_path=save_path)

总结

本文主要是作者对自己学习工作过程中的一个记录,也希望为正遇到类似问题的朋友提供一个参考。

你可能感兴趣的:(音视频,python,计算机视觉,opencv)