GEE:如何进行对MOD09GA数据集进行水体/云掩膜并计算NDVI将其导出至云盘?

news2024/11/27 17:39:14

目录

01 为什么用GEE而不是传统的下载+ENVI+ArcGIS?

02 操作详解


01 为什么用GEE而不是传统的下载+ENVI+ArcGIS?

由于地理空间数据云中缺少2015年10月份的NDVI月合成影像,于是查看了地理空间数据云的NDVI数据集处理的一些介绍如下(地理空间数据云 (gscloud.cn)):

本打算去NASA下载的,本来下载链接都已经拿到了,但是一看8个G,这还仅仅只是下载,我还需要进行裁剪拼接、NDVI计算重采样等等操作,比较繁琐,最终还只是得到一个张月合成NDVI影像,这时间和精力不成正比:

 于是打算使用GEE平台进行NDVI的计算并导出。

02 操作详解

使用的数据集:MOD09GA.061 Terra Surface Reflectance Daily Global 1km and 500m

这里为了保证精度,对影像进行了云掩膜和水体掩膜。

首先,定义了起始日期和结束日期:

// 定义日期范围
var start_date = '2015-10-01';
var end_date = '2015-10-31';

接着我们定义一个水体和云掩膜函数:

// 定义云和水体掩膜函数
function maskCloudAndWater(image) {
  var QA = image.select('QC_500m');
  // 创建一个空的mask,初始值为1(即所有像素都不被掩膜覆盖)
  var mask = ee.Image.constant(1);
  
  // 遍历每个波段的数据质量标识
  for (var i = 0; i < 2; i++) {  // 因为我选取了两个波段进行ndvi的计算
    // 计算当前波段的数据质量标识的起始位(是从2开始)
    var startBit = 2 + i * 4;
    // 提取当前波段的数据质量标识
    var bandQuality = QA.rightShift(startBit).bitwiseAnd(15);
    // 如果数据质量标识为15,说明该像素可能被云或深海覆盖,需要被掩膜覆盖
    mask = mask.min(bandQuality.neq(15));  // min取两者间小的那个值,逐像元
  }
  
  // 应用掩膜
  return image.updateMask(mask);
}

这里的水体掩膜和云掩膜与一般的数据集不太一样,这里的QC波段是针对每一个波段影像都有4位二进制数进行标识,所以是对每一个波段进行mask的求取再将所有mask求一个类似的或运算。

以下是MOD09GA数据集AC_500m波段的一个介绍(来自GEE):

 

这里主要讲讲二进制掩膜的问题。

在我们的函数里,QA是一个32位的整数,也就是说它是由32个二进制数位组成的,每一个波段都有4位的数据质量标识,这4位被放在QA中的某一位置。例如:

我们举一个简单的例子,对于一个某一个像元,它的属性(32位的二进制整数)值为:

0010 1100 1011 0011 0101 1001 0110 1011

(注意:空格是我为了方便阅读加上的)

在上述二进制整数中,每4位表示一个波段的质量部分,那么假定我们关心的是最左侧的0010部分(这就是我们称之为数据质量的部分)。

那么我们可以将其往右边移动(右移操作)28位,得到:

0000 0000 0000 0000 0000 0000 0000 0010

接着我们就可以将其与掩膜值做比较,这里需要使用到位与操作:

位与操作是对两个二进制数进行比较,只有当两个相应的二进制位都为1时,结果的相应位才为1,否则为0。

通过此前的截图我们知道,Bits2~5表示第1个波段的数据质量部分,掩膜值为15(十进制)表示深海或者云层。

而我们知道,十进制的15转化为32位二进制为:

0000 0000 0000 0000 0000 0000 0000 1111

因此二者进行位与操作之后为:

0000 0000 0000 0000 0000 0000 0000 0010

其转化为十进制不等于15,说明该像元位置不是深海或者云层。


其他的代码部分由于时间原因就不一一说明,这里贴出完整代码:

// 定义日期范围
var start_date = '2015-10-01';
var end_date = '2015-10-31';

// 定义云和水体掩膜函数
function maskCloudAndWater(image) {
  var QA = image.select('QC_500m');
  // 创建一个空的mask,初始值为1(即所有像素都不被掩膜覆盖)
  var mask = ee.Image.constant(1);
  
  // 遍历每个波段的数据质量标识
  for (var i = 0; i < 2; i++) {  // 因为我选取了两个波段进行ndvi的计算
    // 计算当前波段的数据质量标识的起始位(是从2开始)
    var startBit = 2 + i * 4;
    // 提取当前波段的数据质量标识
    var bandQuality = QA.rightShift(startBit).bitwiseAnd(15);
    // 如果数据质量标识为15,说明该像素可能被云或深海覆盖,需要被掩膜覆盖
    mask = mask.min(bandQuality.neq(15));  // min取两者间小的那个值,逐像元
  }
  
  // 应用掩膜
  return image.updateMask(mask);
}

