Python遥感开发之FY的批量处理

news2024/12/23 18:08:17

Python遥感开发之FY的批量处理

  • 0 FY遥感数据
  • 1 批量提取数据
  • 2 批量拼接TIF数据
  • 3 批量HAM转WGS投影(重要)
  • 4 批量掩膜裁剪

介绍FY数据的格式,以及FY数据的批量提取数据、批量拼接数据、批量投影转换、批量掩膜裁剪等操作。
本博客代码参考《 Hammer坐标系转换到WGS1984,以处理FY3D/MERSI NVI数据为例。FY3D/MERSI NVI空间分辨率250m,全球 10°×10°分幅 》,非常感谢博主公开代码!!!


0 FY遥感数据

  • 本博客以《MERSI-II植被指数旬产品(1000M)》数据处理为例子,“FY3D_MERSI_00A0_L3_NVI_MLT_HAM_20191130_AOTD_1000M_MS.HDF”,其中FY3D是卫星名字、MERSI是仪器名称、00A0是数据区域类型(也是该影像的经纬度范围)、L3是数据级别、NVI是数据名称、MLT是通道名称、HAM是投影方式、AOTD是时段类型、1000M是分辨率、HDF是数据名称格式。
  • 最核心最难的就是HAM投影如何转换成常见的WGS投影

1 批量提取数据

MERSI-II植被指数旬产品(1000M)数据包含如下波段,根据需要自己取
在这里插入图片描述
切记
在这里插入图片描述
完整代码如下所示:

import os
from osgeo import gdal
import h5py

def get_data_list(file_path, out = ""):
    list1 = []  # 文件的完整路径
    if os.path.isdir(file_path):
        fileList = os.listdir(file_path)
        if out != "":
            for f in fileList:
                out_data = out + "\\" + f
                out_data = out_data.replace(".HDF", "_ndvi.tif")
                list1.append(out_data)
        else:
            for f in fileList:
                pre_data = file_path + '\\' + f  # 文件的完整路径
                list1.append(pre_data)
        return list1

import numpy as np

def HDF2Tif(in_file,out_file):
    hdf_ds = h5py.File(in_file, "r")
    if type(hdf_ds.attrs['Left-Top X']) is np.ndarray:
        left_x = hdf_ds.attrs['Left-Top X'][0]
    else:
        left_x = float(hdf_ds.attrs['Left-Top X'])

    if type(hdf_ds.attrs['Left-Top Y']) is np.ndarray:
        left_y = hdf_ds.attrs['Left-Top Y'][0]
    else:
        left_y = float(hdf_ds.attrs['Left-Top Y'])

    res_x = hdf_ds.attrs['Resolution X'][0]
    res_y = hdf_ds.attrs['Resolution Y'][0]
    ndviname = list(hdf_ds.keys())[6] #5是evi 6是ndvi
    # print(list(hdf_ds.keys()))

    ndvi_ds = hdf_ds[ndviname]
    rows = ndvi_ds.shape[0]
    cols = ndvi_ds.shape[1]
    data = ndvi_ds[()]
    driver = gdal.GetDriverByName("GTiff")
    outds = driver.Create(out_file, cols, rows, 1, gdal.GDT_Int16)
    outds.SetGeoTransform(
        (float(left_x) * 1000,#切记250m的分辨率需要除以4
         float(res_x) * 1000,
         0,
         float(left_y) * 1000,#切记250m的分辨率需要除以4
         0,
         -1 * float(res_y) * 1000)
    )
    proj = 'PROJCS["World_Hammer",GEOGCS["Unknown datum based upon the custom spheroid",DATUM["Not_specified_based_on_custom_spheroid",SPHEROID["Custom spheroid",6363961,0]],PRIMEM["Greenwich",0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hammer_Aitoff"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],UNIT["metre",1],AXIS["Easting",EAST],AXIS["Northing",NORTH]]'
    outds.SetProjection(proj)
    outband = outds.GetRasterBand(1)
    outband.WriteArray(data)
    pass

