Skip to content

Instantly share code, notes, and snippets.

@npyoung
Last active August 29, 2015 14:23
Show Gist options
  • Save npyoung/c14a6a1f92fc3b7d9490 to your computer and use it in GitHub Desktop.
Save npyoung/c14a6a1f92fc3b7d9490 to your computer and use it in GitHub Desktop.
Compile a TIFF stack into a H.264 movie
#!/usr/bin/env python
import argparse, os
from libtiff import TIFF
import moviepy.editor as mpy
import numpy as np
from skimage.color import gray2rgb
if __name__ == '__main__':
ap = argparse.ArgumentParser()
ap.add_argument('input_stack', help="Path to a tiff stack file")
ap.add_argument('output_file', nargs='?', default=None, help="Path to the file that will be created")
ap.add_argument('-i', '--input-rate', type=int, dest='input_rate', help="Frame rate of the input")
ap.add_argument('-o', '--output-rate', type=int, dest='output_rate', help="Frame rate of the output")
ap.add_argument('-c', '--hist-crop', nargs=2, type=float, default=[2, 98], dest='hist_crop', help="Low and high percentiles for normalizing intensity")
ap.add_argument('-b', '--swap-bytes', action='store_true', default=False, dest='swap_bytes', help="Seems to be necessary for float (e.g. ratio) images, but not 16 bit uint tiffs")
args = ap.parse_args()
if not args.output_file:
root, ext = os.path.splitext(args.input_stack)
args.output_file = root + '_%0.1fx.mp4' % (args.output_rate / args.input_rate)
tif = TIFF.open(args.input_stack, mode='r')
stack_iter = tif.iter_images()
stack_iter.next()
test_frame = stack_iter.next().byteswap()
low, high = np.percentile(test_frame, args.hist_crop[0]), np.percentile(test_frame, args.hist_crop[1])
depth = 2**8 - 1
def get_image(t):
frame = stack_iter.next()
if args.swap_bytes:
frame = frame.byteswap()
normed = np.clip(depth * (frame - low) / high, 0, depth)
uint = np.uint8(normed)
return gray2rgb(uint)
clip = mpy.VideoClip(get_image, duration=60*5)
clip.write_videofile(args.output_file, fps=args.output_rate, codec='libx264', audio=False, preset='fast', threads=4, ffmpeg_params=['-pix_fmt', 'yuv420p'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment