在Python中读取16位无符号大端原始图像文件数据
我有一些图片想用一个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
补充:感谢大家的帮助 - 看来数据实际上是小端格式,而不是大端格式。谢谢。
2 个回答
你可以使用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
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')