if __name__ == '__main__':
    infile = r"C:\Users\Administrator\Desktop\HDF"
    outfile = r"C:\Users\Administrator\Desktop\01提取ndvi"
    infile_list = get_data_list(infile)
    outfile_list = get_data_list(infile,outfile)
    for in_file,out_file in zip(infile_list,outfile_list):
        print(in_file)
        HDF2Tif(in_file,out_file)

在这里插入图片描述

在这里插入图片描述

2 批量拼接TIF数据

import os
from osgeo import gdal

def get_data_list(file_path, out = ""):
    list1 = []  # 文件的完整路径
    if os.path.isdir(file_path):
        fileList = os.listdir(file_path)
        if out != "":
            for f in fileList:
                out_data = out + "\\" + f
                out_data = out_data.replace(".HDF", "_ndvi.tif")
                list1.append(out_data)
        else:
            for f in fileList:
                pre_data = file_path + '\\' + f  # 文件的完整路径
                list1.append(pre_data)
        return list1

def get_same_list(image, infile_list):
    infile_list02 = []
    for data in infile_list:
        if image in data:
            # print("----", data)
            infile_list02.append(data)
    return infile_list02

def get_same_image_list(infile_list):
    image_list= []
    for file in infile_list:
        filename = file[-31:-23]
        if filename not in image_list:
            image_list.append(filename)
    return list(set(image_list))

def pinjie(infile_list,outfile):
    ds = gdal.Open(infile_list[0])
    cols = ds.RasterXSize
    rows = ds.RasterYSize
    ingeo = ds.GetGeoTransform()
    proj = ds.GetProjection()
    minx = ingeo[0]
    maxy = ingeo[3]
    maxx = ingeo[0] + ingeo[1] * cols
    miny = ingeo[3] + ingeo[5] * rows
    ds = None
    for file in infile_list[1:]:
        ds = gdal.Open(file)
        cols = ds.RasterXSize
        rows = ds.RasterYSize
        geo = ds.GetGeoTransform()
        minx_ = geo[0]
        maxy_ = geo[3]
        maxx_ = geo[0] + geo[1] * cols
        miny_ = geo[3] + geo[5] * rows
        minx = min(minx, minx_)
        maxy = max(maxy, maxy_)
        maxx = max(maxx, maxx_)
        miny = min(miny, miny_)
        geo = None
        ds = None
    newcols = int((maxx - minx) / abs(ingeo[1]))
    newrows = int((maxy - miny) / abs(ingeo[5]))
    driver = gdal.GetDriverByName("GTiff")
    outds = driver.Create(outfile, newcols, newrows, 1, gdal.GDT_Int16)
    outgeo = (minx, ingeo[1], 0, maxy, 0, ingeo[5])
    outds.SetGeoTransform(outgeo)
    outds.SetProjection(proj)
    outband = outds.GetRasterBand(1)
    for file in infile_list:
        ds = gdal.Open(file)
        data = ds.ReadAsArray()
        geo = ds.GetGeoTransform()
        x = int(abs((geo[0] - minx) / ingeo[1]))
        y = int(abs((geo[3] - maxy) / ingeo[5]))
        outband.WriteArray(data, x, y)
        ds = None
    outband.FlushCache()
    pass
if __name__ == '__main__':

    infile = r"C:\Users\Administrator\Desktop\01提取ndvi"
    outfile = r"C:\Users\Administrator\Desktop\02拼接"
    infile_list = get_data_list(infile)
    image_name_list = get_same_image_list(infile_list)
    print(image_name_list)
    for name in image_name_list:
        print(name)
        infile_list02 = get_same_list(name, infile_list)
        pinjie(infile_list02,outfile+"\\"+name+".tif")

在这里插入图片描述

3 批量HAM转WGS投影(重要)

