保存 3D 蒙版阵列

Posted

技术标签:

【中文标题】保存 3D 蒙版阵列【英文标题】:Saving 3D masked array 【发布时间】:2015-08-04 14:32:56 【问题描述】:

我正在尝试使用以下代码将 3D masked_array 的数据保存到文件中:

print "Writing results to a file..."
format = "GTiff"
driver = gdal.GetDriverByName(format)

fileName = 'path_to_folder/FLENAME.tif'
NumberOfBands = 46

new_dataset = driver.Create( fileName, 2400, 2400, NumberOfBands,gdal.GDT_Float32)
new_dataset = None

for band in range( NumberOfBands ):
    new_dataset.GetRasterBand(band + 1).WriteArray(DATA[band,:,:])

这样我得到了错误: 'NoneType' object has no attribute 'GetRasterBand'

我在没有 GetRasterband 的情况下试了一下,得到了'NoneType' object is not attainable

最初尝试np.save 作为替代方法,但未实现,建议尝试此方法。

任何帮助将不胜感激。

谢谢。

更新: 由于凯文的建议,原始错误得到了解决。 然而,在保存文件后,检查它是否包含所需的数据,发现所有值都是 0.0。

-使用 Mike T 的建议解决了这个问题。然而,它似乎只保存了原始的未屏蔽数组,而不是所需的masked_array

有问题的数据是表面反射率的蒙版 (masked_array) MODIS 文件。不需要的像素是被屏蔽的值。

【问题讨论】:

使用immediate problem fixed - 你需要生成一个Minimal, Complete and Verifiable example - 特别是在这里我们需要知道DATA 变量中的内容 - 至少在某些情况下确实存在非零值乐队的? 谢谢你,我已经更新了帖子。我希望这就是你的意思。 【参考方案1】:

我推荐阅读Gotchas in the GDAL and OGR Python Bindings。一般来说,您可以通过在顶部启用异常来更好地调试:

gdal.UseExceptions()

至于为什么您看到所有 0.0 值是您可能需要通过取消引用 bandnew_dataset 来编写数据集。这可以在底部完成:

new_dataset = band = None  # save, close

要写入掩码数组,您需要设置 NoDataValue。例如,如果您希望 -9999.0 表示没有数据,则:

NODATA = -9999
for bdx in range(new_dataset.RasterCount):
    band = new_dataset.GetRasterBand(bdx + 1)
    band.SetNoDataValue(NODATA)
    band.WriteArray(DATA[bdx].filled(NODATA))
new_dataset = band = None  # save, close

您也可以考虑使用更 Pythonic 的东西,请参阅 rasterio。例如:

import rasterio
with rasterio.open(fileName, 'w', 'GTiff', 2400, 2400, NumberOfBands, dtype='f',
                   masked=True, nodata=NODATA) as r:
    r.write(DATA.astype('f'))

【讨论】:

在末尾添加该行确实解决了 0.0 值问题,谢谢。我之前忘了提(我会编辑我的帖子)我要保存的数据是 masked_array 它现在正在保存一个文件,但它是没有掩码的原始文件 我也尝试了你的 rasterio 建议,但是该模块没有实现,不幸的是我没有必要的权限来在我工作的地方安装它。 谢谢,NODATA 部分是否屏蔽了数组?因为在我的情况下,DATA 是一个数组,其中质量差的像素已被屏蔽,而填充值 (32767) 的像素也已被屏蔽,或者我应该将第二个蒙版更改为 NODATA? 很抱歉刚刚意识到 -99999 的用途。当我似乎运行它时,它会稍微改变输出但并没有掩盖我以前拥有的所有东西?它似乎掩盖了质量罚款,但没有掩盖填充值。当我使用 NODATA=0 运行代码时,它具有所需的输出,但问题是所有掩码值现在都是 0,这会影响平均值等。【参考方案2】:
new_dataset = None

尝试删除此行。否则,在此之后访问new_dataset 属性的所有尝试都将失败。

【讨论】:

这似乎解决了NoneType 错误,谢谢。但它似乎写了一个空白文件,因为所有值都是 0.0? 抱歉,我不能说我对gdal 有任何经验...我希望第一个问题后面不会有任何其他问题。【参考方案3】:

设法通过将数据掩码更改为:

mask = np.where( quality == 0, 1, 0 )

然后在保存时将掩码与原始数据相乘,如下所示:

for band in range( NumberOfBands ):
    out_band=new_dataset.GetRasterBand(band + 1)
    out_band.WriteArray( databand[band,:,:] * mask[band] )

new_dataset = band = None

我认为问题可能在于将掩码应用于原始数据数组会生成一个掩码数组,其中包含所有原始数据值和真假值的掩码。在文件中保存和读回时,忽略了已保存数组的掩码部分,然后绘制了所有原始值。如上所述,通过将掩码乘以数据来解决此问题,从而仅保存掩码允许的值并解决问题。

感谢您的帮助。

【讨论】:

以上是关于保存 3D 蒙版阵列的主要内容,如果未能解决你的问题,请参考以下文章

延伸的3D阵列

如何将蒙版应用于保存图像(swift3)

保存阵列猫鼬

将阵列保存到设备

如何保存阵列?

将 GPS 线保存到阵列中