// 定义地理空间范围(四川省)
var geom = ee.FeatureCollection('projects/ee-chaoqiezione/assets/china_admin_province')
geom = geom.filter(ee.Filter.eq('省', '四川省'));
// 加载MODIS数据根据日期和地理范围进行筛选
var modis_ndvi = ee.ImageCollection('MODIS/006/MOD09GA')
  .filterDate(start_date, end_date)
  .filterBounds(geom)
  .select(['sur_refl_b02', 'sur_refl_b01', 'QC_500m'])
  .map(function (img) {
    img = maskCloudAndWater(img);  // 水体和云掩膜
    return img.normalizedDifference(['sur_refl_b02', 'sur_refl_b01']).rename('ndvi')  // 计算ndvi
  })
  .mean().clip(geom)

// 添加到地图上以便可视化
print(modis_ndvi)  // 命令面板输出简要信息
Map.addLayer(modis_ndvi.select('ndvi'), {min: 0, max: 1, palette: ['blue', 'white', 'green']}, 'MeanNDVI');
Map.centerObject(geom, 6)

// 导出至云盘
Export.image.toDrive({
  image: modis_ndvi.select('ndvi'),
  description: 'Mean_NDVI',
  region: geom,
  scale: 500,
  maxPixels: 1e13,
  fileFormat: 'GeoTIFF'})

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

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

相关文章

【Linux内核】信号量semaphore机制

信号量实现方法 信号量机制是一种用于控制并发访问的同步机制&#xff0c;常用于多进程或多线程之间的协调。在Linux内核中&#xff0c;信号量机制是通过struct semaphore结构体来实现的。 每个semaphore结构体包含一个计数器和一个等待队列&#xff0c;它们用于跟踪当前可用…

Linux 并发与竞争

一、并发与竞争 1、并发 Linux 系统是个多任务操作系统&#xff0c;会存在多个任务同时访问同一片内存区域&#xff0c;这些任务可 能会相互覆盖这段内存中的数据&#xff0c;造成内存数据混乱。 多线程并发访问&#xff0c; Linux 是多任务(线程)的系统&#xff0c;所以多线…

命令firewalld和firewall-cmd用法

firewalld命令跟firewall-cmd 1.启动firewalld服务 systemctl start firewalld.service2.关闭firewalld服务 systemctl stop firewalld.service3.重启firewalld服务 systemctl restart firewalld.service4.查看firewalld状态 systemctl status firewalld.service5.开机自启…

接口测试怎么做?全网最详细从接口测试到接口自动化详解,看这篇就够了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 抛出一个问题&…

孙鑫VC++第三章 2.基于MFC的程序框架剖析

目录 1. MFC向导生成类 2. 框架流程 2.1 WinMain 2.2 全局对象&#xff1a;theApp 2.3 AfxWinMain函数 1.AfxWinMain&#xff1a; 2.AfxGetThread函数&#xff08;thrdcore.cpp&#xff09;&#xff1a; 3.AfxGetApp是一个全局函数&#xff0c;定义于&#xff08;afxwin1…

原型/原型链/构造函数/类

认识构造函数 为什么有构造函数 因为一般的创建对象的方式一次只能创建一个对象, 利用工厂模式创建的对象&#xff0c;对象的类型都是Object类型 什么是构造函数 构造函数也称之为构造器&#xff08;constructor&#xff09;&#xff0c;通常是我们在创建对象时会调用的函数…

Uni-app项目应用总结(一)

目录 一.新建uniapp项目 第一步&#xff1a;下载HBuilder 第二步:创建uni-app项目 第三步&#xff1a;运行uni-app 二.uni-app组件使用 三.uni-app路由跳转  1.页面路由配置    (1)在pages.json中配置页面路由    (2)在pages.json中配置底部导航栏 2.路由跳转方法…

【输配电路 DZY-104端子排中间继电器 接通、信号转换 JOSEF约瑟】

DZY-104端子排中间继电器品牌:JOSEF约瑟型号:DZY-104名称:端子排式中间继电器触点容量:5A/250V功率消耗:≤1.5W/≤3W/≤7W/≤3VA/≤7VA/≥5W绝缘电阻:≥10MΩ 系列型号&#xff1a; DZY-101端子排中间继电器&#xff1b; DZY-104端子排中间继电器&#xff1b; DZY-105端子排…

