Install¶
pip install videoutils
How to use¶
from videoutils.io import read_video, as_tensor, bgr2rgb, resize
fname = 'files/interstellar-waves-edit.mp4'
x = read_video(fname)
len(x)
x[0].shape
By default, read_video returns a list of np.arrays of shape (height, width, channels).
However, you can define precisely which frames you'd like to grab in a number of ways. This is done by using either the {start_idx, end_idx, frame_stride} or target_frames arguments.
Grab the first n frames¶
n = 50
x = read_video(fname, end_idx=n)
x2 = read_video(fname, target_frames=(0,n))
len(x)
len(x) == len(x2)
Grab every nth frame¶
n=5
x = read_video(fname, frame_stride=n, end_idx=50)
len(x)
x = read_video(fname, frame_stride=50) # total frames = 1578
len(x)
Grab frames at specific indices¶
x = read_video(fname, target_frames=[10, 50, 76, 420])
len(x)
x = read_video(fname, start_idx=10, end_idx=15)
x2 = read_video(fname, target_frames=(10, 15))
len(x)
len(x) == len(x2)
Return as torch.Tensor¶
You can pass any function that transforms a np.array of shape (height, width, channels) to the apply argument. videoutils provides as_tensor for convenience -- if you use this function, read_video will automatically call torch.stack and return the collection of frames as a 4D tensor, else it will return a list of 3D arrays/tensors.
import torch
from functools import partial
x = read_video(fname, end_idx=10, apply=as_tensor)
x2 = read_video(fname, end_idx=10, apply=partial(as_tensor, normalise=True))
x2 = torch.stack(x2) # since we aren't using `as_tensor`, but a partial (thus different) function
x.shape
x.shape == x2.shape
x.mean(), x2.mean()
Resize Video¶
read_video has an optional argument resize_func which is meant to be a function that resizes a np.array of shape (height, width, channels).
You can use the predefined resize function or pass in a custom function here.
help(resize)
x = read_video(fname, target_frames=[0,1,2], apply=as_tensor,
resize_func=partial(resize, scale_factor=2.))
x.shape
x = read_video(fname, target_frames=[0,1,2], apply=as_tensor,
resize_func=partial(resize, width=200, height=100, keep_aspect_ratio=False))
x.shape