第二章 探索图像
原作者:Jeff Howarth
概述
卫星图像是谷歌地球引擎强大功能的核心。这一章教你如何探索和可视化存储在图像波段中的数据。我们首先将单个波段可视化为单独的地图图层,然后探索一种在单个复合图层中可视化三个不同波段的方法。我们比较用于测量可见光和不可见光谱中电磁辐射的卫星波段的不同类型的合成。然后,我们探索图像更抽象的属性,并创建一个复合图层来可视化随时间的变化。
学习目标
• 使用代码编辑器加载图像。
• 使用代码选择图像波段并将其可视化为地图图层。
• 理解图像的真彩色和假彩色合成。
• 构建新的多波段图像。
• 理解加色法的工作原理以及如何解释RGB 合成。
假如你已经知道:
• 注册地球引擎账户,打开代码编辑器,并保存你的脚本(第一章)
2.1 实操
2.1.1 第一部分:加载并查看图像
首先,你将使用代码编辑器构造图像。在以下各节中,你将看到具有不同字体和阴影背景的代码。遇到代码时,将其粘贴到代码编辑器的中心面板中,然后单击“运行”(run)。首先,复制并粘贴以下内容:
var first_image = ee.Image( 'LANDSAT/LT05/C02/T1_L2/LT05_118038_20000606');
单击“运行”后,Earth Engine 将加载 Landsat 5 卫星于 2000 年 6 月 6 日捕获的图像。但你不会看到任何输出。
你可以通过多种方式浏览图像。首先,可以通过将图像打印到代码编辑器的“控制台”面板来检索元数据(有关图像的描述性数据):
print(first_image);
在控制台面板中,你可能需要点击展开箭头来显示信息。你应该能够看到这张图像由 19 个不同的波段组成。对于每个波段,元数据列出了四个属性,但目前让我们简单地注意到第一个属性是用引号括起来的波段名称或标签。例如,第一个波段的名称是“SR_B1”(图 2.1)。
像Landsat 5 号这样的卫星传感器测量电磁光谱不同部分的辐射强度。我们图像中的前六个波段(“SR_B1”到“SR_B7”)包含了对光谱六个不同部分的测量。前三个波段测量光谱的可见部分,即蓝色、绿色和红色光的量。另外三个波段测量人眼不可见的光谱的红外部分。
图像波段是栅格数据模型的一个例子,这是一种在二维像素网格或图像元素中存储地理数据的方法。在遥感中,每个像素存储的值通常称为数字编号(Digital Number)或 DN。根据传感器的不同,像素值或DN 可以表示一系列可能的数据值。
图2. 1控制台中的图像元数据
其中一些信息,比如波段的名称及其维度(宽像素数乘以高像素数),我们可以在元数据中看到。其他一些信息,比如每个波段所测量的光谱部分以及可能的数据值范围,可以通过地球引擎数据目录(将在接下来的两章中描述)或其他地球引擎方法找到。这些将在本书后面更详细地描述。
2.1.2 第二部分:可视化图像
现在,让我们将其中一个波段作为图层添加到地图中,以便我们可以看到它。
Map.addLayer(
first_image, // 要显示的数据
{
bands: ['SR_B1'], // 要显示的波段
min: 8000, // 显示范围
max: 17000
},
'Layer 1' // 命名
);
这里的代码使用了代码编辑器中地图的 `addLayer` 方法。上述命令有四个重要组成部分:
1. `first_image`:这是要在地图上显示的数据集。
2. `bands`:这些是要在地图上显示的数据集的特定波段。在我们的示例中,我们显示了一个名为“SR_B1”的单个波段。
3. `min`、`max`:它们分别代表要在屏幕上显示的“SR_B1”值的下限和上限。默认情况下,提供的最小值(8000)映射为黑色,提供的最大值(17000)映射为白色。介于最小值和最大值之间的值线性映射为黑白之间的灰度。低于 8000 的值绘制为黑色。高于 17000 的值绘制为白色。波段、最小值和最大值参数一起定义了可视化参数,即数据显示的指令。
4. `'Layer 1'`:这是要在图层管理器中显示的地图图层的标签。此标签出现在地图右上角的图层下拉菜单中。
当你运行代码时,除非你四处拖动查看,否则可能不会注意到显示的图像。尝试在图像上四处拖动,点击并拖动地图到中国上海方向。(你也可以在代码编辑器顶部的搜索(Search)面板中输入“Shanghai”跳转到那里,提示为“搜索地点和数据集……”)在上海上方,你应该看到一个小的、深色的、稍微倾斜的正方形。使用缩放工具(地图左上角的“+”号)来提高缩放级别,使正方形显得更大。
你能识别图像中的任何特征吗?通过与图像下方显示的标准谷歌地图(作为基础图层)进行比较,你应该能够区分出海岸线。靠近岸边的水通常看起来比陆地稍亮,除了图像底部陆地上可能有一个大的浅色斑点。
让我们用检查器(Inspector)工具来探索这张图像。当你点击代码编辑器右侧的检查器选项卡(图 2.2,区域 A)时,你的光标现在应该看起来像十字准线。当你在图像中的某个位置点击时,检查器面板将在以下三个类别下报告该位置的数据:
图2. 2通过“检查器”面板报告的图像数据
•点(Point):关于地图上位置的数据。这包括地理位置(经度和纬度)以及一些关于地图显示的数据(缩放级别和比例尺)。
• 像素(Pixels):关于图层中像素的数据。如果你展开这个,你会看到地图图层的名称、数据源的描述和一个柱状图。在我们的例子中,我们看到“Layer 1”是从一个包含 19 个波段的图像数据集中绘制的。在图层名称下,图表显示了你点击位置的每个波段在数据集中的像素值。当你将光标悬停在一个柱上时,会弹出一个面板来显示波段名称和“波段值”(像素值)。要找到“SR_B1”的像素值,将光标悬停在左边的第一个柱上。或者,通过点击“Layer 1”右侧的小蓝色图标(图 2.2,区域 B),你将把显示从柱状图更改为一个字典,报告每个波段的像素值。
• 对象(Objects):关于源数据集的数据。在这里,你会找到关于图像的元数据,它看起来与你之前指示地球引擎将图像打印到控制台时检索到的非常相似。
让我们再添加两个波段到图层上。
Map.addLayer(
first_image,
{
bands: ['SR_B2'],
min: 8000,
max: 17000
},
'Layer 2',
0, // 显示
1 // 不显示
);
Map.addLayer(
first_image,
{
bands: ['SR_B3'],
min: 8000,
max: 17000
},
'Layer 3',
1, // 显示
0 // 不显示
);
在上述代码中,请注意我们在 `Map.addLayer` 调用中包含了两个额外的参数。一个参数控制在绘制图层时该图层是否在屏幕上显示。它可以是 1(显示)或 0(不显示)。另一个参数定义了图层的不透明度或你“看穿”地图图层的能力。不透明度值可以在 0(透明)和 1(不透明)之间变化。
你是否看到这些新参数如何影响地图图层的显示(图 2.3)?对于图层 2,我们将显示参数设置为 0。对于图层 3,我们将不透明度参数设置为 0。因此,当我们首次运行代码时,这两个图层对我们都是不可见的。我们可以使用地图右上角的图层管理器复选框中的控件使每个图层可见(在地图的右上角)。展开此列表,你应该看到我们将每个图层添加到地图时赋予它们的名称。每个名称位于一个复选框和一个不透明度滑块之间。要使图层 2 可见,请单击复选框(图 2.3,区域 A)。要使图层 3 可见,请将不透明度滑块向右移动(图 2.3,区域 B)
图2. 3Landsat 影像中的三个波段,绘制为三个不同的灰度图层
通过操作这些控件,你应该注意到这些图层是以堆叠的方式显示的,即一个在另一个之上。例如,将每个图层的不透明度通过将不透明度滑块一直推到右侧设置为 1。然后,确保每个图层旁边的每个框都被选中,以便显示所有图层。现在,你可以通过选中和取消选中每个图层来确定哪个图层在堆叠的顶部。如果一个图层在另一个图层之上,取消选中顶部图层将显示下面的图层。如果一个图层在堆叠中的另一个图层之下,那么取消选中底部图层不会改变显示(因为顶部图层仍将可见)。如果你在我们的堆叠上尝试此操作,你应该看到列表顺序反映了堆叠顺序,这意味着图层列表顶部的图层出现在堆叠的顶部。现在,将列表中的图层顺序与脚本中的操作顺序进行比较。你的脚本首先添加的是哪个图层,它在地图上的分层顺序中出现在哪里?
代码检查点 F11a
本书的代码库包含一个脚本,展示了此时你的代码应该是什么样子。
2.1.3 第三部分 真彩色合成
使用图层管理器中的控件,探索这些图层并检查每个波段中的像素值如何不同。图层 2(显示来自“SR_B2”波段的像素值)看起来通常比图层 1(“SR_B1”波段)更亮吗?与图层 2 相比,图层 3(“SR_B3”波段)中的海水在北部看起来是否稍暗,但在南部看起来稍亮?
我们可以使用颜色将每个波段图层的像素值中的这些视觉差异一次性作为 RGB 合成进行比较。这种方法使用三原色(红、绿、蓝)来显示三个波段中每个像素的值。要尝试这个,请添加以下代码并运行它:
Map.addLayer(
first_image,
{
bands: ['SR_B3', 'SR_B2', 'SR_B1'],
min: 8000,
max: 17000
},
'Natural Color');
其结果(图 2.4)看起来就像我们所看到的世界,被称为自然彩色合成,因为它自然地将图像波段的光谱范围配对以显示颜色。也称为真彩色合成,这张图像用红色阴影显示红色光谱波段,用绿色阴影显示绿色波段,用蓝色阴影显示蓝色波段。我们通过列表中波段的顺序简单地指定了这种配对:B3、B2、B1。因为陆地卫星 5 号的波段 3、2 和 1 分别对应于现实世界中的红、绿、蓝颜色,所以这张图像类似于我们在飞机窗外或低空飞行的无人机上看到的世界。
图2. 4 真彩色合成
2.1.4 第四部分 假彩色(伪彩色)合成
正如你在打印波段列表时所看到的(图2.1),陆地卫星图像包含的波段远不止三个真彩色波段。我们可以制作 RGB 合成来显示任何波段的组合——甚至是那些在人眼可见范围之外的波段。例如,波段 4 代表近红外波段,就在人类视觉范围之外。由于其在区分环境条件方面的价值,这个波段甚至在20 世纪 70 年代最早的陆地卫星上就已包含。例如,它在针叶林和落叶林中具有不同的值,并且可以指示作物的健康状况。要查看此示例,请将以下代码添加到你的脚本中并运行它:
Map.addLayer(
first_image,
{
bands: ['SR_B4', 'SR_B3', 'SR_B2'],
min: 8000,
max: 17000
},
'False Color'
);
在这个假彩色合成图(图 2.5)中,显示的颜色不再与波段自然配对。这个特殊的例子,更准确地称为彩色红外合成,是一个我们用眼睛无法观察到的场景,但你可以学习阅读和解释。通过思考传递给红色、绿色和蓝色通道的内容,可以从逻辑上解读其含义。
图2. 5 彩色红外图像伪彩色合成
请注意北部半岛的陆地如何呈现出鲜红色(图 2.5,区域 A)。这是因为对于该区域,第一个波段(绘制近红外亮度)的像素值相对于其他两个波段的像素值要高得多。你可以使用检查器工具进行检查。尝试放大图像中带有红色斑块的部分(图 2.5,区域 B),然后点击看起来是红色的像素。然后,在检查器面板中展开“假彩色”图层(图 2.6,区域 A),点击图层名称旁边的蓝色图标(图 2.6,区域 B),并读取合成的三个波段的像素值(图 2.6,区域 C)。B4 的像素值应该远大于 B3 或 B2。
在图像的左下角(图 2.5,区域 C),河流和湖泊显得非常暗,这意味着三个波段的像素值都很低。然而,从河流向大海扇形分布的泥沙羽流呈现出蓝色和青色色调(图 2.5,区域 D)。如果它们看起来像原色蓝色,那么第二个波段(B3)的像素值可能高于第一个(B4)和第三个(B2)波段。如果它们看起来更像青色,一种加色,这意味着第二个和第三个波段的像素值都大于第一个波段。
图2. 6显示为亮红色的像素的 B4、B3、B2 波段值
总的来说,与真彩色图像相比,假彩色合成在理解场景中的差异方面提供了更多的对比度。这表明其他波段可能也包含更多有用的信息。我们之前看到我们的卫星图像由 19 个波段组成。其中六个代表电磁光谱的不同部分,包括三个超出可见光谱的部分,可用于制作不同的假彩色合成图像。使用下面的代码来探索一个显示短波红外、近红外和可见绿光的合成图像(图 2.7)
Map.addLayer(
first_image,
{
bands: ['SR_B5', 'SR_B4', 'SR_B2'],
min: 8000,
max: 17000
},
'Short wave false color'
);
图2. 7短波红外假彩色合成
为了比较这两个伪彩色合成图像,放大图2.8 中两张图片所示的区域。你应该注意到,左边合成图像中的亮红色位置在右边的合成图像中呈现为亮绿色。你认为这是为什么呢?右边的图像是否显示了左边图像中未看到的新区别?如果是,你认为它们是什么?
图2. 8近红外与短波红外假彩色合成图层的对比
代码检查点 F11b
本书的代码库包含一个脚本,展示了此时你的代码应该是什么样子。
2.1.5 第五部分 加色系统
现在,我们已经使用 RGB 合成来制作真彩色图像,其中屏幕上的颜色与我们日常生活中的颜色相匹配。我们还使用相同的原理绘制了卫星收集的两个光学波段的伪彩色组合。为了能够普遍地从合成图像中读取和解释信息,理解加色系统是很有必要。地球引擎中的数据视图,实际上是计算机屏幕上绘制的所有内容,都使用三个通道进行显示(红色、绿色和蓝色)。合成图层中波段的顺序决定了用于显示像素 DN 的颜色通道。当一个波段的 DN 相对于其他两个波段较高时,像素将显示为用于显示该波段的颜色通道的色调。例如,当第一个波段相对于其他两个波段较高时,像素将呈现红色。像素颜色的强度将表示 DN 量之间差异的大小。
在加色系统中,原色组合形成新颜色的方式起初可能会令人困惑,特别是如果你是通过绘画或印刷学习如何混合颜色的。在使用加色系统时,红色与绿色组合形成黄色,绿色与蓝色组合形成青色,红色与蓝色组合形成品红色(图 2.9)。将所有三种原色组合在一起形成白色。所有原色都不存在则形成黑色。对于 RGB 合成,这意味着如果两个波段的像素值大于第三个波段,则像素颜色将呈现为混合颜色的色调。例如,当合成的第一和第二个波段的像素值高于第三个波段时,像素将呈现黄色。
图2. 9 加色系统
2.1.6 第六部分 位置的属性
到目前为止,我们已经探索了波段作为存储卫星可测量的电磁光谱切片数据的一种方法。现在,我们将致力于将加色系统应用于存储地理位置的非光学和更抽象属性的波段。
首先,将此代码添加到你的脚本中并运行它。
var lights93 = ee.Image('NOAA/DMSP-OLS/NIGHTTIME_LIGHTS/F101993');
print('Nighttime lights', lights93);
Map.addLayer(
lights93,
{
bands: ['stable_lights'],
min: 0,
max: 63
},
'Lights'
);
此代码加载了一张全球夜间灯光的图像,并向地图添加了一个新图层。请查看我们打印到控制台面板的元数据。你应该看到该图像由四个波段组成。代码选择“stable_lights”波段作为地图的图层进行显示。显示的值范围(0 - 63)表示此图像中的最小和最大像素值。如前所述,你可以在地球引擎数据目录或通过其他地球引擎方法找到此范围。这些将在接下来的几章中更详细地描述。
全球夜间灯光图像表示一个日历年中每个像素的夜间灯光平均亮度。对于我们这些在夜间乘坐飞机下降到目的地时坐在窗边的人来说,这个场景可能看起来有点熟悉。但是,该图像在很大程度上是一种抽象。它为我们提供了一个从飞机上甚至从太空中都无法看到的地球视图。夜晚使整个星球笼罩在黑暗中。没有云彩。
图2. 10 1993年的夜间stable lights
在“stable lights”波段中,不存在短暂的光源。闪电、野火和其他瞬时光源已被去除。这是一个图层,旨在回答关于我们星球在某一时刻的一个问题:在 1993 年,地球上稳定的人造光源有多亮?
通过地图上的缩放控件,你可以缩小以看到上海的亮点、东北部首尔的大片光亮、除了平壤的小点之外朝鲜的黑暗,以及日本和台湾西海岸密集的光带(图 2.10)
2.1.7 第七部分 抽象的 RGB 合成
现在,我们可以使用加色系统制作一个 RGB 合成,比较三个不同时间片段的稳定夜间灯光。将以下代码添加到你的脚本中并运行它
var lights03 = ee.Image('NOAA/DMSP-OLS/NIGHTTIME_LIGHTS/F152003')
.select('stable_lights').rename('2003');
var lights13 = ee.Image('NOAA/DMSP-OLS/NIGHTTIME_LIGHTS/F182013')
.select('stable_lights').rename('2013');
var changeImage = lights13.addBands(lights03)
.addBands(lights93.select('stable_lights').rename('1993'));
print('change image', changeImage);
Map.addLayer(
changeImage,
{
min: 0,
max: 63
},
'Change composite'
);
这段代码做了几件事。首先,它创建了两个新的图像,每个都代表不同的时间片段。对于这两个图像,我们使用 select 方法选择一个波段(“stable_lights”),并使用 rename 方法更改波段名称以指示其代表的年份。
接下来,代码使用 addBands 方法创建一个新的三波段图像,我们将其命名为“changeImage”。它通过将一个图像(lights13)作为第一个波段,使用另一个图像(lights03)作为第二个波段,以及之前看到的 lights93 图像作为第三个波段来实现。当第三个波段放入图像时,它被命名为“1993”。
最后,代码将元数据打印到控制台,并使用 Map.addLayer 将图层作为 RGB 合成添加到地图中。如果你查看打印的元数据,应该在“change image”标签下看到我们的图像由三个波段组成,每个波段都以一个年份命名。你还应该注意到图像中波段的顺序:2013、2003、1993。这个顺序决定了用于在合成中表示每个时间片段的颜色通道:2013 为红色,2003 为绿色,1993 为蓝色(图 2.11)。
现在,我们可以读取图层上显示的颜色来解释过去二十多年来全球夜间灯光的不同变化。显示为白色的像素在这三年中亮度都很高。你可以使用检查器面板来确认这一点。单击检查器面板将光标更改为十字准线,然后单击显示为白色的像素。在检查器面板的“Change composite”图层的“像素”(Pixel)类别下查看。每个波段的像素值应该很高(在 63 或接近 63)
图2. 11稳定的夜间灯光的RGB合成(2013年,2003年,1993年)
许多白色像素团代表城市核心。如果你放大到上海,你会注意到白色核心的周边呈现黄色,终端边缘呈现红色。黄色代表在 2013 年和 2003 年明亮但在 1993 年黑暗的位置。红色代表在 2013 年明亮但在 2003 年和 1993 年黑暗的位置。如果你缩小,你会看到这种从白色核心到黄色周边再到红色边缘的梯度在全球许多城市周围都有出现,展示了 20 年来城市扩张的全球模式。
当你从上海缩小视图时,你可能会注意到每次更改缩放级别时,每个地图图层都会重新绘制。为了更有效地探索变化合成图层,使用图层管理器面板不显示(取消选中)除“Change composite”之外的所有图层。现在,当你缩放和平移时,地图的响应速度会更快,因为它只会刷新单个显示的可见图层。
除了城市变化,该图层还显示了产生明亮灯光的资源开采活动的变化。通常,这些活动产生的灯光在一年的时间内是稳定的(因此包含在“稳定灯光”波段中),但在十年或更长时间内不可持续。例如,在朝鲜海峡(韩国和日本之间),你可以看到使用明亮卤素灯将鱿鱼和其他海洋生物吸引到水面并进入渔网的渔船队的地理变化。蓝色像素可能在1993 年捕捞活动更频繁,到2003 年使用频率降低,而绿色像素可能在2003 年捕捞活动更频繁,到2013 年使用频率降低(图2.11)。
图2. 12北达科他州和德克萨斯州在特定年份因化石燃料开采而出现的大红色斑点
同样,化石燃料开采通过天然气燃烧产生夜间灯光。如果你平移到北美(图 2.12),艾伯塔省和北达科他州的红色斑点以及德克萨斯州东南部的红色地带都代表了在 1993年和 2003 年不存在但在 2013 年蓬勃发展的石油和天然气开采地点。平移到波斯湾,你会看到类似于节日灯光的变化,白色、红色、绿色和蓝色的点相互靠近;这些区分了石油生产的稳定和变化位置。在伊拉克边境附近的叙利亚的蓝色灯光表示 1993 年后油田的废弃(图 2.13)。再向北平移,你会看到俄罗斯苏尔古特周围石油和天然气开采的另一个“节日灯光”展示。在许多这些地方,你可以通过放大到一个彩色点,使灯光图层不可见,并选择卫星基础图层(右上角)来检查石油和天然气基础设施。
图2. 13中东的夜间光线变化
在探索此图像时,请记住通过单击像素并读取每个波段的像素值,使用检查器面板检查你的解释。回顾加色图以记住颜色系统的工作原理。如果你进行此练习,你应该能够通过了解颜色与每个波段的相对像素值的关系来读取任何 RGB 合成。这将使你能够使用伪彩色合成作为一种灵活而强大的方法来探索和解释地球表面的地理模式和变化。
代码检查点 F11c
本书的代码库包含一个脚本,展示了此时您的代码应该是什么样子。
2 综合练习
任务 1. 比较和对比叙利亚大马士革和约旦安曼(Damascus, Syria versus Amman, Jordan)夜间灯光的变化。这两个城市的颜色有哪些相似之处和不同之处?您如何解释这些差异?
任务 2. 查看尼日利亚哈科特港(Port Har court, Nigeria)夜间灯光的变化。您认为这些颜色意味着什么样的变化?您在卫星底图中能看到哪些线索来证实您的说法?
任务3. 夜间灯光变化合成中,我们没有指定用于 RGB 合成的三个波段。您认为地球引擎是如何选择要显示的三个波段的?您认为地球引擎是如何确定哪个波段应该用红色、绿色和蓝色通道显示的?
任务4.为这幅图像创建一个新脚本,制作三个合成图(自然色、近红外伪彩色和短波红外伪彩色合成图):
'LANDSAT/LT05/C02/T1_L2/LT05_022039_20050907'
您认为这些图像展示了什么环境事件?比较和对比自然色合成图和伪彩色合成图。伪彩色合成图帮助您看到了哪些在自然色合成图中更难解读的内容?
任务5. 创建一个新脚本并运行以下代码来查看上海的这幅图像:
var image =
ee.Image('LANDSAT/LT05/C02/T1_L2/LT05_118038_20000606');
Map.addLayer(
image,
{
bands: ['SR_B1'],
min: 8000,
max: 17000
},
'Layer 1'
);
Map.addLayer(
image.select('SR_B1'),
{
min: 8000,
max: 17000
},
'Layer 2'
);
使用检查器面板检查 Layer 1 和 Layer 2。描述这两个图层的不同之处,并解释它们不同的原因
3.总结
在本章中,我们研究了一幅图像是如何由一个或多个波段组成的,其中每个波段都以像素值的形式存储有关地理位置的数据。我们探索了将这些像素值可视化为地图图层的不同方式,包括单个波段的灰度显示和三个波段的 RGB 合成。我们创建了自然色和伪彩色合成图,它们使用加色法来显示光谱中可见和不可见部分的信息。我们将加色法作为一种通用系统来研究如何跨多个波段可视化像素值。然后,我们探讨了如何使用波段和 RGB 合成来表示更抽象的现象,包括随时间变化的不同类型。