#!/usr/bin/python # -*- coding: utf-8 -*- """Take a vertical or horizontal slice through a video. I had done this previously with some slow and kludgy shell scripts. This way is faster, although presumably it won’t scale to producing images much larger than your RAM. It processes about 128 frames per second at the 640×480 size I’m using. At some point this should start using the untested argument parser in its entrails. """ from __future__ import print_function import argparse import os import sys import numpy import PIL.Image def parse_args(): formatter = argparse.RawDescriptionHelpFormatter p = argparse.ArgumentParser(description=__doc__, formatter_class=formatter) p.add_argument('-o', '--output', nargs=1, help='name of output file to write or overwrite') p.add_argument('-d', '--decimation', type=int, default=2, help='only uses one of every DECIMATION frames' +' (default %(default)s)') p.add_argument('-h', '--horizontal', action='store_true', help='take a horizontal slice of vertical pixel rows' +' rather than vice versa') p.add_argument('-s', '--offset', type=int, default=0, help='signed number of pixels to offset the slice from' +' the center of each frame (default %(default)s)') p.add_argument('files', nargs='+', help='filenames of video frames in the desired order') return p.parse_args() if __name__ == '__main__': decimation = 2 files = sys.argv[1:][::decimation] horizontal = False offset = +20 outbuf = None for i, f in enumerate(files): img = PIL.Image.open(f) # XXX is asarray better? pixels = numpy.array(img) # shape is 480×640×3 in my case if outbuf is None: if horizontal: out_shape = (pixels.shape[0], len(files), pixels.shape[2]) else: out_shape = (len(files), pixels.shape[1], pixels.shape[2]) outbuf = numpy.zeros(dtype=pixels.dtype, shape=out_shape) if horizontal: col = int(pixels.shape[1] // 2) + offset outbuf[:, i, :] = pixels[:, col, :] else: row = int(pixels.shape[0] // 2) + offset outbuf[i, :, :] = pixels[row, :, :] if not i % 64: print("\r%s (%d/%d)%s" % (f, i, len(files), ' ' * 40), end='') sys.stdout.flush() outimg = PIL.Image.fromarray(outbuf) outimg.save('../slices.png')