切记:代码中出现的0.01表示1000m分辨率,如果需要换成250m分辨率,请根据代码注释自行更换。
在这里插入图片描述
在这里插入图片描述

完整代码如下:

import os
from osgeo import gdal
import numpy as np
import math
from osgeo import osr

def get_data_list(file_path, out = ""):
    list1 = []  # 文件的完整路径
    if os.path.isdir(file_path):
        fileList = os.listdir(file_path)
        if out != "":
            for f in fileList:
                out_data = out + "\\" + f
                # out_data = out_data.replace(".HDF", "_ndvi.tif")
                list1.append(out_data)
        else:
            for f in fileList:
                pre_data = file_path + '\\' + f  # 文件的完整路径
                list1.append(pre_data)
        return list1

def H2W(infile,outfile):
    ds = gdal.Open(infile)
    ingeo = ds.GetGeoTransform()
    cols = ds.RasterXSize
    rows = ds.RasterYSize
    or_x = ingeo[0]
    or_y = ingeo[3]
    end_x = ingeo[0] + cols * ingeo[1]
    end_y = ingeo[3] + rows * ingeo[5]
    # X方向分块
    xblocksize = int((cols + 1) / 5)
    # Y方向分块
    yblocksize = int((rows + 1) / 5)
    lon_max = -360
    lon_min = 360
    lat_max = -90
    lat_min = 90
    for i in range(0, rows + 1, yblocksize):
        if i + yblocksize < rows + 1:
            numrows = yblocksize
        else:
            numrows = rows + 1 - i
        for j in range(0, cols + 1, xblocksize):
            if j + xblocksize < cols + 1:
                numcols = xblocksize
            else:
                numcols = cols + 1 - j
            # 计算所有点的Hammer坐标系下X方向坐标数组
            x = ingeo[0] + j * ingeo[1]
            y = ingeo[3] + i * ingeo[5]
            xgrid, ygrid = np.meshgrid(np.linspace(x, x + numcols * ingeo[1], num=numcols),
                                       np.linspace(y, y + numrows * ingeo[5], num=numrows))
            # 将hammer坐标转化为经纬度坐标
            # 首先将Hammer转化为-1到1
            xgrid = np.where(xgrid > (18000.0 * 1000.0), (18000.0 * 1000.0) - xgrid, xgrid)
            xgrid = xgrid / (18000.0 * 1000.0)
            ygrid = np.where(ygrid > (9000.0 * 1000.0), (9000.0 * 1000.0) - ygrid, ygrid)
            ygrid = ygrid / (9000.0 * 1000.0)
            z = np.sqrt(1 - np.square(xgrid) / 2.0 - np.square(ygrid) / 2.0)
            lon = 2 * np.arctan(np.sqrt(2) * xgrid * z / (2.0 * (np.square(z)) - 1))
            xgrid = None
            lat = np.arcsin(np.sqrt(2) * ygrid * z)
            ygrid = None
            z = None
            lon = lon / math.pi * 180.0
            lat = lat / math.pi * 180.0
            lon[lon < 0] = lon[lon < 0] + 360.0
            # lat[lat<0]=lat[lat<0]+180
            lon_max = max(lon_max, np.max(lon))
            lon_min = min(lon_min, np.min(lon))
            lon = None
            lat_max = max(lat_max, np.max(lat))
            lat_min = min(lat_min, np.min(lat))
            lat = None

    newcols = math.ceil((lon_max - lon_min) / 0.01)#切记250m的分辨率需要把0.01换成0.0025
    newrows = math.ceil((lat_max - lat_min) / 0.01)#切记250m的分辨率需要把0.01换成0.0025
    driver = gdal.GetDriverByName("GTiff")
    outds = driver.Create(outfile, newcols, newrows, 1, gdal.GDT_Int16)
    geo2 = (lon_min, 0.01, 0, lat_max, 0, -1 * 0.01)#切记250m的分辨率需要把0.01换成0.0025
    oproj_srs = osr.SpatialReference()
    proj_4 = "+proj=longlat +datum=WGS84 +no_defs"
    oproj_srs.ImportFromProj4(proj_4)
    outds.SetGeoTransform(geo2)
    outds.SetProjection(oproj_srs.ExportToWkt())
    outband = outds.GetRasterBand(1)
    datav = ds.ReadAsArray()
    data = np.full((datav.shape[0] + 1, datav.shape[1] + 1), -32750, dtype=int)
    data[0:datav.shape[0], 0:datav.shape[1]] = datav
    xblocksize = int(newcols / 5)
    yblocksize = int(newrows / 5)
    for i in range(0, newrows, yblocksize):
        if i + yblocksize < newrows:
            numrows = yblocksize
        else:
            numrows = newrows - i
        for j in range(0, newcols, xblocksize):
            if j + xblocksize < newcols:
                numcols = xblocksize
            else:
                numcols = newcols - j
            x = lon_min + j * 0.01 + 0.01 / 2.0 #切记250m的分辨率需要把0.01换成0.0025
            y = lat_max + i * (-1 * 0.01) - 0.01 / 2.0#切记250m的分辨率需要把0.01换成0.0025
            newxgrid, newygrid = np.meshgrid(np.linspace(x, x + numcols * 0.01, num=numcols),#切记250m的分辨率需要把0.01换成0.0025
                                             np.linspace(y, y + numrows * (-1 * 0.01), num=numrows))#切记250m的分辨率需要把0.01换成0.0025
            # 将经纬度坐标转化为Hammer坐标
            newxgrid = np.where(newxgrid > 180.0, newxgrid - 360.0, newxgrid)
            newxgrid = newxgrid / 180.0 * math.pi
            newygrid = newygrid / 180.0 * math.pi
            newz = np.sqrt(1 + np.cos(newygrid) * np.cos(newxgrid / 2.0))
            x = np.cos(newygrid) * np.sin(newxgrid / 2.0) / newz
            newxgrid = None
            y = np.sin(newygrid) / newz
            newygrid = None
            newz = None
            x = x * (18000.0 * 1000.0)
            y = y * (9000.0 * 1000.0)
            x_index = (np.floor((x - or_x) / ingeo[1])).astype(int)
            x_index = np.where(x_index < 0, data.shape[1] - 1, x_index)
            x_index = np.where(x_index >= data.shape[1], data.shape[1] - 1, x_index)
            y_index = (np.floor((y - or_y) / ingeo[5])).astype(int)
            y_index = np.where(y_index < 0, data.shape[0] - 1, y_index)
            y_index = np.where(y_index >= data.shape[0], data.shape[0] - 1, y_index)
            newdata = data[y_index, x_index]
            outband.WriteArray(newdata, j, i)
    outband.SetNoDataValue(-32750)
    outband.FlushCache()

