Python:(Sentinel-1)如何解析SNAP输出的HDF5文件并输出为GeoTIFF?

2023-12-19 04:20

本文主要是介绍Python:(Sentinel-1)如何解析SNAP输出的HDF5文件并输出为GeoTIFF?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

博客已同步微信公众号:GIS茄子;若博客出现纰漏或有更多问题交流欢迎关注GIS茄子,或者邮箱联系(推荐-见主页).
微信公众号
Python:(Sentinel-1)如何解析SNAP输出的HDF5文件并输出为GeoTIFF?

01 前言

最近在了解sentinel-1的预处理过程,但是由于影响太大了,常规的GeoTIFF无法输出预处理结果,BigTIFF输出时似乎也遇到了一些问题(好在后面解决了,所以正好做一下HDF5文件输出的TIFF文件与BigTIFF文件的对比),对于输出的HDF5文件则完全没有问题。但是问题在于HDF5文件的结构尚不了解,因此对于其中的地理信息如何提取很关键(当然你可以使用ArcGIS或者ENVI打开其中的VV和VH波段,但是都无法自动读取到其中的地理信息或者坐标系信息)。

02 解析HDF5文件

由于我处理的Sentinel-1时IW的VV和VH,因此输出的HDF5文件存在两个波段:

VV和VH相关波段信息

下方是关于这个地理信息的参数(ps:找了我好久,里面的属性信息真的太多了,而且官方文档似乎对于这个HDF5文件的结构并没有说明,真的象拔蚌了🌿):

元数据

那么我们来解释一下其中关键的8个参数:
first_near_lat = 30.710711909958782; // double
first_near_long = 106.20485428671394; // double
first_far_lat = 30.710711909958782; // double
first_far_long = 109.12878070499457; // double
last_near_lat = 28.79451557740343; // double
last_near_long = 106.20485428671394; // double
last_far_lat = 28.79451557740343; // double
last_far_long = 109.12878070499457; // double

未必准确,但是目前从得到的结果与BigTIFF对比是几乎完全一致的地理位置(如果有更详细的文档或者准确信息,请微信公众号或者邮箱联系我,这对我帮助很大)。

first 表示第一行,last表示最后一行,near表示扫描线的起点,far表示扫描线的终点。

其实这里搞不懂为什么要有四个点位的信息?一般的角点信息只需要左上和右下两个点位就足够了,算了我不是这个方向的多说无益。

那么,其实说到这里其实已经搞定了,WGS84坐标系有了,仿射参数也已经有了,VV和VH波段数据也有了。

03 代码

