Reputation: 316
I have some images I want to analyze using a python script. They are stored as raw binary data files. They are in the following format. 16-bit unsigned, big endian, 592x600 pixels with a 520 byte header.
When I look at the .dat file in my OS (OS X yosemite) I see that the file is 710,920 bytes
This makes sense as (592 x 600 pixels) * (2 bytes per pixel) = 710,400 bytes. Thus the remainder is the 520 byte header.
I want to write a quick python script to generate an array of the pixel values. i.e. I want to ditch the header of the file and store the rest of the data as an array so that I can use something like PIL to then quickly convert into an image and output a jpg or png.
Just doing something really quick quick:
myfile = open('test.dat', 'rb')
data = myfile.read()
len(data)
trimdata = data[520:]
len(trimdata)
This gives me the raw data without the header.
From here I am unsure about the easiest way to parse the data into a 592x600 array that I can then use with PIL to export a quick greayscale image.
here is a link to the file incase that helps out: test.dat
Edit: Thanks for all the help - It appears the data was Little Endian not Big Endian after all. Cheers.
Upvotes: 1
Views: 6648
Reputation: 308530
PIL should be able to read that data directly, but heck if I can figure out how to do it. It doesn't take too many steps to do it indirectly though.
fmt = '>' + str(592*600) + 'H'
pix = struct.unpack(fmt, trimdata)
scaled_pix = ''.join(chr(p/256) for p in pix)
im = Image.fromstring('L', (592,600), scaled_pix, 'raw')
Edit: It looks like your sample picture is little-endian, not big-endian. Here's some corrected code. I also threw in automatic brightness scaling and gamma correction, since the full 16-bit scale wasn't being used.
fmt = '<' + str(592*600) + 'H'
pix = struct.unpack(fmt, trimdata)
lightest = max(pix)
scaled = ''.join(chr(int((float(p) / lightest)**(1/2.2) * 255)) for p in pix)
im = Image.fromstring('L', (592,600), scaled, 'raw')
Upvotes: 2
Reputation: 208077
You can convert them to quick JPEGs without writing any Python at all using ImageMagick's convert
from the commandline.
Just tell ImageMagick the size and bit depth and data offset and it can make a greyscale JPEG or 16-bit TIFF for you.
Something like this but I do not have my Mac to hand to test:
convert -size 592x600+520 -depth 16 GRAY:image.dat output.jpg
You may need -endian MSB
(or LSB) before the first filename too.
I am back at my Mac now, and the command to produce this image is:
convert -size 592x600+520 -depth 16 -endian MSB GRAY:image.dat -auto-level output.jpg
Upvotes: 2