-
-
Save grschafer/04f051d959b3c3c2501e to your computer and use it in GitHub Desktop.
Python script for blending video frames together. http://toystoryblended.blogspot.com/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from scipy import misc | |
import numpy as np | |
import multiprocessing as mp | |
import os | |
# number of frames to combine when producing 1 output frame | |
FRAME_LIMIT = 300 | |
# input and output directories | |
INDIR = 'ts1' | |
OUTDIR = '%s_300avg' % INDIR | |
infiles = os.listdir(INDIR) | |
# filters files in input directory to only include those starting with "image" and ending with ".png" | |
infiles = sorted((x for x in infiles if x.startswith('image') and x.endswith('.png'))) | |
NUM_FRAMES = len(infiles) | |
frame1 = misc.imread(os.path.join(INDIR, infiles[0])) | |
def avg_frames(frames): | |
"""Calculates and returns the average of input list of frames, using pyramid-like weighting""" | |
avg_frame = np.zeros(frame1.shape, dtype=float) | |
adj_factor = FRAME_LIMIT / 2; | |
for idx, filename in enumerate(frames): | |
im = misc.imread(os.path.join(INDIR, filename)) | |
avg_frame += im * (1. - float(abs(adj_factor - idx))/adj_factor) / adj_factor | |
return avg_frame | |
def make_frame(inframes, idx): | |
"""Saves average of input frames to file""" | |
frame = avg_frames(inframes) | |
misc.imsave('%s/frame%04d.png' % (OUTDIR, idx), frame) | |
def get_frames(framenum, infiles): | |
"""Gets frames within FRAME_LIMIT/2 on either side of the indicated frame number (wraps around beginning/end)""" | |
if framenum < FRAME_LIMIT/2: | |
frames = infiles[(framenum - FRAME_LIMIT/2):] | |
frames.extend(infiles[:framenum + FRAME_LIMIT/2 + 1]) | |
elif framenum > NUM_FRAMES - FRAME_LIMIT/2: | |
frames = infiles[framenum - FRAME_LIMIT/2:] | |
frames.extend(infiles[:(framenum + FRAME_LIMIT/2) % NUM_FRAMES + 1]) | |
else: | |
frames = infiles[framenum - FRAME_LIMIT/2:framenum + FRAME_LIMIT/2 + 1] | |
return frames | |
def main(): | |
"""Starts 8 processes which execute frame averaging+saving tasks from a pool""" | |
pool = mp.Pool(processes=8) | |
for i, f in enumerate(infiles): | |
frames = get_frames(i, infiles) | |
pool.apply_async(make_frame, args = (frames, i)) | |
print "done filling pool" | |
pool.close() | |
pool.join() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment