在 Google 地球引擎中使用 QA 波段和位掩码
大多数光学卫星图像产品都带有一个或多个 QA 波段,允许用户评估每个像素的质量并提取满足其要求的像素。QA 波段最常见的应用是提取有关多云像素的信息并对其进行屏蔽。但是 QA 波段包含大量其他信息,可以帮助您从分析中删除低质量数据。通常,QA 频带中包含的信息存储为按位标志。在这篇文章中,我将介绍与位运算相关的基本概念,以及如何使用位掩码提取和屏蔽特定的质量指标。
对于这篇文章,我们将使用MOD11A1.006 Terra Land Surface Temperature and Emissivity Daily Global 1km数据集。但是这些概念和代码片段可以很容易地应用于任何其他数据集。查看乐队元数据,我们看到LST_Day_1km
乐队伴随着一个QC_Day
包含 LST 质量指标的波段。
了解 QA 标志
该QC_day
频段包含 8 位信息。这意味着像素值的范围可以从 0 到 255。这个波段中存储了 4 个不同的指标,每个指标都有 4 个可能的值。这些值的每种组合都会产生一个不同的 8 位数字,该数字存储在输出中。我们可以通过一个具体的例子来了解如何解释这些 QA 位。假设您将QC_Day
波段添加到地图并检查了一个像素。该像素的值为145。这是什么意思?嗯,值 145 是每个 QA 标志设置为特定值的结果。
提示:使用这个方便的十进制到二进制转换器来了解数字的二进制表示,反之亦然。
下图将值分解为位对并显示如何解释它们。
了解位掩码
假设您要查询 QA 波段中位 4-5 设置为特定值的所有像素。您将需要提取存储在位 4-5 中的信息,同时忽略所有其他位。这可以使用Bitmask来实现。简单地说,位掩码将保留感兴趣位中的信息,并将所有其他值设置为 0。
可以使用左移 (<<) 和右移 (>>) 运算符创建位掩码。GEE API 为和提供leftShift()
和rightShift()
功能。创建位掩码后,可以使用() 函数将其应用于输入图像。下面是一个提取特定位的 GEE API 函数。ee.Image()
ee.Number()
bitwiseAnd
1
2
3
4
5
6
7
8
|
// Helper function to extract the values from specific bits
// The input parameter can be a ee.Number() or ee.Image()
// Code adapted from google earth engine - Creating Cloud free images out of a MOD09A1 MODIS image in GEE? - Geographic Information Systems Stack Exchange
var bitwiseExtract = function (input, fromBit, toBit) {
var maskSize = ee.Number(1).add(toBit).subtract(fromBit)
var mask = ee.Number(1).leftShift(maskSize).subtract(1)
return input.rightShift(fromBit).bitwiseAnd(mask)
}
|
要理解这段代码,请看下图。我们将继续上一节中的示例,并尝试通过回答以下问题来了解该算法的工作原理:数字 145 中的第 4 位和第 5 位的值是多少?
屏蔽低质量数据
现在让我们将所有这些放在一起,看看我们如何屏蔽 MODIS LST 图像中的低质量数据。我们的目标是使用波段并从图像中QC_day
提取所有像素LST_Day_1km
- QA 标志(位 0-1)为0或1(LST 生产的质量良好和其他质量)
- 数据质量标志(位 2-3)为 0(良好的数据质量)
- LST 错误标志(位 6-7)为0(平均 LST 错误 ≤ 1K)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
var modisLST = ee.ImageCollection( "MODIS/006/MOD11A1" )
var lsib = ee.FeatureCollection( "USDOS/LSIB_SIMPLE/2017" )
var australia = lsib.filter(ee.Filter.eq( 'country_na' , 'Australia' ))
var geometry = australia.geometry()
var terra = modisLST
.filter(ee.Filter.date( '2001-01-01' , '2010-01-01' ))
.select( 'LST_Day_1km' , 'QC_Day' );
// Get a single image for testing
var image = ee.Image(terra.first())
var lstDay = image.select( 'LST_Day_1km' )
var qcDay = image.select( 'QC_Day' )
// Let's extract all pixels from the input image where
// Bits 0-1 <= 1 (LST produced of both good and other quality)
// Bits 2-3 = 0 (Good data quality)
// Bits 4-5 Ignore, any value is ok
// Bits 6-7 = 0 (Average LST error ≤ 1K)
var qaMask = bitwiseExtract(qcDay, 0, 1).lte(1)
var dataQualityMask = bitwiseExtract(qcDay, 2, 3).eq(0)
var lstErrorMask = bitwiseExtract(qcDay, 6, 7).eq(0)
var mask = qaMask.and(dataQualityMask).and(lstErrorMask)
var lstDayMasked = lstDay.updateMask(mask)
var visParams = {min:13000, max:16000, palette: ['green ', ' yellow ', ' red ']}
Map.addLayer(lstDay.clip(geometry), visParams, ' Original LST Image ');
Map.addLayer(lstDayMasked.clip(geometry), visParams, ' LST Masked');
|
原始图像与蒙面图像