Skip to content

Instantly share code, notes, and snippets.

@josch
Created June 5, 2013 13:33
Show Gist options
  • Save josch/5713871 to your computer and use it in GitHub Desktop.
Save josch/5713871 to your computer and use it in GitHub Desktop.
reads a deltavision file and stores all images therein as png
#!/usr/bin/env python
#
# reads a deltavision file and stores all images therein as png
# this reader is fairly limited
#
# it expects a deltavision video in which there are two types of images, stored
# interleaved: ABABAB... Both types only have one channel. Each pair A and B is
# combined into an RGB image such that A is green and B is red
#
# example usage:
# python deltavision.py foo input.dv
# avconv -y -r 5 -i foo_%03d.png -c:v libx264 out.mp4
import struct
import Image, ImageDraw
import sys
if len(sys.argv) != 3:
print "usage: %s prefix input.dv"%sys.argv[0]
exit(1)
f = open(sys.argv[2])
dvdata = f.read()
f.close()
dvExtendedHeaderSize = struct.unpack_from("<I", dvdata, 92)[0]
# endian-ness test
if not struct.unpack_from("<H", dvdata, 96)[0] == 0xc0a0:
print "unsupported endian-ness"
exit(1)
dvImageWidth=struct.unpack_from("<I", dvdata, 0)[0]
dvImageHeight=struct.unpack_from("<I", dvdata, 4)[0]
dvNumOfImages=struct.unpack_from("<I", dvdata, 8)[0]
dvPixelType=struct.unpack_from("<I", dvdata, 12)[0]
dvImageDataOffset=1024+dvExtendedHeaderSize
# print dvImageWidth, dvImageHeight, dvNumOfImages, dvPixelType
if dvPixelType != 6:
print "unsupported pixel type"
exit(1)
dvExtendedHeaderNumInts=struct.unpack_from("<H", dvdata, 128)[0]
dvExtendedHeaderNumFloats=struct.unpack_from("<H", dvdata, 130)[0]
sectionSize = 4*(dvExtendedHeaderNumFloats+dvExtendedHeaderNumInts)
sections = dvExtendedHeaderSize/sectionSize
if (sections < dvNumOfImages):
print "number of sections is less than the number of images"
exit(1)
sections = dvNumOfImages
elapsed_times = [[struct.unpack_from("<f", dvdata, i*sectionSize+k*4)[0] for k in range(sectionSize/4)][25] for i in range(sections)]
def strftimefloat(secs):
total_secs, millisecs = int(secs), int((secs - int(secs))*1000)
hours, remainder = divmod(total_secs, 3600)
minutes, seconds = divmod(remainder, 60)
return "%02d:%02d:%02d.%03d"%(hours,minutes,seconds,millisecs)
elapsed_times = [strftimefloat(s) for s in elapsed_times]
offset = dvImageDataOffset
size = dvImageWidth*dvImageHeight*2
def save_im(offset, factor):
im = Image.frombuffer("I;16", [dvImageWidth,dvImageHeight], dvdata[offset:offset+size],'raw','I;16',0,1)
im = Image.eval(im, lambda x:x*factor)
im = im.convert('L')
return im
for i in range(dvNumOfImages/2):
green = save_im(offset, 0.25) # 12 bit data in range 0-4095
offset+=size
red = save_im(offset, 0.5) # double the intensity of the red channel
offset+=size
blue = Image.new('L', (dvImageWidth,dvImageHeight))
im = Image.merge("RGB", (red, green, blue))
draw = ImageDraw.Draw(im)
draw.text((10, 10),elapsed_times[i*2])
im.save("%s_%03d.png"%(sys.argv[1],i))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment