Skip to content

Instantly share code, notes, and snippets.

@grschafer
Created February 17, 2013 01:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save grschafer/04f051d959b3c3c2501e to your computer and use it in GitHub Desktop.
Save grschafer/04f051d959b3c3c2501e to your computer and use it in GitHub Desktop.
Python script for blending video frames together. http://toystoryblended.blogspot.com/
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