华南农业大学|图像处理与分析技术综合测试|题目解答:求芒果单层坏损率

设计任务 对于一幅芒果果实内部的 CT 断层图像&#xff0c;试采用图像处理与分析技术&#xff0c;设计适当的算法和程序&#xff0c;首先分割出其中的坏损区域&#xff0c;然后计算其像素面积占整个果肉区域的百分比&#xff08;单层坏损率&#xff09;。请按统一要求写出算法…

nuc980 uboot 2017.11 移植:env 保存位置选择问题

开发环境 Win10 64位 ubuntu 20.04 虚拟机 VMware Workstation 16 Pro 开发板&#xff1a;NK-980IOT&#xff08;NUC980DK61Y&#xff09; gcc 交叉编译工具链&#xff1a; ARM 官方 gcc version 11.2.1 20220111 NUC980 uboot 版本 &#xff1a;尝试移植到 u-boot-2017.1…

科普 “平均工资又涨了”

周四晚上做了一个图&#xff0c;发了一则朋友圈&#xff0c;科普了一下为什么平均工资一直在涨&#xff1a; 曲线是 drawio 画的&#xff0c;不是类似 geogebra 画的精确数学函数&#xff0c;误差比较大&#xff0c;但大概就是这个意思。 收入应该是无标度分形的幂律分布&am…

孙鑫VC++第三章 4.窗口类、窗口类对象与窗口三者之间关系

目录 1. 创建CWnd 2. WinMain 3. 创建CButton 1. 创建CWnd 模拟CWnd类的封装过程。在解决方案ch04下添加一个新的空项目&#xff0c;项目名称为&#xff1a;WinMain&#xff0c;在项目创建完成后&#xff0c;将WinMain项目设为启动项目。 接下来在WinMain项目中添加一个名…

【C++ 学习 ④】- 类和对象(下)

目录 一、初始化列表 1.1 - 定义 1.2 - 使用初始化列表的原因 1.3 - 成员变量的初始化顺序 二、静态成员 2.1 - 静态成员变量 2.2 - 静态成员函数 三、友元 3.1 - 友元函数 3.2 - 友元类 四、内部类 五、匿名对象 5.1 - 匿名对象的特性 5.2 - 匿名对象的使用场景…

3.View的绘制流程

View是在什么时候显示在屏幕上面的?(如:MainActivity的布局文件activity_main.xml) setContentView最终的结果是将解析的xml文件中的View添加到DecorView中. 那么这个DecorView是什么时候添加到Window(PhoneWindow)的呢? DecorView是在ActivityThread.java的handleResumeA…

2-Zookeeper单机版安装

2-Zookeeper单机版安装 本文介绍的是 Linux 系统下 Zookeeper 安装方式 ① 下载 进入官网 https://zookeeper.apache.org/ 点击下载按钮 进入下载页 https://zookeeper.apache.org/releases.html 后选择 最新的稳定版本&#xff0c;如下&#xff1a; 3.7.1 为最新的稳定版本…

号称分割一切的图片分割模型开源了——Segment Anything Meta SAM

头条号:人工智能研究所 微信号:启示AI科技 微信小程序:AI人工智能工具 以前,要解决任何类型的分割问题,有两类方法。第一种是交互式分割,允许分割任何类别的对象,但需要人通过迭代细化掩码来指导。第二种,自动分割,允许分割提前定义的特定对象类别(例如,猫或椅子),…

【计算机系统】指令

leaq指令 一元指令 二元指令 例子 指令addq 指令subq 指令incq 指令subq 移位指令 移位指令用途 特殊运算指令

LitCTF2023 郑州轻工业大学首届网络安全赛 WP 部分

LitCTF2023 郑州轻工业大学首届网络安全赛 WP 部分 前言&#xff1a;Web&#xff1a;我Flag呢&#xff1f;导弹迷踪&#xff1a;Follow me and hack me&#xff1a;PHP是世界上最好的语言&#xff01;&#xff01;作业管理系统&#xff1a;Vim yyds&#xff1a;Ping&#xff1a…

Java基础-面向对象总结(2)

这篇文章主要讲解 Java中的 变量方法代码块访问修饰限定符Java 是值传递&#xff0c;还是引用传递&#xff1f;类和对象的生命周期..... 希望给您带来帮助 目录 变量 成员变量与局部变量的区别 静态变量和实例变量的区别&#xff1f;静态方法、实例方法呢&#xff1f; 可以…