# @Author   : ChaoQiezi
# @Time     : 2023/12/18  8:40
# @Email    : chaoqiezi.one@qq.com"""
This script is used to 读取HDF5、BigTIFF文件
"""import os.path
import h5py
from osgeo import gdal, osr# 准备
h5_path = r'H:\Datasets\Objects\TobacooLeafRecognition\Data\HDF5\S1A_IW_GRDH_1SDV_20220602T103546_20220602T103611_043483_05311F_8F62_NR_Orb_Cal_Spk_TC_dB.h5'
tiff_path = r'H:\Datasets\Objects\TobacooLeafRecognition\Data\BigTIFF\S1A_IW_GRDH_1SDV_20220602T103546_20220602T103611_043483_05311F_8F62_NR_Orb_Cal_Spk_TC_dB.tif'
out_dir = r'H:\Datasets\Objects\TobacooLeafRecognition\Data'
out_path = os.path.join(out_dir, 'vv_vh.tiff')
vh_name = 'bands/Sigma0_VH_db'
vv_name = 'bands/Sigma0_VV_db'
metadata_name = 'metadata/Abstracted_Metadata'
lon_min_name = 'first_near_long'
lon_max_name = 'last_far_long'
lat_min_name = 'last_far_lat'
lat_max_name = 'first_near_lat'
lon_res_name = 'lon_pixel_res'
lat_res_name = 'lat_pixel_res'# 探索HDF5文件
with h5py.File(h5_path) as h5:vh, vv = h5[vh_name][:], h5[vv_name][:]metadata = h5[metadata_name]lon_min = metadata.attrs[lon_min_name]lon_max = metadata.attrs[lon_max_name]lat_min = metadata.attrs[lat_min_name]lat_max = metadata.attrs[lat_max_name]lon_res = metadata.attrs[lon_res_name]lat_res = metadata.attrs[lat_res_name]
# 提取栅格信息
rows, cols = vv.shape
transform = [lon_min, lon_res, 0, lat_max, 0, -lon_res]
# 定义地理信息(WGS84)
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)  # WGS84
# 输出
driver = gdal.GetDriverByName('GTiff')
ds = driver.Create(out_path, cols, rows, 2, gdal.GDT_Float32)
ds.SetProjection(srs.ExportToWkt())  # 设置坐标系
ds.SetGeoTransform(transform)  # 设置仿射参数
[ds.GetRasterBand(_ix+1).WriteArray(_band) for _ix, _band in enumerate([vv, vh])]  # 写入数据
ds.FlushCache()
ds = None
# 探索BigTIFF文件
ds = gdal.Open(tiff_path)
bands = ds.ReadAsArray()
proj = ds.GetProjection()
tiff_transform = ds.GetGeoTransform()
print('HDF5的proj: {}'.format(srs.ExportToWkt()))
print('BigTIFF的proj: {}'.format(proj))
print('HDF5的仿射变换参数: {}'.format(transform))
print('BigTIFF的proj: {}'.format(tiff_transform))

输出:

HDF5的proj: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]BigTIFF的proj: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]HDF5的仿射变换参数: [106.20485428671394, 8.983152841195215e-05, 0, 30.710711909958782, 0, -8.983152841195215e-05]BigTIFF的proj: (106.20485428671394, 8.983152841195215e-05, 0.0, 30.710711909958782, 0.0, -8.983152841195215e-05)

基本上一致

HDF5输出与BigTIFF对比

这篇关于Python:(Sentinel-1)如何解析SNAP输出的HDF5文件并输出为GeoTIFF?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/510879

相关文章

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

python使用watchdog实现文件资源监控

《python使用watchdog实现文件资源监控》watchdog支持跨平台文件资源监控,可以检测指定文件夹下文件及文件夹变动,下面我们来看看Python如何使用watchdog实现文件资源监控吧... python文件监控库watchdogs简介随着Python在各种应用领域中的广泛使用,其生态环境也

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python

python 字典d[k]中key不存在的解决方案

《python字典d[k]中key不存在的解决方案》本文主要介绍了在Python中处理字典键不存在时获取默认值的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录defaultdict:处理找不到的键的一个选择特殊方法__missing__有时候为了方便起见,

使用Python绘制可爱的招财猫

《使用Python绘制可爱的招财猫》招财猫,也被称为“幸运猫”,是一种象征财富和好运的吉祥物,经常出现在亚洲文化的商店、餐厅和家庭中,今天,我将带你用Python和matplotlib库从零开始绘制一... 目录1. 为什么选择用 python 绘制?2. 绘图的基本概念3. 实现代码解析3.1 设置绘图画

Python pyinstaller实现图形化打包工具

《Pythonpyinstaller实现图形化打包工具》:本文主要介绍一个使用PythonPYQT5制作的关于pyinstaller打包工具,代替传统的cmd黑窗口模式打包页面,实现更快捷方便的... 目录1.简介2.运行效果3.相关源码1.简介一个使用python PYQT5制作的关于pyinstall

使用Python实现大文件切片上传及断点续传的方法

《使用Python实现大文件切片上传及断点续传的方法》本文介绍了使用Python实现大文件切片上传及断点续传的方法,包括功能模块划分(获取上传文件接口状态、临时文件夹状态信息、切片上传、切片合并)、整... 目录概要整体架构流程技术细节获取上传文件状态接口获取临时文件夹状态信息接口切片上传功能文件合并功能小

python实现自动登录12306自动抢票功能

《python实现自动登录12306自动抢票功能》随着互联网技术的发展,越来越多的人选择通过网络平台购票,特别是在中国,12306作为官方火车票预订平台,承担了巨大的访问量,对于热门线路或者节假日出行... 目录一、遇到的问题?二、改进三、进阶–展望总结一、遇到的问题?1.url-正确的表头:就是首先ur