在python中读取卫星图像文件时优化性能

2024-03-29 06:18:46 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

[B1][B2][B3][B4][B5][B1][B2][B3][B4][B5]。。。以此类推(基本上是5个字节-每个频带一个字节-从图像左上角开始的每个像素)。在

我需要在python3.2(windows7 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库,但我不确定如何使用它们,或者它们是否能提供任何帮助。在

由于图像中的条带数量也是可变的,我发现很难找到一种方法来快速读取文件并将图像分割成各个部分。在

我曾经尝试过在循环中搞乱list方法(使用slices,不使用slices,只使用append,只使用extend等),这并没有特别大的影响,因为所涉及的迭代次数(width*height*numberOfBands)会损失主要时间。在

任何建议或建议都会很有帮助。谢谢。在


Tags: 方法in图像fordata头文件波段像素
3条回答

我怀疑重复的扩展不是很好最好先分配所有的

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

我的测量结果显示没有减速

^{pr2}$

如果您可以找到一个快速函数来加载大python列表(或numpy数组)中的二进制数据,那么可以使用切片表示法对数据进行反交错:

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

有帮助吗?在

标准PIL

要从文件加载图像,请使用图像模块中的“打开”函数。在

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

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

^{pr2}$

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

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

拆分和合并波段

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

所以我认为你应该简单地推导出模式,然后相应地分解。在

PIL与光谱Python(间谍Python模块)

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

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

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

希望这有帮助。在

相关问题 更多 >