if __name__ == '__main__':
    infile_path = r"C:\Users\Administrator\Desktop\02拼接"
    outfile_path = r"C:\Users\Administrator\Desktop\03WGS"
    infile_list = get_data_list(infile_path)
    outfile_list = get_data_list(infile_path,outfile_path)
    for infile,outfile in zip(infile_list,outfile_list):
        print(infile)
        H2W(infile,outfile)

在这里插入图片描述
在这里插入图片描述

4 批量掩膜裁剪

请参考本人博客《Python遥感开发之批量掩膜和裁剪》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL SQL优化 【建议熟读并背诵】

插入数据 批量插入数据 insert into tb_test values(1,Tom),(2,Cat),(3,Jerry);手动控制事务 start transaction; insert into tb_test values(1,Tom),(2,Cat),(3,Jerry); insert into tb_test values(4,Tom),(5,Cat),(6,Jerry); insert into tb_test values(7,Tom),(8,Cat…

在Windows中使用Linux命令安装这款软件就可以

由于平时经常使用Linux命令&#xff0c;所以导致在Windows的cmd中输入命令的时候经常打错&#xff0c;提示不是内部或外部命令&#xff0c;也不是可运行的程序。 那么有办法将补全cmd命令&#xff0c;使Linux中的命令在Windows中也能使用呢&#xff1f; 下面我来讲解如何在Win…

微服务架构-服务网关(Gateway)-服务网关在微服务中的应用

服务网关在微服务中的应用 我们将目光转向Spring Cloud应用的外围&#xff0c;讨论微服务架构下的各个模块如何对外提供服务。 1、对外服务的难题 微服务架构下的应用系统体系很庞大&#xff0c;光是需要独立部零的基础组件就有注册中心、配置中心和服务总线、Turbine异常聚…

【版本控制】Github同步Gitee镜像仓库自动化脚本

文章目录Github同步Gitee镜像仓库自动化脚本前言什么是Hub Mirror Action&#xff1f;1.介绍2.用法配置步骤1.生成密钥对2.GitHub私钥配置3.Gitee公钥配置4.Gitee生成私人令牌5.Github绑定Gitee令牌6.编写CI脚本7.多仓库同步推送8.定时运行脚本总结Github同步Gitee镜像仓库自动…

Softmax和Cross Entropy Loss在分类问题中的作用

本文以三分类神经网络为例&#xff0c;讲解Softmax和Cross Entropy Loss在分类问题中的作用。 首先&#xff0c;对类别标签进行一位有效编码&#xff1a; y[y1,y2,y3]Ty[y_{1},y_{2},y_{3}]^{T}y[y1​,y2​,y3​]T yi{1,if(iy)0,otherwisey_{i}\left\{\begin{matrix} 1 ,& …

形式语言和自动机总结----正则语言RE

第3-4章正则表达式 正则表达式的设计举例 正则表达式的运算 正则表达式的优先级 举例 1.倒数第三个字符是1 &#xff08;01)*1(01)(01) 2.不含有连续的0 &#xff08;101&#xff09;*&#xff08;0&#xff09; 3.含有000 &#xff08;01&#xff09;*000&#xff08;01&a…

【算法LearnNO.1】算法介绍以及算法的时间复杂度和空间复杂度

目录 一、算法 1、算法概述 2、算法的5个特性 3、设计算法的标准 二、时间复杂度 1、时间复杂度的介绍 2、渐进时间复杂度的求法 3、计算时间复杂度的代码举例&#xff08;平方阶示例&#xff09; 4、时间复杂度排序 三、空间复杂度 一、算法 1、算法概述 算法就是解…

蔚来试水辅助驾驶订阅,NOP+能否吃蟹?

作者 | 德新 编辑 | 王博2021年的NIO Day上&#xff0c;随着当时ET7发布&#xff0c;蔚来最早宣布了智能驾驶订阅服务&#xff1a;NAD&#xff0c;月费680元。 两年后&#xff0c;辅助驾驶订阅模式终于开始落地&#xff1a;蔚来将从7月1日起&#xff0c;对NOP进行收费&#xff…

Nginx基础教程

Nginx 目标 Nginx简介【了解】 Nginx安装配置【掌握】 一、Nginx简介 Nginx称为:负载均衡器或 静态资源服务器:html,css,js,img ​ Nginx(发音为“engine X”)是俄罗斯人编写的十分轻量级的HTTP服务器,是一个高性能的HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/P…

索引优化、优化,你又是一个好MongoDB!!!博学谷狂野架构师

MongoDB索引优化 作者: 博学谷狂野架构师GitHub&#xff1a;GitHub地址 &#xff08;有我精心准备的130本电子书PDF&#xff09;只分享干货、不吹水&#xff0c;让我们一起加油&#xff01;&#x1f604; 索引简介 索引通常能够极大的提高查询的效率&#xff0c;如果没有索引&a…

【pg数据库状态监控相关参数展示】

1、最近项目中做了一个postgresql数据库监控状态功能的需求&#xff0c;需求如下图 2、研究好久&#xff0c;终于在pg数据库的官方文档中找到了相关视图参数&#xff0c; 文档连接如下&#xff1a; 数据库基础信息&#xff1a; http://www.postgres.cn/docs/9.3/functions-in…

开源项目:数据库表结构生成文档工具

目录 一、软件介绍 二、技术框架 三、功能介绍 四、代码展示 1、获取数据库信息部分代码 2、导出Html文档代码 五、运行效果 六、项目开源地址 一、软件介绍 今天给大家分享我自己编写的数据库表结构文档生成工具&#xff0c;方便大家在实际开发当中&#xff0c;可以很方便导出…

JAVA常用工具-文件操作相关IO

IO技术在JDK中算是极其复杂的模块&#xff0c;文件管理都依赖IO技术&#xff0c;而且都是编程的难点&#xff0c;想要整体理解IO流&#xff0c;先从Linux操作系统开始&#xff0c; Linux空间隔离 Linux使用是区分用户的&#xff0c;这个是基础常识&#xff0c;其底层也区分用…

【MQTT协议】使用Mosquitto实现mqtt协议(二):编写视频帧的发布/订阅服务

目录一、Mosquitto中的QoS定义QoS1和3区别二、安装base64库三、cjson简介四、主程序代码五、调用Mosquitto库使用的cmakelist更多内容详见 【MQTT协议】使用c实现mqtt协议&#xff08;Mosquitto源码编译&#xff09;一、Mosquitto中的QoS定义 MQTT协议中的QoS&#xff08;Qual…

CLIP论文拜读及理解

文章目录一、clip论文阅读二、prompt1.除prompt之外的预训练语言模型2.prompt2.1. prompt定义2.2. prompt类型2.3. prompt重构2.3.1 prompt template2.3.2 Answer engineering2.4 多个 prompt的使用2.5 prompt的训练总结参考&#xff08;博文、论文&#xff09;一、clip论文阅读…

Windows系统安装WSL,并安装docker服务

背景 因为工作需要&#xff0c;要在电脑上执行sh脚本&#xff0c;并启动docker服务执行具体逻辑。因为我的电脑是windows系统&#xff0c;对做本任务来说&#xff0c;比较吃力&#xff0c;所以想到使用wsl&#xff0c;让windows电脑具有linux电脑的能力。 什么是 WSL 2 WSL 2 …

JVM的类加载的过程以及双亲委派模型

目录 1、加载 &#xff08;加载字节码文件&#xff0c;生成.class对象&#xff09; 2、验证&#xff08;验证Class文件是否符合规范&#xff09; 3、准备 &#xff08;为静态变量分配内存并设置变量初始值&#xff09; 4、解析&#xff08;初始化常量池中的一些常量&#…

索引的分类

1.唯一索引 给表中某一列设置为了唯一约束(这列不允许出现重复数据)后&#xff0c;数据库会为将这一列设置索引&#xff0c;这个索引叫做唯一索引&#xff08;主键那一列是一个特殊的唯一索引&#xff0c;不仅要满足唯一索引这一列不可以出现重复数据&#xff0c;而且这一列还…

Android opencv

install cmake cpp folder,新建c项目 获取 OpenCV4Android SDK O4A_SDK 下载&#xff0c;并解压 ~/Downloads/OpenCV-android-sdk$ tree -d -L 2 . ├── apk ├── samples │ ├── 15-puzzle │ ├── camera-calibration │ ├── color-blob-detection │ ├…

文件:IO流

1. 什么是IO /O 即输入Input/ 输出Output的缩写&#xff0c;其实就是计算机调度把各个存储中&#xff08;包括内存和外部存储&#xff09;的数据写入写出的过程&#xff1b;java中用“流&#xff08;stream&#xff09;”来抽象表示这么一个写入写出的功能&#xff0c;封装成一…