Как я могу сделать видео из последовательностей изображений, пропустив каждый n файлы?

Я знаю, как сделать видео из использования последовательности изображений ffmpeg -i %0Xd.png или *.png и т.д. Но то, что я хотел бы сделать, так или иначе говорят ffmpeg пропускать каждый n файлы. Например, если у меня есть файлы, пронумерованные 0000, 0001, 0002, 0003, 0004, 0005, 0006 и т.д. Я хотел бы сделать видео из файлов 0000, 0003, 0006, 0009 и т.д. (т.е. взятие каждого n == 3-й файл). Перемещение и переименование не являются действительно опцией, поскольку у меня есть сотни тысяч изображений, и я хотел бы к пакетному преобразованию много различных версий с различными суммами n. например.

  • 0000, 0001, 0002...-> n1.mp4
  • 0000, 0002, 0004...-> n2.mp4
  • 0000, 0003, 0006...-> n3.mp4

и т.д.

Действительно ли это возможно?

1
задан 21 May 2019 в 08:59

1 ответ

Я закончил тем, что писал сценарий Python, чтобы сделать это

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
'''
converts sequence of images to video
uses glob pattern and allows skipping images

---
uses [sk-video](https://github.com/scikit-video/scikit-video)
```> pip install sk-video```

backend uses ffmpeg or libav

TODO:
- add more input & output dict opts 

For full list of flags see
- https://ffmpeg.org/ffmpeg.html 
- https://trac.ffmpeg.org/wiki/Encode/H.264

Note: Not using opencv2.VideoWriter because it fails silently on Anaconda

'''
from __future__ import print_function
from __future__ import division

import argparse
import glob
import os
from imageio import imread
from skvideo.io import FFmpegWriter
from tqdm import tqdm
from pprint import pprint

parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input_folder', default='.', help='path to folder containing images')
parser.add_argument('-p', '--file_pattern', default='*.png', help='Unix filename pattern. For details see https://docs.python.org/2/library/fnmatch.html')
parser.add_argument('-o', '--output_path', default='output.mp4', help='path to output video file')
parser.add_argument('-n', '--every', default=10, type=int, help='include every nth image. i.e. every==1 uses every image. every==2 takes every other image ')
parser.add_argument('-m', '--max_count', default=None, type=int, help='if > 0, cap at this many frames')
parser.add_argument('-v', '--verbose', default=False, type=int, help='dump a lot of stuff to the console')

# ffmpeg args
parser.add_argument('-r', '--fps', default='30', type=str, help='frames per second')
parser.add_argument('-vcodec', default='libx264', type=str, help='output video codec')
parser.add_argument('-b', '--bitrate', default=None, type=str, help='bitrate')
parser.add_argument('-crf', default=None, type=str, help='Constant Rate Factor. The range of the CRF scale is 0–51, where 0 is lossless, 23 is the default, and 51 is worst quality possible. A lower value generally leads to higher quality, and a subjectively sane range is 17–28. Consider 17 or 18 to be visually lossless or nearly so; it should look the same or nearly the same as the input but it isnt technically lossless')
args = parser.parse_args()


#%% Get input file list
glob_path = os.path.join(os.path.expanduser(os.path.expandvars(args.input_folder)), args.file_pattern)

# read all files in folder matching pattern
print('Reading folder "{}"'.format(glob_path))
paths = sorted(glob.glob(glob_path))
args.stats = {'file_count_total' : len(paths) }
print(args.stats['file_count_total'], 'files found')

# skip 
if args.every > 1:
    paths = [x for i,x in enumerate(paths) if i % args.every == 0]
    args.stats['file_count_with_skip'] = len(paths)
    print(args.stats['file_count_with_skip'], 'files with skip')

# cap to max_count
if args.max_count:
    paths = paths[:args.max_count]
    args.stats['file_count_capped'] = len(paths)
    print(args.stats['file_count_capped'], 'files after cap')

#%% init video writer with parameters
inputdict = {}
outputdict = {}

if args.fps:
    inputdict['-r'] = args.fps
    outputdict['-r'] = args.fps           

if args.vcodec: outputdict['-vcodec'] = args.vcodec
if args.bitrate: outputdict['-b'] = args.bitrate
if args.crf: outputdict['-crf'] = args.crf

video_writer = FFmpegWriter(args.output_path, inputdict=inputdict, outputdict=outputdict)

#%%
print('Starting with args:')
pprint(vars(args))
for path in tqdm(paths):
    img = imread(path)
    if args.verbose: print('processing file', i, path)
    video_writer.writeFrame(img)

print('\n-')
print('Finished. Video saved at', args.output_path)

video_writer.close()
1
ответ дан 7 December 2019 в 15:23

Другие вопросы по тегам:

Похожие вопросы: