Google Earth Engine:对NDVI进行惠特克平滑算法进行长时序分析

news2024/9/20 16:33:56

目录

简介

函数

ee.Array.identity(size)

Arguments:

Returns: Array

transpose(axis1, axis2)

Arguments:

Returns: Array

matrixMultiply(image2)

Arguments:

Returns: Image

matrixSolve(image2)

Arguments:

Returns: Image

arrayFlatten(coordinateLabels, separator)

Arguments:

Returns: Image

arrayReduce(reducer, axes, fieldAxis)

Arguments:

Returns: Image

代码

结果


简介

惠特克(GEE)平滑算法是一种用于时间序列预测的统计方法,特别适用于非线性、非平稳和非高斯的数据。该算法基于广义估计方程,通过最小化残差的平方和来拟合数据并找到最佳的平滑曲线。

GEE平滑算法的主要思想是在时间序列数据中引入一个平滑函数来描述数据的趋势和周期性变化。该平滑函数由一系列基函数的线性组合组成,其中每个基函数具有不同的频率和振幅。通过调整基函数的权重,可以得到最佳的平滑曲线,以最大程度地拟合数据。

在实际应用中,GEE平滑算法通常与其他统计方法结合使用,例如自回归移动平均模型(ARIMA)或指数平滑法。通过将GEE平滑算法与其他方法相结合,可以进一步提高时间序列的预测准确度和稳定性。

总的来说,GEE平滑算法是一种针对非线性、非平稳和非高斯数据的时间序列预测方法,通过引入一个平滑函数来描述数据的趋势和周期性变化,以最大程度地拟合数据。它在实际应用中通常与其他统计方法结合使用,以进一步提高预测的准确度和稳定性。

函数

ee.Array.identity(size)

Creates a 2D identity matrix of the given size.

创建一个给定大小的二维标识矩阵。

Arguments:

size (Integer):

The length of each axis.

Returns: Array

transpose(axis1axis2)

Transposes two dimensions of an array.

平移数组的两个维度。

Arguments:

this:array (Array):

Array to transpose.

axis1 (Integer, default: 0):

First axis to swap.

axis2 (Integer, default: 1):

Second axis to swap.

Returns: Array

matrixMultiply(image2)

Returns the matrix multiplication A * B for each matched pair of bands in image1 and image2. If either image1 or image2 has only 1 band, then it is used against all the bands in the other image. If the images have the same number of bands, but not the same names, they're used pairwise in the natural order. The output bands are named for the longer of the two inputs, or if they're equal in length, in image1's order. The type of the output pixels is the union of the input types.

返回图像 1 和图像 2 中每对匹配波段的矩阵乘法 A * B。如果图像 1 或图像 2 中只有一个波段,则该波段将与另一幅图像中的所有波段相对应。如果图像中的条带数量相同,但名称不同,则按自然顺序成对使用。输出波段以两个输入波段中较长的一个命名,如果两个输入波段长度相等,则按图像 1 的顺序命名。输出像素的类型是输入类型的组合。

Arguments:

this:image1 (Image):

The image from which the left operand bands are taken.

image2 (Image):

The image from which the right operand bands are taken.

Returns: Image

matrixSolve(image2)

Solves for x in the matrix equation A * x = B, finding a least-squares solution if A is overdetermined for each matched pair of bands in image1 and image2. If either image1 or image2 has only 1 band, then it is used against all the bands in the other image. If the images have the same number of bands, but not the same names, they're used pairwise in the natural order. The output bands are named for the longer of the two inputs, or if they're equal in length, in image1's order. The type of the output pixels is the union of the input types.

求解矩阵方程 A * x = B 中的 x,如果 A 对图像 1 和图像 2 中每对匹配的波段都是过确定的,则找到最小二乘法解。如果图像 1 或图像 2 中只有一个波段,则使用该波段与另一幅图像中的所有波段进行比对。如果图像中的波段数相同,但名称不相同,则按自然顺序成对使用。输出波段以两个输入波段中较长的一个命名,如果两个输入波段长度相等,则按图像 1 的顺序命名。输出像素的类型是输入类型的组合。

Arguments:

this:image1 (Image):

The image from which the left operand bands are taken.

image2 (Image):

The image from which the right operand bands are taken.

Returns: Image

arrayFlatten(coordinateLabels, separator)

Converts a single-band image of equal-shape multidimensional pixels to an image of scalar pixels, with one band for each element of the array.

将等形多维像素的单波段图像转换为标量像素图像,阵列中的每个元素对应一个波段。

Arguments:

this:image (Image):

Image of multidimensional pixels to flatten.

coordinateLabels (List):

Name of each position along each axis. For example, 2x2 arrays with axes meaning 'day' and 'color' could have labels like [['monday', 'tuesday'], ['red', 'green']], resulting in band names'monday_red', 'monday_green', 'tuesday_red', and 'tuesday_green'.

separator (String, default: "_"):

Separator between array labels in each band name.

Returns: Image

arrayReduce(reducer, axes, fieldAxis)

Reduces elements of each array pixel.

减少每个阵列像素的元素。

Arguments:

this:input (Image):

Input image.

reducer (Reducer):

The reducer to apply.

axes (List):

The list of array axes to reduce in each pixel. The output will have a length of 1 in all these axes.

fieldAxis (Integer, default: null):

The axis for the reducer's input and output fields. Only required if the reducer has multiple inputs or outputs.

Returns: Image

代码

//加载研究区
var geometry = 
    /* color: #d63000 */
    /* displayProperties: [
      {
        "type": "rectangle"
      }
    ] */
    ee.Geometry.Polygon(
        [[[113.44773227683973, 38.6708907304602],
          [113.44773227683973, 38.64783484482313],
          [113.47588474266004, 38.64783484482313],
          [113.47588474266004, 38.6708907304602]]], null, false);

// 将 qa 位图像转换为标志的辅助函数
function extractBits(image, start, end, newName) {
    // 计算我们需要提取的比特。
    var pattern = 0;
    for (var i = start; i <= end; i++) {
       pattern += Math.pow(2, i);
    }
    // 返回提取的质量保证位的单波段图像,并为该波段命名。
    return image.select([0], [newName])
                  .bitwiseAnd(pattern)
                  .rightShift(start);
}

// 在输入矩阵上获取指定阶次的差分矩阵的函数。将矩阵和阶次作为参数
function getDifferenceMatrix(inputMatrix, order){
    var rowCount = ee.Number(inputMatrix.length().get([0]));
    var left = inputMatrix.slice(0,0,rowCount.subtract(1));
    var right = inputMatrix.slice(0,1,rowCount);
    if (order > 1 ){
        return getDifferenceMatrix(left.subtract(right), order-1)}
    return left.subtract(right);
};

// 将数组图像解包为图像和波段
// 以数组图像、图像 ID 列表和乐队名称列表为参数
function unpack(arrayImage, imageIds, bands){
    
    function iter(item, icoll){
        
        function innerIter(innerItem, innerList){
            return ee.List(innerList).add(ee.String(item).cat("_").cat(ee.String(innerItem)))}
        
        var temp = bands.iterate(innerIter, ee.List([]));
        return ee.ImageCollection(icoll)
            .merge(ee.ImageCollection(ee.Image(arrayImage).select(temp,bands).set("id",item)))}

    var imgcoll  = ee.ImageCollection(imageIds.iterate(iter, ee.ImageCollection([])));
    return imgcoll}


// 用于计算回归结果的反对数比率并转换回百分比单位的函数
function inverseLogRatio(image) {
  var bands = image.bandNames();
  var t = image.get("system:time_start");
  var ilrImage = ee.Image(100).divide(ee.Image(1).add(image.exp())).rename(bands);
  return ilrImage.set("system:time_start",t);
}

function whittakerSmoothing(imageCollection, isCompositional, lambda){
  // 快速配置以设置默认值
  if (isCompositional === undefined || isCompositional !==true) isCompositional = false;
  if (lambda === undefined ) lambda = 10;
  // 程序启动  

  var ic = imageCollection.map(function(image){
     var t = image.get("system:time_start");
    return image.toFloat().set("system:time_start",t);
  });

  var dimension = ic.size();
  var identity_mat = ee.Array.identity(dimension);
  var difference_mat = getDifferenceMatrix(identity_mat,3);
  var difference_mat_transpose = difference_mat.transpose();
  var lamda_difference_mat = difference_mat_transpose.multiply(lambda);
  var res_mat = lamda_difference_mat.matrixMultiply(difference_mat);
  var hat_matrix = res_mat.add(identity_mat);

  
  // 备份原始数据
  var original = ic;

  // 获取原始图像属性
  var properties = ee.List(ic.iterate(function(image, list){
    return ee.List(list).add(image.toDictionary());
  },[]));
  
  var time = ee.List(ic.iterate(function(image, list){
    return ee.List(list).add(image.get("system:time_start"));
  },[]));
  
  // 如果数据是合成的
  // 计算图像在 0 到 100 之间的对比率。首先
  // 夹在 delta 和 100-delta 之间,其中 delta 是一个很小的正值。
  if (isCompositional){
    ic = ic.map(function(image){
      var t = image.get("system:time_start");
      var delta = 0.001;
      var bands = image.bandNames();
      image = image.clamp(delta,100-delta);
      image = (ee.Image.constant(100).subtract(image)).divide(image).log().rename(bands);
      return image.set("system:time_start",t);
    });
  }

  var arrayImage = original.toArray();
  var coeffimage = ee.Image(hat_matrix);
  var smoothImage = coeffimage.matrixSolve(arrayImage);
  
  var idlist = ee.List(ic.iterate(function(image, list){
    return ee.List(list).add(image.id());
  },[]));
  var bandlist = ee.Image(ic.first()).bandNames();
  
  var flatImage = smoothImage.arrayFlatten([idlist,bandlist]);
  var smoothCollection = ee.ImageCollection(unpack(flatImage, idlist, bandlist));
  
  if (isCompositional){
    smoothCollection = smoothCollection.map(inverseLogRatio);
  }
  // 通过添加后缀fitted获得新的乐队名称
  var newBandNames = bandlist.map(function(band){return ee.String(band).cat("_fitted")});
  // 重新命名平滑图像中的波段
  smoothCollection = smoothCollection.map(function(image){return ee.Image(image).rename(newBandNames)});
  
  // 一个非常笨的方法,可以flatten谷歌地球引擎生成的 ID,这样就可以将两张图片合并为图表了
  var dumbimg = arrayImage.arrayFlatten([idlist,bandlist]);
  var dumbcoll = ee.ImageCollection(unpack(dumbimg,idlist, bandlist));
  var outCollection = dumbcoll.combine(smoothCollection);
  
  var outCollectionProp = outCollection.iterate(function(image,list){
      var t = image.get("system:time_start")
    return ee.List(list).add(image.set(properties.get(ee.List(list).size())));
  },[]);

  var outCollectionProp = outCollection.iterate(function(image,list){
    return ee.List(list).add(image.set("system:time_start",time.get(ee.List(list).size())));
  },[]);


  var residue_sq = smoothImage.subtract(arrayImage).pow(ee.Image(2)).divide(dimension);
  var rmse_array = residue_sq.arrayReduce(ee.Reducer.sum(),[0]).pow(ee.Image(1/2));
  
  var rmseImage = rmse_array.arrayFlatten([["rmse"],bandlist]);
  
  return [ee.ImageCollection.fromImages(outCollectionProp), rmseImage];
}



var ndvi =ee.ImageCollection("NOAA/VIIRS/001/VNP13A1").select('NDVI').filterDate("2019-01-01","2019-12-31");
// 去除屏蔽像素
ndvi = ndvi.map(function(img){return img.unmask(ndvi.mean())});

var ndvi =  whittakerSmoothing(ndvi)[0];

