如何避免使用"没有数据"在图像堆叠

时间:2014-05-18 22:14:18

标签: python-2.7 image-processing numpy gdal

我是使用python的新手。我的问题似乎很容易,但不幸的是我无法找到解决方案。我有一组Geotiff格式的图像,它们的大小相同,像素值介于0到5之间,非值为-9999。我想用Numpy和Gdal做一些图像堆叠。我正在寻找一种堆叠算法,其中使用每个图像中具有0到5之间的值的那些像素,并且在计算平均值时不使用无数据值。例如,如果我有30个图像,并且对于其中两个图像,则索引图像[20,20]的值为2&分别为3,对于其余图像,在该指数处为-9999。我希望单频段输出图像在此索引处为2.5。我想知道是否有人知道如何做到这一点?

非常感谢任何建议或提示。

编辑: 让我澄清一点。这是一个示例:

import numpy as np

myArray = np.random.randint(5,size=(3,3,3))
myArray [1,1,1] = -9999

myArray
>> array([[[    0,     2,     1],
           [    1,     4,     1],
           [    1,     1,     2]],

          [[    4,     2,     0],
           [    3, -9999,     0],
           [    1,     0,     3]],

          [[    2,     0,     3],
           [    1,     3,     4],
           [    2,     4,     3]]])

假设myArray是一个包含三个图像的ndarray,如下所示:

Image_01 = myArray[0]
Image_02 = myArray[1]
Image_03 = myArray[2]

最终堆叠的图片是:

stackedImage = myArray.mean(axis=0)

>> array([[  2.00000000e+00,   1.33333333e+00,   1.33333333e+00],
          [  1.66666667e+00,  -3.33066667e+03,   1.66666667e+00],
          [  1.33333333e+00,   1.66666667e+00,   2.66666667e+00]])

但我希望它是这样的:

array([[  2.00000000e+00,   1.33333333e+00,   1.33333333e+00],
       [  1.66666667e+00,              3.5,   1.66666667e+00],
       [  1.33333333e+00,   1.66666667e+00,   2.66666667e+00]])

1 个答案:

答案 0 :(得分:2)

Masked arrays是处理缺失值或无效值的好方法。屏蔽数组具有.data属性,其中包含每个元素的数值,以及.mask属性,用于指定哪些值应被视为“无效”并被忽略。

以下是使用您的数据的完整示例:

import numpy as np

# your example data, with a bad value at [1, 1, 1]
M = np.array([[[    0,     2,     1],
               [    1,     4,     1],
               [    1,     1,     2]],

              [[    4,     2,     0],
               [    3, -9999,     0],
               [    1,     0,     3]],

              [[    2,     0,     3],
               [    1,     3,     4],
               [    2,     4,     3]]])

# create a masked array where all of the values in `M` that are equal to
# -9999 are masked
masked_M = np.ma.masked_equal(M, -9999)

# take the mean over the first axis
masked_mean = masked_M.mean(0)

# `masked_mean` is another `np.ma.masked_array`, whose `.data` attribute
# contains the result you're looking for
print masked_mean.data
# [[ 2.          1.33333333  1.33333333]
#  [ 1.66666667  3.5         1.66666667]
#  [ 1.33333333  1.66666667  2.66666667]]