将UCF101数据集的视频提取为帧(多线程实现)

1.实现代码

最开始的版本是使用opencv实现的,但是在实施的过程中,发现opencv在读取视频帧的时候,有的时候ret, frame = capture.read()中的返回值ret有时会为False,会存为错误的1帧,所以改用ffmpeg实现。
使用多线程的ffmpeg实现代码如下:

# 将UCF101数据集中的视频提取为帧
from __future__ import print_function, division
import os
import sys
import subprocess
from multiprocessing import Pool
from tqdm import tqdm

n_thread = 30

# file_name: v_ApplyEyeMakeup_g01_c01.avi
# class_path: xxx/Videos/ApplyEyeMakeup
# dst_class_path: xxx/jpgs/ApplyEyeMakeup
def vid2jpg(file_name, class_path, dst_dir_path):
    if '.avi' not in file_name:
        return
    name, ext = os.path.splitext(file_name)
    dst_directory_path = os.path.join(dst_dir_path, name)  # dst_directory_path: xxx/jpgs/v_ApplyEyeMakeup_g01_c01

    video_file_path = os.path.join(class_path, file_name)  # video_file_path: xxx/Videos/ApplyEyeMakeup/v_ApplyEyeMakeup_g01_c01.avi
    try:
        if os.path.exists(dst_directory_path):
            if not os.path.exists(os.path.join(dst_directory_path, 'img_00001.jpg')):
                subprocess.call('rm -r \"{}\"'.format(dst_directory_path), shell=True)
                print('remove {}'.format(dst_directory_path))
                os.mkdir(dst_directory_path)
            else:
                print('*** convert has been done: {}'.format(dst_directory_path))
                return
        else:
            os.mkdir(dst_directory_path)
    except:
        print(dst_directory_path)
        return
    cmd = 'ffmpeg -i \"{}\" -threads 1 -vf scale=-1:331 -q:v 0 \"{}/img_%05d.jpg\"'.format(video_file_path, dst_directory_path)
    # print(cmd)
    subprocess.call(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)


def class_process(dir_path, dst_dir_path, class_name):  # dir_path: xxx/Videos dst_dir_path: xxx/jpgs ApplyEyeMakeup
    print('*' * 20, class_name, '*'*20)
    class_path = os.path.join(dir_path, class_name)  # class_path: xxx/Videos/ApplyEyeMakeup
    if not os.path.isdir(class_path):
        print('*** is not a dir {}'.format(class_path))
        return

    # dst_class_path = os.path.join(dst_dir_path, class_name)  # dst_class_path: xxx/jpgs/ApplyEyeMakeup
    # if not os.path.exists(dst_class_path):
    #     os.mkdir(dst_class_path)

    vid_list = os.listdir(class_path)
    vid_list.sort()
    p = Pool(n_thread)
    from functools import partial
    worker = partial(vid2jpg, class_path=class_path, dst_dir_path=dst_dir_path)
    for _ in tqdm(p.imap_unordered(worker, vid_list), total=len(vid_list)):
        pass
    # p.map(worker, vid_list)
    p.close()
    p.join()

    print('\n')


if __name__ == "__main__":
    dir_path = sys.argv[1]  # /home/xxx/data/projects/datasets/UCF101/Videos
    dst_dir_path = sys.argv[2]  # /home/xxx/data/projects/datasets/UCF101/jpgs

    class_list = os.listdir(dir_path)
    class_list.sort()
    for class_name in class_list:  # class_name: ApplyEyeMakeup
        class_process(dir_path, dst_dir_path, class_name)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值