// 添加图表
print(ui.Chart.image.series(
  ndvi.select(['NDVI', 'NDVI_fitted']), geometry, ee.Reducer.mean(), 500)
    .setSeriesNames(['NDVI', 'NDVI_fitted'])
    .setOptions({
      title: 'smoothed',
      lineWidth: 1,
      pointSize: 3,
}));


结果

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

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

相关文章

Ajax day-01

目录 一. Ajax 1.1 创建XMLHttpRequest对象 1.2 Ajax向服务器发送请求 1.3 设置http请求头 1.4 发送请求 1.5 获得响应 1.6 监听请求状态的改变 1.7 获取响应头 1.8 获得响应主体 1.9 处理服务器返回的数据 1.10 怎样向服务器传递数据&#xff1f; 二. 接口文档 三…

线性表之数组

数组&#xff08;Array&#xff09;是 C/C 中最基础和重要的数据结构之一&#xff0c;它提供了一种有效存储和访问固定大小元素集合的方式。关于数组的定义和使用相信大家都已经熟练掌握&#xff0c;本文将着重为大家剖析数组的物理结构和逻辑结构。 1. 数组的物理结构 数组的…

视频技术未来展望:EasyCVR如何引领汇聚融合平台新趋势

随着科技的飞速发展&#xff0c;视频技术已成为现代社会不可或缺的一部分&#xff0c;广泛应用于安防监控、娱乐传播、在线教育、电商直播等多个领域。本文将探讨视频技术的未来发展趋势&#xff0c;并深入分析TSINGSEE青犀EasyCVR视频汇聚融合平台的技术优势&#xff0c;展现其…

【SolidWorks2024 详细安装教程【附安装包】】

提示&#xff1a;【SolidWorks2024 详细安装教程【附安装包】】 文章目录 安装包获取一、安装步骤总结 安装包获取 提示&#xff1a;这里可以获得软件安装包&#xff1a; SolidWorks2024详细安装教程&#xff0c;百度网盘 链接&#xff1a;https://pan.baidu.com/s/1UyipwXokK…

rsync搭建全网备份

rsync搭建全网备份 1. 总体概述1.1 目标1.2 简易指导图1.3 涉及工具或命令1.4 环境 2. 实施2.1 配置备份服务器2.2 备份文件准备2.3 整合命令2.4 扩展功能 1. 总体概述 1.1 目标 本次搭建目标&#xff1a; 每天定时把服务器数据备份到备份服务器备份完成后进行校验把过期数据…

【python】turtle的使用

文章目录 1.初始化2.颜色3.画笔4.其他案例&#xff1a;分形树的绘制 1.初始化 import turtle# 创建一支画笔 pen turtle.Turtle()# ...# 暂停屏幕&#xff0c;防止程序关闭 turtle.done()2.颜色 # 设置颜色模式(如果要使用颜色相关设置&#xff0c;必须要使用这个) turtle.c…

基于STM32的RFID高速收费系统(论文+源码+实物)

1系统方案设计 本文基于STM32的RFID高速收费系统&#xff0c;其可以实现小车和货车两种车型收费&#xff0c;当车辆超过了规定的重量后&#xff0c;出现声光报警提示&#xff0c;并且启动杆不会抬起&#xff0c;只有当车辆重量低于设置值时&#xff0c;启动杆才会自动抬起&…

零基础学习Redis(7) -- hash类型命令使用

Redis本身就是通过哈希表的方式组织数据&#xff0c;同时redis中的value也可以是另一个哈希表。 1. 常用命令 1. hset / hsetnx hset key filed1 value1 filed2 value2 ... hset 用于把键值对存入value中&#xff0c;这里的key为redis组织的键&#xff0c; filed1 value1 fil…

SpringData-ElasticSearch入门

文章目录 1、创建demo工程2、application.properties3、Goods 实体类4、EsDemoApplicationTests 测试类5、pom.xml6、查看索引库7、查看单个索引&#xff08;数据库&#xff09;8、从goods索引中检索出符合特定搜索条件的文档&#xff08;或记录&#xff09; 1、创建demo工程 2…

Elasticsearch:使用 LTR 进行个性化搜索

