使用PIL和Python读取原始图像

1 投票
3 回答
3903 浏览
提问于 2025-04-16 08:56

我有一个从NASA那里得到的7GB的图像,我想用Python和PIL写一个解码器。获取这个图像的页面上写着:

这些数据是以单通道16位整数(两个字节,长整型)格式存储的原始二进制文件,采用大端字节序,并且没有头部信息。

这里有关于如何写图像解码器的文档,但我在Python中处理图像的经验不多,现在完全不知道该怎么做。

3 个回答

0

你遇到的问题是,文件是16位像素的,而PIL(一个处理图像的库)只支持8位像素。这个问题在之前的讨论中也提到过,具体可以参考这封邮件:

http://osdir.com/ml/python.image/2006-11/msg00021.html

这件事是在四年前提到的,而今年又有人再次提起了这个话题:

http://mail.python.org/pipermail/image-sig/2010-April/006166.html

0

在查看 .../Imaging-1.1.7/PIL/Image.py 这个文件时,我发现了一些内容,特别是关于 PIL v1.1.7 的一些注释,最后提到了几个“实验模式”。

# --------------------------------------------------------------------
# Modes supported by this version

_MODEINFO = {
    # NOTE: this table will be removed in future versions.  use
    # getmode* functions or ImageMode descriptors instead.

    # official modes
    "1": ("L", "L", ("1",)),
    "L": ("L", "L", ("L",)),
    "I": ("L", "I", ("I",)),
    "F": ("L", "F", ("F",)),
    "P": ("RGB", "L", ("P",)),
    "RGB": ("RGB", "L", ("R", "G", "B")),
    "RGBX": ("RGB", "L", ("R", "G", "B", "X")),
    "RGBA": ("RGB", "L", ("R", "G", "B", "A")),
    "CMYK": ("RGB", "L", ("C", "M", "Y", "K")),
    "YCbCr": ("RGB", "L", ("Y", "Cb", "Cr")),

    # Experimental modes include I;16, I;16L, I;16B, RGBa, BGR;15, and
    # BGR;24.  Use these modes only if you know exactly what you're
    # doing...

}

所以看起来它对16位图像有一些支持。

UTSL - 使用源代码吧,卢克。

2

我经常处理原始图像,有些是16位的,有些是8位的灰度图像。

我发现把原始图像加载到numpy数组中,然后再转换成图像,通常是可行的。

如果字节顺序有问题,可以使用numpy数组的.byteswap()命令来解决这个问题,然后再转换成PIL图像对象。

下面这段代码是从一个可以读取8位原始图像到PIL的程序中提取的:

scene_infile = open(scene_infile_fullname,'rb')
scene_image_array = fromfile(scene_infile,dtype=uint8,count=rows*columns)
scene_image = Image.frombuffer("I",[columns,rows],
                                     scene_image_array.astype('I'),
                                     'raw','I',0,1)

在第二行,把uint8改成uint16,就可以加载一个2字节的原始图像,而不是1字节的。在第三行,图像被转换成4字节的整数,因为PIL的一些处理函数似乎对这种类型的支持更好。

撰写回答