使用geemap与eemont从Landsat-8影像中快速提取水体

首页 / 科技区 / 正文

最近自己在探索将 GEE 与 python 相结合进行地学分析的应用场景。不久前,我发现了一个强大的 gee-python 扩展库 eemont,在此简单记录下自己运用 geemapeemont 快速进行影像获取、光谱指数计算,数据下载与可视化的心得体会,整个流程高效而优雅。

一、环境配置与库安装

首先确保自己拥有一个有访问 GEE 权限的账户和流畅的网络环境,并且电脑上已安装了 gcloud 验证程序。在此基础上,新建一个 conda 环境,安装使用 gee 分析所对应的部分 python 库。

conda create -n ee python=3.9
conda activate ee
conda install -c conda-forge earthengine-api eemont geemap

安装完成后,进行 gee 账户的验证。这里需要注意,因为在国内需要使用代理访问谷歌服务,所以需要在验证时设置好代理的代理地址与端口,不然会报 Time out 的错误!

端口位置说明
Mac的代理地址与端口在“Settings—Network—Advanced—Proxies—Web Proxy(HTTP) ”下;Windows的代理地址与端口在“开始菜单—设置—网络和Internet—代理”下

然后就可以输入以下的代码进行验证了。其中会前往浏览器提示输入账号密码进行授权(只会出现一次),只要没报错就可以愉快使用啦。

import ee
import os

os.environ['HTTP_PROXY'] = 'http://127.0.0.1:4780'  # 自行调整端口!
os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:4780'

ee.Authenticate()  # 第一次使用时输入
ee.Initialize()

如果想要使用 geemap,可以直接:

import geemap
import ee

geemap.set_proxy(4780)
Map = geemap.Map()  # 其中会包含 ee.Initialize()
Map

在 jupyter 中将 python 与 GEE 进行结合有若干好处,包括可以直接调用本地的矢量数据,可以与numpy, pandas等其他 python 库进行协同,可以运用 jupyter 笔记本强大的分步运行功能,可以直接从 GEE 上下载数据而不用经过 Google Drive等。

二、Landsat8 影像获取

如果已有研究区域的矢量文件,可以调用 geemap 的 shp_to_ee(), geojson_to_ee() 等函数将本地文件直接加载进来。如果想交互式地绘制一个范围,可以运用 Map 界面中左下角的绘制工具,然后调用 geemap 的 Map.draw_last_feature 获取范围。

eemont 提供了若干强大的构造函数,以最简洁的方式完成了图像的去云、缩放(调整像元值)、校正、光谱指数计算等工作。例如,我要获取 2018 年下半年手动划定范围的校正后的 Landsat-8 影像集合(ImageCollection),并计算 AWEI, MNDWI 等光谱指数以提取水体,可以使用这样的语法:

L8 = (ee.ImageCollection("LANDSAT/LC08/C02/T1_L2")
      .filterBounds(Map.draw_last_feature.geometry()) # 交互式划定范围
      .maskClouds() # 去云,默认阈值为60
      .scaleAndOffset() # 根据影像的尺度和偏移参数缩放波段
      .filterDate("2018-06-01","2018-12-01")
      .spectralIndices(['MNDWI', 'AWEInsh'])) # 快速计算光谱指数

关于 Landsat8 数据的 Collection / Tier / Level 的 1 与 2 版本的辨析可以参照这篇博客。总的来说,Collection 2 与 Tie 1 的数据质量更高一些。

如果想在地图中加载指定时空范围内的卫星影像,可以按如下可视化参数加入:

vis_params = {
  "bands": ['SR_B4', 'SR_B3', 'SR_B2'],
  "min": 0.0,
  "max": 0.3,
}
Map.addLayer(L8, vis_params, "L8")

效果如下:

image-20220812140357878

三、光谱指数计算与下载

以 AWEI (Automated Water Extraction Index) 指数为例,可以采用如下的函数快速计算出这一水体指数,然后加载入地图中。

L8_AWEI = L8.spectralIndices(["AWEInsh"]).median()
awei_vis = {
    "min": 0,
    "max": 1,
    "palette": ['white', 'blue']
}
Map.addLayer(L8.select(["AWEInsh"]).median(), awei_vis, "L8_AWEI")

需要留意的是,这里 AWEI 指数的全名被写作为 AWEInsh。这个名称是来自于 Github 上的 awesome-spectral-indices 库,nsh 表示 no shadow elimination。如果需要计算任何的光谱指数,都可以直接访问这个仓库,里面列出了各卫星图像在各个应用领域的可用内容。

image-20220812141344375

如果仅需要下载一份镶嵌后的水体提取结果,则需要将获取到的图像集合(ImageCollection)合并为一张镶嵌的图像(Image),通常使用 median()mean() 等方法。下载的指令为:

geemap.download_ee_image_collection(ee.ImageCollection(L8.select(['MNDWI']).median()), 
                                    out_dir="./zj", 
                                    filenames="AWEI_2018_test.tif", 
                                    scale=30, 
                                    region=Map.draw_last_feature.geometry(), 
                                    crs="EPSG:3857")

这里我调用的是 geemap.download_ee_image_collection() 函数,将镶嵌的 Image 又转为了ImageCollection,而并没有使用 geemap.download_ee_image() 函数,原因是后者对下载到的图像的像元数有着更高的限制,如果划定的研究区域较大的话就很有可能会下载失败,而前者则能够支持下载。

四、简单的可视化

我下载了浙江部分地区的一些水体指数,在本地进行了简单的可视化。例如选取连续的白-蓝色带查看水与陆地的差别,也可以根据直方图手动或使用 otsu 等方法自动划定阈值,对图像进行二值化处理,并进行矢量化等操作。


image-20220812145133631
image-20220812145345931

五、总结

无意间发现的 eemont 这个库真的太高效了!我从来都没想过可以以如此简洁的方式进行遥感图像的下载与处理。geemap 库也着实给力,极大地扩展了在 jupyter notebook 中查看空间数据的可能性。这里仅简单记录下提取水体的一种简便方案,但 GEE 的强大与高效远不止于此,包括阈值提取、内陆水体分离等工作也完全可以在云端进行。在拥有了能够便捷获取海量的长时序遥感数据的条件之后,自己便需要继续思考如何对其进行挖掘,提炼特征,以分析地理科学问题了......

评论区
头像
    头像

    看的我热血沸腾啊www.jiwenlaw.com

    头像

    想想你的文章写的特别好https://www.237fa.com/

文章目录