作者&#xff1a;来自 Elastic Max Jakob 如今&#xff0c;用户已经开始期待根据个人兴趣定制搜索结果。如果我们听的所有歌曲都是摇滚歌曲&#xff0c;那么在搜索 “Crazy” 时&#xff0c;我们会期望 Aerosmith 的歌曲排在搜索结果的首位&#xff0c;而不是 Gnarls Barkley 的…

使用安信可Ai-WB2-12F开启wifi与手机通信TCP-IP(AT指令)

当时在做两个单片机之间无线通信&#xff0c;或者单片机与手机无线通信&#xff0c;就像找一个蓝牙和wifi双模的无线模块&#xff0c;一开始看ESP8684&#xff08;ESP32-C2&#xff09;这个芯片模组是有wifi和蓝牙的&#xff0c;买回来后才发现他不可以在程序运行中更换蓝牙或者…

《黑神话·悟空》这款游戏到底是用什么编程语言开发的?

你也有被这段游戏试玩视频刷屏吗&#xff1f; 13分钟、国产团队出品、B站上线不到24小时&#xff0c;播放量已经破千万&#xff0c;迅速火爆全网。 这就是来自国内游戏团队游戏科学&#xff08;Game Science&#xff09;开发的3A大作《黑神话&#xff1a;悟空》。 《黑神话悟…

vscode开发小程序

1 安装 "微信小程序开发工具" 2 安装 "WXML - Language Service" 3 安装 "wxmp-api-plugin" 或 "wechat-snippet" 4 安装"WXSS"

顶级的python入门教程!小白到大师,从这篇教程开始!

1. 为什么要学习Python&#xff1f; 学习Python的原因有很多&#xff0c;以下是几个主要的原因&#xff1a; 广泛应用&#xff1a;Python被广泛应用于Web开发、数据科学、人工智能、机器学习、自动化运维、网络爬虫、科学计算、游戏开发等多个领域。掌握Python意味着你可以在这…

嵌入式全栈开发学习笔记---Linux系统编程(进程间通信)

目录 进程间通信概述 进程通信目的 进程间通信的发展 进程间通信分类 管道通信 无名管道 有名管道mkfifo() 信号 发送信号kill & raise 忽略信号signal() 发送信号alarm() 消息队列 消息队列使用的步骤 创建消息队列msgget() 读写消息队列msgrcv()/msgsnd()…

ip地址一天变化好几次

‌IP地址每天变化的原因主要取决于其分配方式&#xff1a;静态或动态。静态IP地址是长期固定分配给一台设备的&#xff0c;除非进行手动更改或网络配置发生变化&#xff0c;否则该设备的IP地址将保持不变。而动态IP地址则是根据网络环境和需求动态分配给设备的&#xff0c;可能…

一些评估模型的总结(1)

最近学习了评估模型&#xff08;如下所示&#xff09;&#xff0c;对这四种方法进行小总结。 目录 1. 层次分析法。&#xff08;主观赋权方法&#xff0c;主观确定成对比较矩阵&#xff09; 2. 熵权法&#xff08;基于数据的客观赋权的方法&#xff09; 3. topsis方法&…

【图论入门】图的存储

1.邻接矩阵 邻接矩阵是图论中用于表示图&#xff08;Graph&#xff09;结构的一种重要数据结构&#xff0c;特别适用于表示顶点之间连接关系的图形。在计算机科学和数学领域&#xff0c;它被广泛应用来编码无向图和有向图的信息。 特点&#xff1a; 1、无向图的邻接矩阵是对称…

Java:时区的用法

文章目录 ZoneId常见用法 ZonedDateTime常见方法 代码 黑马学习笔记 ZoneId 常见用法 ZonedDateTime 常见方法 代码 package NewTime;import java.time.Clock; import java.time.ZoneId; import java.time.ZonedDateTime;/*** Author: ggdpzhk* CreateTime: 2024-08-31*/ pu…

09:Logic软件原理图信号连通

原理图信号连通 快捷键&#xff1a;F2 2.添加网络名称