从python中读取16位无符号大端原始图像文件中的数据

时间:2014-10-24 06:01:29

标签: python image image-processing python-imaging-library

我想要使用python脚本分析一些图像。 它们存储为原始二进制数据文件。它们采用以下格式。 16位无符号,大端,592x600像素,带有520字节的标头。

当我查看操作系统(OS X yosemite)中的.dat文件时,我发现文件是710,920字节

这是有意义的(592 x 600像素)*(每像素2个字节)= 710,400字节。因此,余数是520字节的标题。

我想编写一个快速python脚本来生成像素值数组。即我想丢弃文件的标题并将其余数据存储为数组,以便我可以使用像PIL这样的东西然后快速转换为图像并输出jpg或png。

快速做一些事情:

myfile = open('test.dat', 'rb') 

data = myfile.read()

len(data)

trimdata = data[520:]

len(trimdata)

这为我提供了没有标题的原始数据。

从这里我不确定将数据解析为592x600阵列的最简单方法,然后我可以使用PIL导出快速的灰度图像。

这是一个指向文件的链接,可以帮助: test.dat

编辑:感谢所有帮助 - 看来数据显然是Little Endian而不是Big Endian。欢呼声。

2 个答案:

答案 0 :(得分:1)

您可以使用命令行中的ImageMagick convert将它们转换为快速JPEG而无需编写任何Python。

告诉ImageMagick大小和位深度以及数据偏移量,它可以为您制作灰度JPEG或16位TIFF。

这样的东西,但我没有让我的Mac进行测试:

convert -size 592x600+520 -depth 16 GRAY:image.dat output.jpg

在第一个文件名之前,您可能还需要-endian MSB(或LSB)。

我现在回到了我的Mac,生成这张图片的命令是:

convert -size 592x600+520 -depth 16 -endian MSB GRAY:image.dat -auto-level output.jpg

enter image description here

答案 1 :(得分:1)

PIL 能够直接读取该数据,但是如果我能弄明白该怎么做的话。尽管如此,它并没有采取太多步骤来间接地做到这一点。

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')

编辑:看起来您的示例图片是小端,而不是大端。这里有一些更正后的代码。我还投入了自动亮度缩放和伽马校正,因为没有使用完整的16位音阶。

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')

enter image description here