俄勒冈州立大学eMapR 实验室的Justin Braaten编写的文档、应用程序和 API ,由Robert Kennedy 博士指导
该站点是 Google Earth Engine 实现 LandTrendr 光谱-时间分割算法的指南。
直接进入- 使用 GUI 绘制分段时间序列或地图干扰。
非常感谢杨志强 (OSU) 和 Google Earth Engine 的工程师。没有您的帮助,这是不可能的!
这项工作得到了美国森林服务景观变化监测系统和 NASA 碳监测系统(NNH13AW62I,PI:Cohen;NNX16AQ25G,PI:Kennedy)、谷歌基金会资助(肯尼迪)和美国国家公园管理局合作协议的资助(P17AC00585)
偶尔回来查看新的 GEE 应用程序、示例脚本和 API 函数。您可以尝试在网站上进行硬刷新,以确保您看到最近的更改(您正在查看的可能是该网站以前缓存的版本)
本指南旨在介绍在 Google Earth Engine (GEE) 中运行 LandTrendr (LT) 的基础知识。它描述了 LT 概念框架、运行 LT-GEE 需要什么、如何运行它、输出是什么以及它们如何格式化。它还提供了三个示例脚本、一系列 LT 操作的用户界面以及一个用于固执但易于使用的 API。
LandTrendr 是一组光谱-时间分割算法,可用于中等分辨率卫星图像(主要是 Landsat)时间序列中的变化检测,以及生成基于轨迹的光谱时间序列数据,这些数据基本上不存在年际信号噪声。LT 最初是在 IDL(交互式数据语言)中实现的,但在 Google 工程师的帮助下,它已经移植到 GEE 平台(移植论文;GEE 概述;GEE 论文)。GEE 框架几乎消除了 IDL 实现中繁重的数据管理和图像预处理方面。它也比 IDL 实现快了光年,在 IDL 实现中,计算时间以分钟而不是天来衡量。
我们假设您有一个GEE 账号,您对GEE JavaScript API有点熟悉,并且对 LandTrendr(方法, 应用程序)有基本的了解。
图像时间序列中的每个像素都有一个故事要讲,LandTrendr 旨在简洁地讲述它们。我们来看一个例子;在这里,我们有一个像素相交 Lon:-123.845,Lat:45.889(图 2.1)来自美国太平洋西北部的针叶树占主导地位的工业林区。在其记录之初,它是一个成熟的二生针叶林,17 年来几乎没有变化。然后,在 2000 年和 2001 年的夏天之间,一条服务道路穿过它修建,去除了它的一些植被。在接下来的一年里,它经历了一次明显的收获,清除了所有剩余的植被。在过去的 14 年里,它一直在再生。最近,它是一个封闭的树冠,成熟的针叶林。
图 2.1。每个像素都讲述一个故事。Landsat 提供了景观特征的历史记录。通过从 Landsat 影像的时间序列中提取单个像素,可以重新计算构成像素 1 公顷区域的特征随时间的状态和变化。在本例中,我们分析了太平洋西北部(美国)工业林区的针叶林像素的历史,该区域经历了一段相对稳定的时期,植被急剧迅速丧失,随后又重新恢复。
这个示例像素的历史描述当然被删节了,并且只传达了状态和森林特征变化的中等分辨率视角。该像素故事的未删节版本包括它所代表的林分的许多其他小变化,但鉴于卫星传感器的精度和处理方法,所提供的描述是我们有信心的像素历史解释类型在图像时间序列。LandTrendr 是一种简洁算法,它会听取像素故事的年度、冗长、嘈杂的细节,并编写一个删节版本。
在实践中,LandTrendr 从像素的光谱历史中获取单一观点,如波段或指数,并通过一个过程来识别分隔光谱轨迹中持久变化或稳定时期的断点,并记录发生变化的年份发生了。这些由年份和光谱索引值定义的断点使我们能够将像素的光谱历史表示为一系列边界线段的顶点(图 2.2)。
图 2.2。LandTrendr 像素时间序列分割。图像数据被缩减为单个波段或光谱索引,然后通过断点(顶点)识别分为一系列直线段。
这种光谱历史的分段视图产生了两个简洁的特征。
在顶点之间插入新值的能力非常有用。它确保每个观察都与与像素所在位置和去向一致的轨迹对齐。我们可以将其视为事后增强的图像时间序列数据。它有两个实用的工具。它可以从时间序列中缺失的观察中填充数据(由于云或阴影而被掩盖),并保持预测映射随时间的一致性;例如,由于来自大气的光谱反射率或阴影差异的微小差异,年度森林分类不太可能在成熟和古老的针叶树之间反弹(图 2.3)。
图 2.3。事后增强的图像时间序列数据。时间序列断点或顶点的识别允许对顶点之间的观察进行插值,去除无关信息并将每个观察置于其所属轨迹的上下文中。这对于填充由于云和阴影而丢失的观测很有用,并使年度地图预测更加一致。
由于断点或顶点是按年份定义的,我们还可以将在一个光谱带或索引中识别的断点强加于任何其他光谱带或索引。例如,我们可以分割作为归一化燃烧比(NBR:[NIR-SWIR]/[NIR+SWIR])的像素时间序列来识别顶点,然后基于 NBR 分割短波红外 (SWIR) 波段- 已识别的顶点(图 2.4)。
图 2.4。将一种光谱表示的分割结构强加于另一种。在这里,我们使用 NBR 确定了像素时间序列的四个断点或顶点,然后使用这些顶点的年份对同一像素的 SWIR 波段时间序列的值进行分割和插值。
这很有用,因为我们可以使像素时间序列的整个数据空间相对于单个视角保持一致(图 2.5),并总结相同时间段的所有光谱表示的起始、结束和增量值,这可以成为强大的预测因子土地覆盖、变化的推动因素和状态转换。
图 2.5。一系列光谱表示可以标准化为单个光谱带或索引的分割结构。在这里,我们展示了流苏帽亮度、绿色度和湿度对 NBR 分割结构的标准化。这使我们能够利用多维光谱空间来描述光谱时期和断点的特性,以从一致的角度 (NBR) 预测土地覆盖、变化过程和转变。
光谱历史分段世界观的第二个特点是简单的几何计算可以总结光谱时代的属性(图 2.6)。可以基于顶点时间和频谱维度为每个段计算时间持续时间和频谱幅度。这些属性让我们可以很容易地查询到变化发生的时间、发生的频率、平均持续多长时间、扰动(或恢复)段的平均幅度等数据。我们还可以查询相邻段的信息到焦点片段。例如,我们可以问,扰动段之后的平均恢复率是多少,或者在我们归因于火灾的扰动段之前的像素时间序列的轨迹是什么。
图 2.6。段属性图。从这些属性中,我们可以总结和查询景观上每个像素的变化。
LT-GEE 需要两件事:
组成集合的图像数据需要表示随时间一致的观察结果。它不应包括来自大气、云和阴影、传感器差异或其他异常的噪声。时间序列的年度变化应该是景观物理特征变化的结果。本指南中的示例、GUI 和 API 函数使用USGS Landsat Surface Reflectance Tier 1数据集。这些数据已经过大气校正,包括使用CFMASK生成的云、阴影、水和雪掩膜。
USGS Landsat 表面反射的 GEE ImageCollection ID
尽管我们使用了 Landsat 表面反射率波段和光谱指数,但要有创意并尝试其他数据,例如某种覆盖类型的概率、某种覆盖类型的预测覆盖百分比、其他地球观测源等。 LandTrendr 并不关心数据是什么,它将简单地将提供的时间序列减少到少量片段并记录有关信号何时发生变化的信息。
收集必须每年仅包括一次观察。但是,因为云通常出现在任何给定的图像中,所以最好检索一个季节的多个图像,从每个图像中屏蔽云和云阴影,然后创建这些图像的合成,以便您有合理的年度空间覆盖范围- 查看像素。您应用的最佳像素合成方法取决于您。我们使用了接近目标日期和medoid 合成,我们更喜欢后者并将其包含在提供的示例中. LandTrendr 将分割图像集合中的第一个波段,并为每个后续波段生成年度拟合顶点 (FTV) 数据。因此,您需要处理您的集合,以便您想要分割的波段或光谱索引是第一个波段,并且您想要拟合顶点的任何其他波段都应该跟随。您选择用于细分的波段或指数应基于明智的决定,并根据其对您正在处理的景观条件变化的敏感性进行加权。对于灌木、树木、针叶树、落叶等,变化的最佳光谱表示可能不同。我们发现 SWIR 波段和利用它们的指数通常对变化非常敏感,但我们也知道它是高度可变的。您应该尝试对多个波段或指数进行分段,以查看哪种效果最好。
在提供的示例脚本中,我们合成了北半球生长季节(6 月中旬至 9 月中旬)的图像日期,这对于 25-50 度纬度似乎非常有效。如果您要包含生长季节的图像,在南半球工作的人们将需要修改示例脚本,因为它跨越了新年:例如,2016 年 12 月到 2017 年 2 月。您还必须处理如何标记年度图像合成的年份 - 应该是生长季节合成的前一年还是后一年?
图像采集构建中的两个真正重要的步骤包括 1) 在年度图像合成期间屏蔽云和云阴影像素,以及 2) 确保要分割的光谱带或索引是定向的,以便植被损失由正增量表示。例如,当植被从一次观测到下一次消失时,NBR 在其自然方向上会导致负增量。在这种情况下,NBR 在被分割之前必须乘以 -1。相反,如果选择 Landsat TM 波段 5 (SWIR) 进行分割,则不需要对光谱值进行反演,因为原生地,植被损失由正增量表示。
请注意,在 API 中,我们提供了用于构建年度 Landsat 表面反射率集合并将其转换为格式以供 LandTrendr 使用的集合的函数。请参阅API 函数部分中的buildSRcollection
和buildLTcollection
函数。
LT-GEE 函数采用 9 个参数:8 个用于调整光谱时间分割方式的控制参数,以及年度图像收集。LandTrendr 的原始论文描述了更改其中一些参数值的影响和敏感性。我们建议您尝试更改设置,以查看最适合您工作环境的方法。在 GEE 中使用 LT 的好处之一是参数设置可以轻松快速地迭代以找到最佳设置。
范围 | 类型 | 默认 | 定义 |
---|---|---|---|
最大分段数 | 整数 | 要在时间序列上拟合的最大段数 | |
尖峰阈值 | 漂浮 | 0.9 | 抑制尖峰的阈值(1.0 表示没有抑制) |
顶点计数过冲 | 整数 | 3 | 初始模型可以超出 maxSegments + 1 个顶点这个数量。稍后,它将被修剪为 maxSegments + 1 |
防止一年恢复 | 布尔值 | 错误的 | 防止代表一年恢复的段 |
恢复阈值 | 漂浮 | 0.25 | 如果一个段的恢复率快于 1/recoveryThreshold(以年为单位),则该段被禁止 |
阈值 | 漂浮 | 0.1 | 如果拟合模型的 p 值超过此阈值,则丢弃当前模型并使用 Levenberg-Marquardt 优化器拟合另一个模型 |
最佳模特比例 | 漂浮 | 1.25 | 将具有最多 p 值的顶点的模型从 p 值最低的模型中取出至多此比例 |
minObservationsNeeded | 整数 | 6 | 执行输出拟合所需的最小观察值 |
时间序列 | 图像集 | 从中提取趋势的集合(假设集合中的每个图像代表一年)。第一个波段用于寻找断点,所有后续波段都使用这些断点进行拟合 |
LT-GEE 使用以下函数运行:ee.Algorithms.TemporalSegmentation.LandTrendr
该函数将参数参数字典作为输入。
在最基本的形式中,在 Google Earth Engine 中运行 LandTrendr 需要 6 个步骤。以下代码片段有助于说明这些步骤。
以下代码片段仅作为演示帮助。在应用程序中,使用提供的代码示例进行学习和构建,并利用我们组合在一起的API 函数来构建集合并运行 LandTrendr
var startYear = 1985;
var endYear = 2010;
ee.Geometry
var coords = [[-123.925, 42.996],
[-122.327, 42.996],
[-122.327, 43.548],
[-123.925, 43.548],
[-123.925, 42.996]];
var aoi = ee.Geometry.Polygon(coords);
var run_params = {
maxSegments: 6,
spikeThreshold: 0.9,
vertexCountOvershoot: 3,
preventOneYearRecovery: true,
recoveryThreshold: 0.25,
pvalThreshold: 0.05,
bestModelProportion: 0.75,
minObservationsNeeded: 6
};
for(var year = startYear; year <= endYear; year++) {
var img = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
.filterBounds(aoi)
.filterDate(year+'-06-15', year+'-09-15');
img = reduceToSingeImageMockFunction(img);
var tempCollection = ee.ImageCollection(img.select(['B5']));
if(year == startYear) {
var srCollection = tempCollection;
} else {
srCollection = srCollection.merge(tempCollection);
}
};
run_params.timeSeries = srCollection;
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params);
请注意,为了 LT-GEE 运行的基本示例,我们没有解决集合构建中两个真正重要的步骤:1)在年度图像合成(步骤 4)和 2)期间屏蔽云和云阴影像素以确保要被分割的光谱带或指数的方向使得植被损失由正增量表示(我们使用了 SWIR 波段,这是在 LT-GEE 中使用的正确方向)。
LT-GEE 的结果包括(图 5.1):
图 5.1。从 LT-GEE 返回哪些数据的可视化图表。每个图例项都作为输出返回。
LT-GEE 的结果不能立即用于分析、显示或导出为变化图或拟合时间序列数据。将每个像素视为需要解包的一组数据。每个像素的数据打包类似于 Python 或 R 中的嵌套列表。主要列表如下所示:
[[Annual Segmentation Info], Fitting RMSE, [Fitted Time Series n]]
在 GEE 构造中,该主要列表是具有至少 2 个波段的图像,一个包含年度分割信息,一个包含分割拟合的 RMSE。此外,如果 LT-GEE 的输入图像集合包含多个波段,则第一个波段之后的每个波段都将表示为光谱拟合的年度序列(图 5.2 和图 5.3)。
图 5.2。LT-GEE 的结果本质上是每个像素的列表列表,用于描述分割并可选择提供拟合的年度光谱数据 (FTV)。输出作为具有至少 2 个波段的 GEE 图像提供,一个包含年度分割信息,一个包含分割拟合的 RMSE。此外,如果 LT-GEE 的输入图像集合包含多个波段,则第一个波段之后的每个波段都将表示为光谱拟合年度序列 (FTV)。
图 5.3。LT-GEE 的结果打印到 GEE 控制台。默认情况下包括“LandTrendr”和“rmse”,包括“B4_fit”是因为 Landsat TM/+ETM 波段 4 (B4) 作为第二个波段包含在输入集合中。
'LandTrendr' 波段是一个 4 x nYears 维度数组。你可以像这样子集:
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
var segmentationInfo = LTresult.select(['LandTrendr']); // subset the LandTrendr segmentation info
它包含 4 行和与时间序列中给定像素的年度观测值一样多的列。二维“LandTrendr”年度分段数组如下所示:
[
[1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, ...] // Year list
[ 811, 809, 821, 813, 836, 834, 833, 818, 826, 820, 765, 827, 775, ...] // Source list
[ 827, 825, 823, 821, 819, 817, 814, 812, 810, 808, 806, 804, 802, ...] // Fitted list
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ...] // Is Vertex list
]
您可以使用 GEEarraySlice
函数提取一行。以下是将年份和拟合值行提取为单独列表的示例:
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
var LTarray = LTresult.select(['LandTrendr']); // subset the LandTrendr segmentation info
var year = LTarray.arraySlice(0, 0, 1); // slice out the year row
var fitted = LTarray.arraySlice(0, 2, 3); // slice out the fitted values row
GEEarraySlice
函数将您要进行子集化的维度以及要提取的维度上的起点和终点作为输入。
“rmse”带是一个标量值,它是原始值和分段拟合值之间的均方根误差。
它可以是这样的子集:
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
var segmentationInfo = LTresult.select(['rmse']); // subset the rmse band
如果输入图像集合包含多个波段,则后续波段将作为 FTV 或拟合顶点数据波段包含在输出图像中。图像集合中第一个波段的由观测年份定义的分割被赋予这些波段。如果输入图像集合中缺少年份,它们将被插入到 FTV 波段中。如果存在序列开头或结尾的年份,则该值将设置为第一个/最后一个已知值。
通过选择波段名称,它可以是主要输出图像的子集,这将是来自输入图像集合的波段名称和“_fit”的串联,如“B4_fit”。以下是子集 FTV“适合”频段的示例:
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
var B4ftv = LTresult.select(['B4_fit']); // subset the B4_fit band
如果您不确定波段名称,可以通过将结果打印到 GEE 控制台来查看波段名称。
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
print(LTresult)
然后在控制台中的“Image”和“Band”对象中展开。
来自 LT-GEE 算法的结果被打包为阵列图像。如果您不熟悉阵列图像格式,请参阅GEE 文档. 作为阵列图像,最好将每个像素视为一个单独的信息容器。每个容器都独立于其他容器,并且可以具有由时间序列中的年数与该时间序列中的屏蔽观察数之间的差异确定的不同观察长度。图像数组非常灵活,在“LandTrendr”波段输出的情况下,它允许在 2 维(观察 [轴 1] 和属性 [轴 0])上进行切片,这对于提取给定的所有属性特别方便观察或一组观察(如识别为顶点的观察)。虽然对切片和操作分割信息很有用,但图像数组构造对于可视化和导出不是很好,arrayProject
) 和/或展平 ( arrayFlatten
) 数组。
具体来说,本节将介绍:
请注意,以下代码片段旨在作为学习和构建的模板。我们还在API 函数部分提供了执行这些操作的快捷函数,这大大简化了这些步骤。
该“LandTrendr”波段输出存在含有对于每个输入集合中未被掩蔽的观察信息的图像阵列。我们希望您能找到利用所有信息的方法,但我们只关注与光谱-时间分割中标识为顶点的观测有关的信息。为了仅提取这些观察,我们可以使用“LandTrendr”波段的第 4 行,它是一个布尔值,指示观察是否为顶点,以屏蔽所有其他行(年份、源值、拟合值):
var lt = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params) // run LandTrendr spectral temporal segmentation algorithm
.select('LandTrendr'); // select the LandTrendr band
var vertexMask = lt.arraySlice(0, 3, 4); // slice out the 'Is Vertex' row - yes(1)/no(0)
var vertices = lt.arrayMask(vertexMask); // use the 'Is Vertex' row as a mask for all rows
现在我们在vertices
数组中只有顶点观察。有了这个,我们可以查询关于顶点的信息,计算顶点的数量,我们还可以生成关于由顶点定义的段的信息,比如变化的幅度和段的持续时间。
在以下代码段中,我们将创建一系列变量,用于描述给定像素时间序列中每个段的 1) 开始年份、2) 结束年份、3) 开始值和 4) 结束值。为此,我们首先将vertices
数组的副本沿轴 1(列/年度观测值)移动 1 列,以便我们可以从另一个中减去一个以获得每个段的开始和结束年份以及开始和结束值。
var left = vertices.arraySlice(1, 0, -1); // slice out the vertices as the start of segments
var right = vertices.arraySlice(1, 1, null); // slice out the vertices as the end of segments
var startYear = left.arraySlice(0, 0, 1); // get year dimension of LT data from the segment start vertices
var startVal = left.arraySlice(0, 2, 3); // get spectral index dimension of LT data from the segment start vertices
var endYear = right.arraySlice(0, 0, 1); // get year dimension of LT data from the segment end vertices
var endVal = right.arraySlice(0, 2, 3); // get spectral index dimension of LT data from the segment end vertices
现在,对于给定像素时间序列中的每个段,我们知道开始和结束年份和值。有了这些信息,我们可以通过从每个段的结束年份和值中减去起始年份和值来计算每个段的持续时间以及变化的增量或幅度。
var dur = endYear.subtract(startYear); // subtract the segment start year from the segment end year to calculate the duration of segments
var mag = endVal.subtract(startVal); // substract the segment start index value from the segment end index value to calculate the delta of segments
var rate = mag.divide(dur); // calculate the rate of spectral change
接下来,我们将创建一个包含所有段属性的数组。
var segInfo = ee.Image.cat([startYear.add(1), endYear, startVal, endVal, mag, dur, rate])
.toArray(0)
.mask(vertexMask.mask());
请记住,根据您是否反转输入集合中的频谱值,段增量和速率可能会从其原始方向反转。不过,这很好,因为我们总是知道正的 delta/rate 表示植被增加,而负的 delta/rate 表示植被减少。
这个分割信息数组是探索、查询和映射变化的基础。
段代表持久的光谱轨迹。像素的状态可以保持稳定或过渡到不同的状态。转变可以在短期或长期内发生,它们可以是主要的或次要的,并且开始和结束状态可以变化。在本节中,我们将获取分段信息并从给定像素时间序列中的所有分段中仅提取最大量级的植被损失分段。为此,我们可以按照变化的幅度对分段信息数组进行排序,然后切出第一个(幅度最大)分段的信息。
var sortByThis = segInfo.arraySlice(0,4,5).toArray(0).multiply(-1); // need to flip the delta here, since arraySort is working by ascending order
var segInfoSorted = segInfo.arraySort(sortByThis); // sort the array by magnitude
var bigDelta = segInfoSorted.arraySlice(1, 0, 1); // get the first segment in the sorted array (greatest magnitude vegetation loss segment)
一旦我们孤立了一个感兴趣的片段(在这种情况下植被损失最大),我们就可以将数组转换为图像并通过感兴趣片段的其他属性执行过滤。由于 LandTrendr 输入集合中的第一个波段是定向的,因此植被损失由正增量表示(参见LT-GEE 要求部分),您可能需要将来自光谱输入的任何属性乘以 -1 以重新定向它到它的原生状态。这在以下代码段中很明显.multiply(distDir)
,其中distDir
是可能反转值的标量。还可以按照示例脚本部分中的链接查看distDir
使用方式。
var bigDeltaImg = ee.Image.cat(bigDelta.arraySlice(0,0,1).arrayProject([1]).arrayFlatten([['yod']]),
bigDelta.arraySlice(0,1,2).arrayProject([1]).arrayFlatten([['endYr']]),
bigDelta.arraySlice(0,2,3).arrayProject([1]).arrayFlatten([['startVal']]).multiply(distDir),
bigDelta.arraySlice(0,3,4).arrayProject([1]).arrayFlatten([['endVal']]).multiply(distDir),
bigDelta.arraySlice(0,4,5).arrayProject([1]).arrayFlatten([['mag']]).multiply(distDir),
bigDelta.arraySlice(0,5,6).arrayProject([1]).arrayFlatten([['dur']]),
bigDelta.arraySlice(0,6,7).arrayProject([1]).arrayFlatten([['rate']]).multiply(distDir));
现在我们有一个传统图像,每个段属性都有带。从这里我们可以创建并应用一个掩码,以仅识别大于/小于(取决于光谱指数方向)最小值且持续时间小于 4 年的植被损失量级。
var distMask = bigDeltaImg.select(['mag']).lt(100)
.and(bigDeltaImg.select(['dur']).lt(4));
var bigFastDist = bigDeltaImg.mask(distMask).int16(); // need to set as int16 bit to use connectedPixelCount for minimum mapping unit filter
最后,我们可以根据干扰检测的年份应用最小映射单元来消除空间噪声(您也可以通过其他属性修补像素)
var mmuPatches = bigFastDist.select(['yod']) // patchify based on disturbances having the same year of detection
.connectedPixelCount(mmu, true) // count the number of pixel in a candidate patch
.gte(11); // are the the number of pixels per candidate patch greater than user-defined minimum mapping unit?
var bigFastDist = bigFastDist.updateMask(mmuPatches); // mask the pixels/patches that are less than minimum mapping unit
前面的部分描述了如何操作“LandTrendr”波段数组。在本节中,我们将把注意力转向一个 FTV 乐队的例子。如果 LT-GEE 在包含多个波段的集合上运行,则后续波段将作为 FTV 波段包含在 LT-GEE 输出中,其中用户定义的起始年和结束年之间的所有观测值都将适合第一个波段的分割结构。
在包含 NBR 作为波段 1 和波段 4 (NIR) 作为第二波段的集合上运行 LT-GEE。输出将包括一个适合 NBR 分段的波段 4,我们将通过调用它的波段名称、来自 LT-GEE 输入集合的波段名称和“_fit”的串联来选择它。
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
var B4ftv = LTresult.select(['B4_fit']); // subset the B4_fit band
'B4ftv' 变量是一个一维数组。要将其转换为带代表年份的图像,我们使用该arrayFlatten
函数。该arrayFlatten
函数采用一系列带标签,其尺寸与要展平的图像数组的尺寸相匹配。我们有 1 个维度,沿着单轴的每个观察值都代表一年,所以我们只需要制作一个年份列表并将其作为输入提供给arrayFlatten
。
var years = []; // make an empty array to hold year band names
for (var i = startYear; i <= endYear; ++i) years.push('yr'+i.toString()); // fill the array with years from the startYear to the endYear and convert them to string
var B4ftvStack = B4ftv.arrayFlatten([years]); // flatten this out into bands, assigning the year as the band name
现在 FTV 图像阵列是一个标准的图像波段堆栈,可以轻松显示或导出。
这些示例脚本依赖于LT-GEE API,需要在运行脚本之前将其添加到您的 Google Earth Engine 脚本库中。要添加 API,请单击此链接。
请参阅API 参考以查找用于构建图像集合和处理 LandTrendr 输出的更多功能。
可以从 LandTrendr 的分段线顶点提取和映射变化事件。有关变化事件检测年份、变化幅度、变化持续时间和变化前事件频谱数据的信息都可以映射。这些变更映射脚本示例使用与 GEE APP UI LandTrendr Change Mapper相同的 LT-GEE API 函数。在提交将数据下载到 Google Drive 之前,使用它来帮助参数化脚本并探索输出。
在这个例子中,我们将绘制最大的植被损失段并显示变化检测的年份和变化的幅度。此外,我们会将更改属性作为 GeoTiff 文件写入您的 Google Drive 帐户。
GEE 路径:users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Greatest Disturbance Mapping
在本例中,我们将绘制最大的植被增益段并显示变化检测年份和变化幅度。此外,我们会将更改属性作为 GeoTiff 文件写入您的 Google Drive 帐户。
GEE 路径:users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Greatest Growth Mapping
我们开发了一些用于探索 LT-GEE 时间序列数据的 UI 应用程序。它们可以在我们的公共 GEE 存储库中找到。要访问应用程序,请访问此 URL:https : //code.earthengine.google.com/?accept_repo=users/ emaprlab/ public)。它会将users/emaprlab/public存储库添加到您的 GEE 帐户。添加后,可以在GEE 脚本库的Reader权限组中找到存储库。您会在那里找到以下作为 GEE 应用程序运行的用户界面应用程序(即不需要您加载和运行脚本)。
此外,我们还开发了一个基于脚本的 UI 工具,该工具结合了上述许多功能,并为某些组件添加了功能。+ [LandTrendr 数据可视化和下载工具] | 关联
*注意:上面的链接是静态的。要访问脚本的最新版本,请从 GEE 界面打开脚本 **users/emaprlab/public:LT-data-download/LT-Data-Visualization-Download-App_v1.0*
该UI LandTrendr像素时间系列绘图仪将绘制陆地卫星表面反射源和LandTrendr配合指数为选定的位置。该脚本可用于简单地探索和可视化像素的光谱时间空间,比较一系列指标在识别景观变化方面的有效性,以及参数化 LandTrendr 以使其最适合您的研究区域。
等待一两分钟,您选择的所有指数的源和 LandTrendr 拟合时间序列数据图都会出现。下次单击某个点或提交输入时,将清除所有当前绘图并显示新的绘图集。
所述UI LandTrendr更改映射器将显示变化的地图层(植被损失或增益)属性,包括:变化检测,幅度变化,变化事件的持续时间的年,和预变化频谱值。
检查员模式选择器。在应用程序的右侧面板中,有一个复选框用于是否在Inspector 模式下与地图交互。当检查器模式被激活时,地图点击将检索点击像素的更改事件属性并将它们显示在右侧面板中。禁用时,地图单击将开始对单击点周围的区域进行映射更改。
该UI LandTrendr拟合指数三角洲RGB映射将显示一个 RGB 颜色图,表示三个时间片的光谱带或索引值。正式地,它被称为写函数内存插入变化检测。每种颜色的红色、绿色和蓝色都被分配了一年的光谱数据,然后这些数据被合成为一个 RGB 图像,其中红色、绿色和蓝色中的每一种都通过对每种颜色代表的年份的光谱强度进行加权来混合。作为一种快速可视化随时间变化或不变的方法,同时提供光谱强度的相对意义,它非常有用。如果我只是探索一个区域的变化,我会经常在严格映射干扰之前使用它,因为我对光谱分布和空间模式有一定的了解。一旦你掌握了解释颜色的方法,它真的是一个非常有趣和有用的可视化。
下图是帮助解释颜色的指南。
该UI LandTrendr时间序列动画将动画GIF从已通过平滑光谱LandTrendr时空分割陆地卫星的时间序列。
此应用程序使用最初由 Gennadii Donchyts 开发的绘图工具的修改版本。
*注意:上面的链接是静态的。要访问脚本的最新版本,请从 GEE 界面打开脚本 **users/emaprlab/public:LT-data-download/LT-Data-Visualization-Download-App_v1.0*
我们开发了一个 LandTrendr JavaScript 模块,用作构建 LandTrendr 输入集合、运行 LandTrendr 和处理输出的 API。可以从我们的公共 GEE 存储库访问 API。要使用 API,您必须首先访问此 URL:https : //code.earthengine.google.com/?accept_repo=users/ emaprlab/ public。它会将users/emaprlab/public存储库添加到您的 GEE 帐户。
要使用 API,您必须使用以下行将LandTrendr.js模块导入脚本 - 将其放在脚本的顶部。
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
LandTrendr API 函数使用USGS Landsat Surface Reflectance Tier 1数据集。他们可以选择使用CFMASK从图像中屏蔽云、云阴影和雪。年度图像合成是使用 medoid 方法生成的:对于给定的图像像素,medoid 是给定波段的值,该值在数值上最接近所考虑图像(提供的年度数据范围之间的所有图像)中所有相应像素的中值。TM 和 ETM+ 数据被包含在没有改变的年度 medoid 合成中,但 OLI 图像波段 2、3、4、5、6 和 7 是子集并转换为 ETM+波段 1、2、3、4、5 和 7 的光谱特性,分别使用 Roy 等人 2016 年表 2 中报告的减少的主轴回归的斜率和截距。
buildSRcollection
构建年度表面反射率集合,可能在给定年份中包含许多图像。了解有多少像素可用于生成年度合成图像会很有帮助。此函数返回每年可用于在提供的年份和日期范围内合成的未屏蔽像素的计数。buildSRcollection
为提供的索引或波段列表。buildSRcollection
和buildLTcollection
功能。ftvList
给buildLTcollection
或的给定索引生成年度波段堆栈runLT
。对于给定的 FTV 索引,它每年将 FTV 阵列格式展平为一个波段。getSegmentData
函数生成的段数据数组,该函数返回由 LandTrendr 标识为 ee.Image 的段数。getChangeMap
描述:
构建 Landsat 表面反射 TM 等效波段 1、2、3、4、5、7 的年度云和云阴影遮蔽中心点复合。此集合在 LandTrendr 使用之外可能很有用,但也是为 LandTrendr 创建输入集合的基础。
用法:
buildSRcollection(startYear, endYear, startDay, endDay, aoi, maskThese)
参数:
结果:
一个 ee.ImageCollection,其中每个图像代表给定年份的每个 TM 等效表面反射带 1-5 和 7 的观测中心点。在包含startYear和endYear的范围内将有与年份一样多的图像。如果该范围内不存在给定年份,则屏蔽带将充当填充符。类似地,如果某个给定像素在一年内的所有观测值都因为包含在 mask这些列表中而被屏蔽,则该像素将被屏蔽。
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var maskThese = ['cloud', 'shadow', 'snow']
// center and zoom the display in case outputs are to be mapped
Map.centerObject(aoi,10);
Map.addLayer(aoi);
// apply LandTrendr.js functions
var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi, maskThese);
print(annualSRcollection);
描述:
返回每年可用于在提供的年份和日期范围内合成的未屏蔽像素的计数。
用法:
buildClearPixelCountCollection(startYear, endYear, startDay, endDay, aoi, maskThese)
参数:
结果:
一个 ee.ImageCollection,在提供的年份范围内每年包含一个单波段图像,该图像表示在给定日期范围和掩码类别的情况下可用于合成的未掩码像素数,以作为掩码像素包括在内。
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var maskThese = ['cloud', 'shadow', 'snow']
// center and zoom the display in case outputs are to be mapped
Map.centerObject(aoi,10);
Map.addLayer(aoi);
// apply LandTrendr.js functions
var nClearCollection = ltgee.buildClearPixelCountCollection(startYear, endYear, startDay, endDay, aoi, maskThese);
print(nClearCollection);
描述:
将年度表面反射率集合中的图像转换buildSRcollection
为提供的索引或波段列表。
用法:
transformSRcollection(srCollection, bandList)
参数:
buildSRcollection
函数生成的年度表面反射率集合。结果:
一个 ee.ImageCollection,它每年包含一个图像,该图像基于由buildSRcollection
转换为bandList
参数中提供的索引的函数构建的图像集合。
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var bandList = ['NBR', 'NDVI', 'TCW'];
// center and zoom the display in case outputs are to be mapped
Map.centerObject(aoi,10);
Map.addLayer(aoi);
// build annual surface reflectance collection (cloud and shadow masked medoid composite)
var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi);
// transform the annual surface reflectance bands to whatever is in the bandList variable
var indexCollection = ltgee.transformSRcollection(annualSRcollection, bandList);
// example of extracting year 2000 as an image from the collection
var year2000 = ee.Image(indexCollection.filterDate('2000-01-01','2000-12-31').first());
print(year2000);
描述:
构建一个集合作为 LandTrendr 的输入。它将准备一个集合,其中第一个波段是光谱索引以作为时间分割的基础,随后的波段将被拟合到分割索引的分割结构。
用法:
buildLTcollection(collection, index, ftvList)
参数:
buildSRcollection
函数生成的年度表面反射率集合。index
参数的分段。此参数也可以由空列表设置,[]
该列表有效并导致 LandTrendr 输出图像中不包含 FTV 波段。结果:
一个 ee.ImageCollection,其中每个图像代表要由 LandTrendr 分割和拟合的波段或索引的组合。在包含startYear和endYear的范围内将有与年份一样多的图像。如果该范围内不存在给定年份,则屏蔽带将充当填充符。类似地,如果一年内给定像素的所有观测值都因云、云影或雪而被屏蔽,则该像素将被屏蔽。每个图像的第一个波段将是index
参数定义的任何光谱表示- 它的方向将使得植被损失导致正光谱增量。任何以下波段将由ftvList
参数,以相同的顺序,并且在光谱增量方向方面未修改。
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var index = 'NBR';
var ftvList = ['NDVI', 'B4', 'B3'];
// center and zoom the display in case outputs are to be mapped
Map.centerObject(aoi,10);
Map.addLayer(aoi);
// apply LandTrendr.js functions
var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi);
var annualLTcollection = ltgee.buildLTcollection(annualSRcollection, index, ftvList);
print(annualLTcollection)
描述:
将图像集合转换为图像堆栈,其中集合中每个图像的每个波段都作为一个波段连接成单个图像。用于在集合上映射函数,例如将表面反射率转换为 NDVI,然后将生成的集合转换为波段顺序时间序列图像堆栈。
用法:
collectionToBandStack(collection, startYear, endYear)
参数:
transformSRcollection(srCollection, ['NDVI'])
、 或产生的结果buildClearPixelCountCollection
。结果:
一个 ee.Image 表示startYear和endYear之间给定集合中每个图像的带序列时间序列的图像带。请注意,图像集合中的掩码值将填充为 0
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var bandList = ['NDVI'];
// center and zoom the display in case outputs are to be mapped
Map.centerObject(aoi,10);
Map.addLayer(aoi);
// build annual surface reflectance collection (cloud and shadow masked medoid composite)
var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi);
// transform the annual surface reflectance bands to whatever is in the bandList variable
var indexCollection = ltgee.transformSRcollection(annualSRcollection, bandList);
// transform image collection of NDVI (from bandList) to a image band stack
var collectionBandStack = ltgee.collectionToBandStack(indexCollection, startYear, endYear);
print(collectionBandStack);
Map.addLayer(collectionBandStack, {"bands":["2000"],"min":-100,"max":1000,"palette":["ff2f0d","fff825","0ab308"]});
描述:
给定一组参数运行 LandTrendr。这是一个包装buildSRcollection
和buildLTcollection
功能。
用法:
runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams, maskThese)
参数:
index
参数的分段。结果:
LT-GEE 输出部分中描述的阵列图像
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var index = 'NBR';
var ftvList = [];
var runParams = {
maxSegments: 6,
spikeThreshold: 0.9,
vertexCountOvershoot: 3,
preventOneYearRecovery: true,
recoveryThreshold: 0.25,
pvalThreshold: 0.05,
bestModelProportion: 0.75,
minObservationsNeeded: 6
};
var maskThese = ['cloud', 'shadow', 'snow']
// center and zoom the display in case outputs are to be mapped
Map.centerObject(aoi,10);
Map.addLayer(aoi);
// apply LandTrendr.js functions
var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams, maskThese);
print(lt)
描述:
从 LandTrendr 识别的断点顶点生成有关频谱-时间段的信息数组。返回所有光谱-时间段,或仅返回植被损失段,或仅返回植被生长段。
用法:
getSegmentData(lt, index, delta, right)
参数:
runLT()
或运行 LandTrendr 的结果的图像数组ee.Algorithms.TemporalSegmentation.LandTrendr()
。lt
参数生成 LandTrendr 输出。'all'
段,要么是仅植被'loss'
段,要么是仅植被'gain'
段。true
或者false
是否将光谱值调整到它们在 0 附近的自然方向。 LandTrendr 要求被分割的光谱索引是定向的,以便植被损失表示为正光谱增量(请参阅LandTrendr 集合构建)。这简化了对结果分割的解释——每个正增量表示植被损失(该算法是围绕 Landsat TM Band 5 SWIR 设计的)。因此,您可能希望重新定向或校正分段数据中的频谱值,使其处于自然形式且更易于直观解释。此参数仅在向'all'
参数提供参数时影响结果delta
。默认为false
。结果:
一个尺寸为:8(行)x nSegments(列)的图像数组。每行描述由 LandTrendr 标识的每个像素时间序列的段的属性。每列代表时间序列中每个像素的一个片段,从序列中最早到最晚排序。
*由 LandTrendr 拟合的 RMSE 标准化的分段光谱增量。有关 DSNR 的更多详细信息,请参见此处:Cohen, WB, Yang, Z., Healey, SP, Kennedy, RE, & Gorelick, N. (2018)。用于森林干扰检测的 LandTrendr 多光谱集成。环境遥感,205,131-140。
要提取一行,请使用该arraySlice
函数。例如,如果你想只与段开始几年的工作,你可以这样做:var segStartYr = segInfo.arraySlice(0, 0, 1)
。有关处理这些数据的更多信息,请参阅使用输出部分。
为参数参数选择loss
或时,频谱段的开始和结束值将处于 0 附近的自然索引方向,并且在参数参数等于时选择if 。在其他情况下,根据分段索引,这些值可能会反转。此外,当为参数参数选择或时,段增量和速率将是绝对值。在选择where作为参数自变量的情况下,频谱增量和变化率的符号将取决于索引在零附近的方向以及参数自变量是等于还是假。growthdeltaallrighttruelossgrowthdeltaalldeltarighttrue
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var index = 'NBR';
var ftvList = [];
var runParams = {
maxSegments: 6,
spikeThreshold: 0.9,
vertexCountOvershoot: 3,
preventOneYearRecovery: true,
recoveryThreshold: 0.25,
pvalThreshold: 0.05,
bestModelProportion: 0.75,
minObservationsNeeded: 6
};
// center and zoom the display in case outputs are to be mapped
Map.centerObject(aoi,10);
Map.addLayer(aoi);
// apply LandTrendr.js functions
var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams);
var segInfo = ltgee.getSegmentData(lt, index, 'all');
print(segInfo);
Map.addLayer(segInfo); // use 'Inspector' to explore values
描述:
为作为索引提供ftvList
给buildLTcollection
或的给定索引生成年度波段堆栈runLT
。对于给定的 FTV 索引,它每年将 FTV 阵列格式展平为一个波段。
用法:
getFittedData(lt, startYear, endYear, index)
参数:
runLT()
或运行 LandTrendr 的结果的图像数组ee.Algorithms.TemporalSegmentation.LandTrendr()
。结果:
一个 ee.Image 表示作为index
参数提供的任何指数的拟合顶点年度光谱数据。将有与包含startYear和endYear的范围内的年份一样多的带。
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var index = 'NBR';
var ftvList = ['NBR', 'NDVI'];
var runParams = {
maxSegments: 6,
spikeThreshold: 0.9,
vertexCountOvershoot: 3,
preventOneYearRecovery: true,
recoveryThreshold: 0.25,
pvalThreshold: 0.05,
bestModelProportion: 0.75,
minObservationsNeeded: 6
};
// center and zoom the display in case outputs are to be mapped
Map.centerObject(aoi,10);
Map.addLayer(aoi);
// apply LandTrendr.js functions
var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams);
var nbrFTV = ltgee.getFittedData(lt, startYear, endYear, ftvList[0]);
var ndviFTV = ltgee.getFittedData(lt, startYear, endYear, ftvList[1]);
print(nbrFTV);
print(ndviFTV);
描述:
生成一组地图图层,描述植被损失或增加事件,其属性包括:变化检测年份、光谱增量、变化事件持续时间、变化前事件光谱值和光谱变化率。每个属性都是 ee.Image 的一个带。
用法:
getChangeMap(lt, changeParams)
参数:
runLT()
或运行 LandTrendr 的结果的图像数组ee.Algorithms.TemporalSegmentation.LandTrendr()
。'loss'
或者'gain'
以定义是否映射植被损失或增益。'greatest'
, 'least'
, 'newest'
, 'oldest'
, 'fastest'
, 'slowest'
。true
或false
是否按年份过滤。如果true
,那么您必须同时定义start
和end
描述如下。true
或false
是否按幅度过滤。如果true
,那么您必须如下定义value
和operator
描述。operator
参数进行比较的变化事件的频谱增量的绝对值。它index
以上述runLT
函数中的参数定义的频谱索引为单位。如果index
是 NBR 或 NDVI 等标准化指数,则该值应乘以 1000。例如,如果要映射大于 0.4 的 NDVI delta 段,则此处的值将是 400。如果index
是 Landsat 光谱带,例如'B5',单位是 USGS Collection 1 Surface Reflectance 产品的单位。'<'
或'>'
,用于将变化事件幅度与value
前面描述的阈值进行比较。只有导致true
条件的更改段才会包含在地图中true
或false
是否应通过 LandTrendr 拟合的 RMSE 对幅度进行标准化。如果true
则value
需要将其解释为 RMSE 的一个因素。如果您只想包括大于拟合的 RMSE 的变化,value
则应为 1,如果您只想包括大于 RMSE 的 2 倍的变化,value
则应为 2。有关 DSNR 的更多详细信息可以在此处找到: Cohen, WB, Yang, Z., Healey, SP, Kennedy, RE, & Gorelick, N. (2018)。用于森林干扰检测的 LandTrendr 多光谱集成。环境遥感,205,131-140。true
或false
是否按持续时间过滤。如果true
,那么您必须如下定义value
和operator
描述。operator
参数进行比较所花费的年数。它以年为单位。'<'
或'>'
,用于将更改事件持续时间与value
之前描述的阈值进行比较。只有导致true
条件的更改段才会包含在地图中。true
或false
是否通过更改前的光谱值进行过滤。如果true
,那么您必须如下定义value
和operator
描述。operator
参数进行比较的变化事件之前的频谱索引值。它index
以上述runLT
函数中的参数定义的频谱索引为单位。如果index
是 NBR 或 NDVI 等标准化指数,则该值应乘以 1000。例如,如果要通过大于 0.3 的 NDVI 更改前值过滤更改事件,则此处的值为 300。如果index
是Landsat 光谱带,如“B5”,单位是 USGS Collection 1 表面反射产品的单位。应根据指数或波段的自然取向进行签名。true
或false
是否按最小补丁大小过滤更改事件。如果true
,那么您必须定义value
如下所述。请参阅下面的示例以格式化字典
结果:
具有符合过滤标准的变更事件属性带的 ee.Image 包括:
'yod'
年份)'mag'
变化事件频谱增量的绝对值)'dur'
年)'preval'
频谱值)'rate'
( mag/dur
)'dsnr'
( mag/fit rmse
) 乘以 100 以保留 Int16 数据的两位小数精度。有关该指标的更多信息,请参阅以下内容:Cohen, WB, Yang, Z., Healey, SP, Kennedy, RE, & Gorelick, N. (2018)。用于森林干扰检测的 LandTrendr 多光谱集成。环境遥感,205,131-140。笔记:
使用LT-GEE Change Mapper App作为测试来确定参数值。
例子:
//##########################################################################################
// START INPUTS
//##########################################################################################
// define collection parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var index = 'NBR';
var maskThese = ['cloud', 'shadow', 'snow', 'water'];
// define landtrendr parameters
var runParams = {
maxSegments: 6,
spikeThreshold: 0.9,
vertexCountOvershoot: 3,
preventOneYearRecovery: true,
recoveryThreshold: 0.25,
pvalThreshold: 0.05,
bestModelProportion: 0.75,
minObservationsNeeded: 6
};
// define change parameters
var changeParams = {
delta: 'loss',
sort: 'greatest',
year: {checked:false, start:2000, end:2010},
mag: {checked:true, value:200, operator: '>', dsnr:false},
dur: {checked:true, value:4, operator: '<'},
preval: {checked:true, value:300, operator: '>'},
mmu: {checked:true, value:11},
};
//##########################################################################################
// END INPUTS
//##########################################################################################
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// add index to changeParams object
changeParams.index = index;
// run landtrendr
var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, [], runParams, maskThese);
// get the change map layers
var changeImg = ltgee.getChangeMap(lt, changeParams);
// set visualization dictionaries
var palette = ['#9400D3', '#4B0082', '#0000FF', '#00FF00', '#FFFF00', '#FF7F00', '#FF0000'];
var yodVizParms = {
min: startYear,
max: endYear,
palette: palette
};
var magVizParms = {
min: 200,
max: 800,
palette: palette
};
// display the change attribute map - note that there are other layers - print changeImg to console to see
Map.centerObject(aoi, 11);
Map.addLayer(changeImg.select(['mag']), magVizParms, 'Magnitude of Change');
Map.addLayer(changeImg.select(['yod']), yodVizParms, 'Year of Detection');
描述:
给定由该getSegmentData
函数生成的段数据数组,该函数返回由 LandTrendr 标识为 ee.Image 的段数。
用法:
getSegmentCount(segData)
参数:
getSegmentData
函数返回的图像数组。结果:
描述由 LandTrendr 识别的每个像素时间序列的段数的单波段 ee.Image。
笔记:
此函数计算从getSegmentData
函数返回的段数,可以选择返回植被loss、gain或所有段。段数将反映delta
提供给getSegmentData
函数的参数。例如,如果您运行该getSegmentData
函数并将delta
参数设置为as'loss'
然后运行该函数,您将获得植被损失段数的地图。或者,如果delta
参数设置为'all'
,您将获得包含所有段类型的段计数映射。
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var index = 'NBR';
var ftvList = [];
var runParams = {
maxSegments: 6,
spikeThreshold: 0.9,
vertexCountOvershoot: 3,
preventOneYearRecovery: true,
recoveryThreshold: 0.25,
pvalThreshold: 0.05,
bestModelProportion: 0.75,
minObservationsNeeded: 6
};
var maskThese = ['cloud', 'shadow', 'snow'];
// center and zoom the display in case outputs are to be mapped
Map.centerObject(aoi,10);
// run LandTrendr using the LT-GEE API
var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams, maskThese);
// get the segment data array
var segData = ltgee.getSegmentData(lt, index, 'all', true);
// get the segment count
var segCount = ltgee.getSegmentCount(segData);
Map.addLayer(segCount, {"min":0, "max":runParams.maxSegments});
描述:
从调用 LandTrendr 分割产生的三个 FTV 波段创建一组 RGB 可视化图像。这对于创建缩略图、幻灯片和 GIF 很有用。
用法:
getFittedRGBcol(lt, startYear, endYear, bands, visParams)
参数:
runLT()
或ee.Algorithms.TemporalSegmentation.LandTrendr()
结果:
包含startYear
和之间每年的 RGB 图像的图像集合endYear
。
笔记:
此函数对于生成用于 GIF 电影的高质量时间序列帧很有用。以下示例将输出应用于地球引擎getVideoThumbURL
函数以生成 GIF。
例子:
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// define parameters
var startYear = 1984;
var endYear = 2018;
var startDay = '06-20';
var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var index = 'NBR';
var ftvList = ['TCB', 'TCG', 'TCW'];
// define LandTrendr parameters
var runParams = {
maxSegments: 6,
spikeThreshold: 0.9,
vertexCountOvershoot: 3,
preventOneYearRecovery: true,
recoveryThreshold: 0.25,
pvalThreshold: 0.05,
bestModelProportion: 0.75,
minObservationsNeeded: 6
};
// define the RGB visualization parameters
var visParams = {
min: [604, -49, -2245],
max: [5592, 3147, 843],
gamma: [1, 1, 1]
};
// define the GIF video parameters
var vidParams = {
crs: 'EPSG:3857',
dimensions: 300,
region: aoi.buffer(10000).bounds(),
framesPerSecond: 8
};
// apply LandTrendr.js functions
var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams);
// get RGB collection
var rgbCol = ltgee.getFittedRGBcol(lt, startYear, endYear, ftvList, visParams);
// print the RGB GIF link
print(rgbCol.getVideoThumbURL(vidParams));
// show RGB image for year 2000 on map
var rgb2000 = rgbCol.filterDate('2000-01-01', '2000-12-31').first().clip(vidParams.region);
Map.centerObject(rgb2000, 10);
Map.addLayer(rgb2000, {}, 'TC/RGB');
LandTrendr.js 函数库有一个定义的索引和波段列表,它将使用。下面的表 9.1 是要使用的“索引”代码列表及其通用名称。您应该将它们指定为全大写字符串。
代码 | 姓名 |
---|---|
丁腈橡胶 | 标准化燃烧率 |
NDVI | 归一化差异植被指数 |
NDSI | 归一化不同雪指数 |
NDMI | 归一化差异水分指数 |
TCB | 流苏帽亮度 |
TCG | 流苏帽绿色 |
TCW | 流苏帽湿度 |
三氯乙烯 | 流苏帽角 |
B1 | 专题地图等效波段 1 |
B2 | Thematic Mapper-equivalent Band 2 |
B3 | Thematic Mapper-equivalent Band 3 |
B4 | Thematic Mapper-equivalent Band 4 |
B5 | Thematic Mapper-equivalent Band 5 |
B7 | Thematic Mapper-equivalent Band 7 |
验证 LandTrendr 分割和派生干扰图的传统方法是 TimeSync 应用程序(论文)。它是作为 LandTrendr 的伴侣开发的,并遵循相同的光谱 - 时间顶点和分割框架。
请参阅此 GitHub存储库,了解从 Google Earth Engine 获取源数据和运行应用程序的桌面旧版所需的所有文件和说明。
问:我读过或听说
for
循环和客户端条件if
语句(如语句)是 GEE 禁忌,但您将它们包含在示例脚本中。这是怎么回事? 答:我们不会混合服务器端和客户端的对象和操作,据我们所知,这是主要问题。我们也不是 GEE 向导,所以拜托了,我们呼吁大家帮助制作更好、更适合 GEE 的模板脚本来分享。