Python地学分析 — GDAL读取HDF数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/XBR_2014/article/details/84594518

欢迎关注博主的微信公众号:“智能遥感”。

该公众号将为您奉上Python地学分析、爬虫、数据分析、Web开发、机器学习、深度学习等热门源代码。

本人的GitHub代码资料主页(持续更新中,多给Star,多Fork):

https://github.com/xbr2017

CSDN也在同步更新:

https://blog.csdn.net/XBR_2014

 本节通过Python + GDAL读取MODIS HDF格式的数据集。

作为一名遥感仁,在接触Python之前,一直使用IDL语言(遥感专业的一门语言)处理遥感数据,从几何校正、辐射定标、图像拼接、矢量裁剪栅格以及几乎所有的遥感图像运算、数据读取与常见格式的存储,无一不是通过IDL来实现的。在读研期间,甚至一度迷上用IDL制作读取与展示遥感数据的小软件界面,在毕业论文里竟然专门有一小节介绍该软件,现在想想,是多么的苍白无力

IDL是一门小众语言,冷了不能再冷的语言。墙裂推荐:不管你是否搞科研,还是做开发,对于没有计算机编程基础(C、C++、Java等)的小伙伴们,包括软妹子吆,Python是性价比最高的语言,没有之一,简单易懂,上手快。来吧,让我们一起高喊:“人生苦短,我用Python”!

顺便多说一句,既然我们使用了Python来处理遥感数据,那就准备抛弃ArcGis、MeteoInfo之类的二次开发环境,所以在今后的遥感数据处理介绍中,争取不使用arcpy包。因为要使用该模块,自己的本本上需要安装ArcGis软件,所以还是尽量不使用arcpy。

GDAL读取HDF

今天以较为经典的卫星数据MODIS为例,讲解如何使用Python+GDAL读取HDF文件,以及输出指定投影的tif文件,这里的tif是指Geotiff文件,其中包含地理信息。

HDF为分层数据格式的文件,可以使用GetSubDatasets函数获取它们的列表,然后使用该信息打开你想要的那个数据集。

例如,让我们打开MODIS文件中包含的子数据集。请注意,默认情况下,HDAL驱动程序不包含在GDAL中,因此如果你的GDAL版本不包含HDF支持,此示例将不适用于你。假设你可以使用HDF文件,第一步是将HDF文件作为数据集打开:

from osgeo import gdal

ds = gdal.Open('MYD13Q1.A2014313.h20v11.005.2014330092746.hdf')

现在,你可以获取此开放数据集中包含的子数据集列表。GetSubDatasets方法返回元组列表,每个子数据集有一个元组。每个元组按顺序包含子数据集的名称和描述。以下代码段获取此列表,然后打印出每个子数据集的名称和描述:

subdatasets = ds.GetSubDatasets()
print 'Number of subdatasets: {}'.format(len(subdatasets))

for sd in subdatasets:
    print 'Name: {0}\nDescription:{1}\n'.format(*sd)

前几行输出看起来像这样,并显示第一个子数据集的信息,即NDVI(归一化差异植被指数),这里只展示第一个,剩余11个就不放在这显示了:

Number of subdatasets: 12

Name: HDF4_EOS:EOS_GRID:"D:/osgeopy-data/Modis/MYD13Q1.A2014313.h20v11.005.2014330092746.hdf":MODIS_Grid_16DAY_250m_500m_VI:250m 16 days NDVI
Description:[4800x4800] 250m 16 days NDVI MODIS_Grid_16DAY_250m_500m_VI (16-bit integer)

要打开子数据集,请将其名称传递给gdalOpen。例如,这将获取与第一个子数据集对应的元组,从元组中获取第一个项(名称),然后使用它来打开子数据集:

ndvi_ds = gdal.Open(subdatasets[0][0])

同样,使用subdatasets[4] [0]表示打开第五个子数据集。一旦打开了这样的子数据集,它就可以像任何其他数据集一样处理。例如,你可以使用ndvi_ds.GetRasterBand(1)获取NDVI子数据集中的第一个波段。

如果没有特殊说明,HDF一般指hdf4,现在很多卫星数据开始使用hdf5格式存储,对于GDAL都可以去读取操作。当然,也有专门读取hdf4与hdf5的包,感兴趣的可以pip install安装一下相关的包就可以直接使用啦。这里给大家稍微展示一下具体代码使用:

# _*_ coding: utf-8 _*_
__author__ = 'xbr'
__date__ = '2018/11/28 22:47'

import h5py
import numpy as np

# HDF5的读取:
in_ds = h5py.File('FY4A-_AGRI--_N_DISK_1047E_L1-_FDI-_MULT_NOM_20180101024500_20180101025959_4000M_V0001.HDF','r')   
# 读取FY4A静止卫星第一波段数据
array = in_ds['NOMChannel01'][:]  
in_ds.close()

GDAL将数据保存为tif格式

遥感图像需要包含经纬度、空间分辨率、投影坐标等地理信息,这是普通图像所不具备的,一般彩色图像只有RGB三个波段,而遥感图像可以包含很多波段。下面的程序是读取MODIS归一化植被指数(NDVI),并将数据保存为带有地理信息的tif文件,必要的解释在代码中已给出。

# _*_ coding: utf-8 _*_
__author__ = 'xbr'
__date__ = '2018/11/26 17:48'

import gdal, osr


def array2raster(newRasterfn, rasterOrigin, xsize, ysize, array):
    """
     newRasterfn: 输出tif路径
     rasterOrigin: 原始栅格数据路径
     xsize: x方向像元大小
     ysize: y方向像元大小
     array: 计算后的栅格数据
    """
    cols = array.shape[1]  # 矩阵列数
    rows = array.shape[0]  # 矩阵行数
    originX = rasterOrigin[0]  # 起始像元经度
    originY = rasterOrigin[1]  # 起始像元纬度
    driver = gdal.GetDriverByName('GTiff')
    outRaster = driver.Create(newRasterfn, cols, rows, 1, gdal.GDT_Float32)
    # 括号中两个0表示起始像元的行列号从(0,0)开始
    outRaster.SetGeoTransform((originX, xsize, 0, originY, 0, ysize))
    # 获取数据集第一个波段,是从1开始,不是从0开始
    outband = outRaster.GetRasterBand(1)
    outband.WriteArray(array)
    outRasterSRS = osr.SpatialReference()
    # 代码4326表示WGS84坐标
    outRasterSRS.ImportFromEPSG(4326)
    outRaster.SetProjection(outRasterSRS.ExportToWkt())
    outband.FlushCache()


ds = gdal.Open('D:/osgeopy-data/Modis/MYD13Q1.A2014313.h20v11.005.2014330092746.hdf')

subdatasets = ds.GetSubDatasets()
print('Number of subdatasets: {}'.format(len(subdatasets)))
for sd in subdatasets:
    print('Name: {0}\nDescription:{1}\n'.format(*sd))

ndvi_ds = gdal.Open(subdatasets[0][0]).ReadAsArray()
dst_filename = "D:/nc/try.tif"
xsize = 0.0025
ysize = 0.0025

array2raster(dst_filename, [90, 75], xsize, ysize, ndvi_ds)

NDVI第一波段的灰色图像展示

NDVI第一波段的彩色图像展示

猜你喜欢

转载自blog.csdn.net/XBR_2014/article/details/84594518
今日推荐