大多数光学卫星图像产品都带有一个或多个 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()
功能ee.Image()
和ee.Number()
。一旦创建了位掩码,就可以使用bitwiseAnd
() 函数将其应用于输入图像。下面是提取特定位的 GEE API 函数。
// 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)
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');
原始图像与mask图像
您还可以将此代码包装在一个函数中并map(
) 将其覆盖在一个集合上,以使用相同的条件屏蔽所有图像。这是显示如何使用附加注释执行此操作的完整脚本。
https://code.earthengine.google.co.in/e21636e7db4a3f757be2f51ed261719fhttps://code.earthengine.google.co.in/e21636e7db4a3f757be2f51ed261719f