4

我有一个以波段交错像素 (BIP) 格式存储的多波段卫星图像以及一个单独的头文件。头文件提供了图像中的行数和列数,以及波段数(可以超过标准3)等详细信息。

图像本身是这样存储的(假设一个 5 波段图像):

[B1][B2][B3][B4][B5][B1][B2][B3][B4][B5] ... 等等(基本上 5 个字节 - 每个波段一个 - 每个像素开始从图像的左上角)。

我需要在 Python 3.2(在 Windows 7 64 位上)中将这些波段中的每一个分离为 PIL 图像,目前我认为我正在错误地解决问题。我目前的代码如下:

def OpenBIPImage(file, width, height, numberOfBands):
    """
    Opens a raw image file in the BIP format and returns a list
    comprising each band as a separate PIL image.
    """
    bandArrays = []
    with open(file, 'rb') as imageFile:
        data = imageFile.read()
    currentPosition = 0
    for i in range(height * width):
        for j in range(numberOfBands):
            if i == 0:
                bandArrays.append(bytearray(data[currentPosition : currentPosition + 1]))
            else:
                bandArrays[j].extend(data[currentPosition : currentPosition + 1])
            currentPosition += 1
    bands = [Image.frombytes('L', (width, height), bytes(bandArray)) for bandArray in bandArrays]
    return bands

这段代码打开 BIP 文件的时间太长了,肯定有更好的方法来做到这一点。我也有 numpy 和 scipy 库,但我不确定如何使用它们,或者它们是否会以任何方式提供帮助。

由于图像中的波段数量也是可变的,我发现很难找到一种快速读取文件并将图像分成其组成波段的方法。

只是为了记录,我尝试在循环中弄乱列表方法(使用切片,不使用切片,仅使用追加,仅使用扩展等),它并没有特别重要,因为主要时间丢失了,因为涉及的迭代次数 - (width * height * numberOfBands)。

任何建议或建议都会非常有帮助。谢谢。

4

3 回答 3

4

如果你能找到一个快速的函数来将二进制数据加载到一个大的 python 列表(或 numpy 数组)中,你可以使用切片符号对数据进行去交错:

band0 = biglist[::nbands]
band1 = biglist[1::nbands]
....

这有帮助吗?

于 2011-09-02T11:15:12.317 回答
1

标准 PIL

要从文件加载图像,请使用 Image 模块中的 open 函数。

>>> import Image
>>> im = Image.open("lena.ppm")

如果成功,此函数将返回一个 Image 对象。您现在可以使用实例属性来检查文件内容。

>>> print im.format, im.size, im.mode
PPM (512, 512) RGB

格式属性标识图像的来源。如果图像不是从文件中读取的,则将其设置为无。size 属性是一个包含宽度和高度(以像素为单位)的 2 元组。mode 属性定义图像中波段的数量和名称,以及像素类型和深度。常见的模式是灰度图像的“L”(亮度)、真彩色图像的“RGB”和印前图像的“CMYK”。

Python 成像库还允许您处理多波段图像的各个波段,例如 RGB 图像。split 方法创建一组新图像,每个图像都包含来自原始多波段图像的一个波段。合并函数接受一个模式和一个图像元组,并将它们组合成一个新图像。以下示例交换了 RGB 图像的三个波段:

拆分和合并波段

r, g, b = im.split()
im = Image.merge("RGB", (b, g, r))

所以我认为你应该简单地推导出模式,然后进行相应的拆分。

PIL 与 Spectral Python(SPy python 模块)

但是,正如您在下面的评论中指出的那样,您处理的不是具有 3 个波段的普通 RGB 图像。因此,为了解决这个问题,SpectralPython(一个需要 PIL 的纯 python 模块)可能正是您正在寻找的。

具体来说 - http://spectralpython.sourceforge.net/class_func_ref.html#spectral.io.bipfile.BipFile

spectral.io.bipfile.BipFile 处理带交错像素 (BIP) 格式的图像文件。

希望这可以帮助。

于 2011-09-02T05:42:40.780 回答
1

我怀疑extend的重复不好最好先全部分配

def OpenBIPImage(file, width, height, numberOfBands):
    """
    Opens a raw image file in the BIP format and returns a list
    comprising each band as a separate PIL image.
    """
    bandArrays = []
    with open(file, 'rb') as imageFile:
        data = imageFile.read()
    currentPosition = 0
    for j in range(numberOfBands):
        bandArrays[j]= bytearray(b"\0"*(height * width)):


    for i in xrange(height * width):
        for j in xrange(numberOfBands):
                bandArrays[j][i]=data[currentPosition])
            currentPosition += 1
    bands = [Image.frombytes('L', (width, height), bytes(bandArray)) for bandArray in bandArrays]
    return bands

我的测量结果并没有显示出这样的减速

def x():
    height,width,numberOfBands=1401,801,6
    before = time.time()
    for i in range(height * width):
        for j in range(numberOfBands):
            pass
    print (time.time()-before)

>>> x()
0.937999963760376

已编辑

于 2011-09-02T09:50:46.057 回答