作为一个个人学习项目,我尝试使用 Python 进行土地覆盖分类,并利用了 geemap、rasterio 和 scikit-learn 等强大的库。这篇博客是对这个小项目的演练——我采取的步骤、经验教训,以及 Python 如何打造灵活、本地化且可扩展的遥感工作流程。

以下是您可能选择(或结合)Python 而不是仅依赖 GEE JavaScript 代码编辑器来执行某些地理空间任务的一些原因:

  1. 机器学习和深度学习: Python 是这些领域无可争议的领导者。像 Scikit-learn(我们在这里使用)、Tensorflow、PyTorch、Keras 和 XGBoost 这样的库提供了丰富的算法、高级架构和微调功能,这些功能在 GEE JavaScript 环境中无法原生或轻松复制。如果您的分析涉及尖端的机器学习/深度学习,那么 Python 就是您的平台。
  2. 可视化:虽然 GEE 具有出色的交互式映射,但 matplotlib、seaborn、plotly 和 folium 等 Python 库为出版质量的静态图、交互式仪表板和多样化数据可视化提供了无与伦比的定制。
  3. 算法开发:如果您需要实现 GEE 中未预先构建的非常具体的、自定义的分类、过滤或特征提取算法,那么 Python 可以让您自由地从头开始编写代码或调整现有的开源实现。
  4. 内存和资源管理:对于非常具体的本地化任务或处理需要精确内存处理的数据时(尽管 GEE 处理大规模云内存),Python 可以对本地环境的资源提供更多控制。
  5. Python 是许多 GIS 软件(例如 ArcGIS、QGIS)的实际语言,如果您需要将 GEE 派生的输出或本地 Python 分析与传统 GIS 桌面应用程序相结合,则它具有高度的互操作性。
该项目的 Python 工具包:
  1. geemap:您的交互式地图桥梁。geemap 不仅常用于在 Jupyter 中可视化 GEE 资源,它还提供了强大的工具,用于本地地理空间数据可视化和交互式地图创建。对于这个项目至关重要的是,geemap 让我能够轻松访问和筛选 Earth Engine 的海量图像集合,绘制我感兴趣的区域 (AOI),然后高效地将数据直接提取到我的 Python 环境中进行本地处理,而无需先将大量图像文件下载到我的电脑上。GEE 云数据与本地 Python 的无缝集成是一个巨大的优势!
  2. rasterio:在本地高效读取、写入和操作常见的地理空间图像格式(如 GeoTIFF)。
  3. numpy:对于像素值进行高效的数组操作至关重要,这是栅格处理中的常见瓶颈。
  4. scikit-learn:机器学习强国——提供了大量的监督和无监督学习算法,您可以将其直接应用于图像特征。
  5. matplotlib:用于生成静态图和结果的详细可视化,提供对美学的细粒度控制。
  6. geopandas: Python 中处理矢量数据(点、线、多边形)的首选库。它提供了强大的空间操作工具,可以读取/写入 Shapefile、GeoJSON 等数据,这对于处理训练多边形或研究区域边界至关重要。
项目概述
  • 研究区域:加利福尼亚州中央谷地
  • 数据集: Sentinel-2 表面反射率 Level-2A [1]、ESA world cover 2020 [2](用于参考预先存在的土地覆盖图,用于收集地面真实训练样本)
  • 目标:使用训练多边形进行基本的监督土地覆盖分类,并分为建筑类、植被类和水类。
先决条件:

在本项目中,我使用了 Google Colab,它提供了一个便捷的云端 Jupyter Notebook 环境,预装了许多数据科学库,并支持 GPU 访问。您可以轻松使用 Google Colab(只需打开一个新的 Notebook 并粘贴代码即可)。如果您更喜欢本地设置,那么在您自己的机器上安装 Jupyter Notebook 环境也能完美运行。

您可以使用 pip 安装这些库。如果您使用的是 Jupyter 或 Colab 笔记本,则可以在命令前加上 ! :

!pip 安装 geemap、rasterio、geopandas、numpy、scikit-learn、matplotlib

土地覆盖分类工作流程:关键步骤和片段

现在,让我们逐步了解土地覆盖分类过程的核心步骤。由于完整脚本内容繁杂,本文不会直接展示完整代码。相反,我将展示关键代码片段来说明每个阶段,以及它们的输出和说明。完整的可运行脚本(包括所有导入代码)请参阅我的 GitHub 代码库(链接将在文章末尾提供)。

导入、验证和初始化 Earth Engine,并在 Geemap 上绘制 AOI

没有任何

数据采集和预处理

没有任何

没有任何

我使用了归一化差异植被指数 (NDVI):量化植被“绿度”或光合作用和归一化燃烧率 (NBR):虽然主要用于火灾,但 NBR 对植被中的水分含量(SWIR 被水高度吸收)和裸露土壤的敏感性使其非常适合将植被区域与裸露地面、岩石露头或最近扰动的土地区分开来。

训练分类器

全球 ESA 世界覆盖 2020 土地覆盖图提供了高分辨率(10 米)土地覆盖分类,可作为训练我的模型的可靠参考数据。为了在 Python 中训练监督土地覆盖分类模型,我首先使用 Google Earth Engine 从堆叠图像中抽取训练数据。我将这些标记点导出为 GeoJSON 文件,然后使用 GeoPandas 将其导入 Python。每个点包含各种光谱波段(例如 B2、B3、B4、B8、B11)的值以及 NDVI 和 NBR 等指数。这些特征被选为机器学习模型的输入 (x),而相应的土地覆盖标签 (y) 作为目标。我从 scikit-learn 库中训练了一个随机森林分类器,该分类器以其稳健性和处理非线性关系的能力而闻名。然后,使用 100 棵决策树,将该模型拟合到训练数据中——这是构建可靠的土地覆盖制图分类器的关键一步。

没有任何

关于地面真相的注释:时间不匹配(ESA World Cover 2020 vs. Sentinel-2 2022)

土地覆盖分类的一个关键考虑因素是卫星图像与地面真实数据之间的时间匹配。在本项目中,我使用 ESA WorldCover 2020 作为地面真实数据,对 2022 年的 Sentinel-2 图像进行分类。

必须认识到,土地覆被是动态的。在两年内(2020 年至 2022 年),由于城市扩张、森林砍伐、农业转型或自然事件的影响,一些地区可能会发生显著变化。这意味着 2020 年 WorldCover 地图中的某些像素可能不再准确代表 2022 年 Sentinel-2 图像中的土地覆被。这种时间上的不匹配可能会在训练数据中引入误差,从而可能导致分类错误。

尽管如此,对于这样的学习项目来说,使用像 ESA WorldCover 2020 这样高质量的现有产品至关重要。它提供了一个易于访问、全球一致且经过充分验证的数据集,当手动创建新的地面实况数据成本过高时,这无疑是一个切实可行的权衡。虽然理想的生产工作流程的目标是获取与影像同一时期的地面实况数据,但利用 WorldCover 使我们能够专注于核心分类方法,而无需进行大量的数据收集。意识到这一局限性有助于我们批判性地解读结果。

此外,还有更新版本的 ESA world cover — 2021 [3]。其他可用的数据源包括 ESRI 10m 年度土地利用/土地覆盖 [4]、Copernicus CORINE 土地覆盖 [5] 和 Dynamic World V1 [6]。

后续步骤Next steps

分类器训练完成后,我需要将其应用到整幅图像。为此,我首先将处理后的图像从 GEE 导出到 Google Drive,以便高效地将预处理的卫星图像从 GEE 云服务器直接传输到 Google Drive 中的指定文件夹。这样可以避免手动下载。导出后,我在 Google Colab 中安装了 Google Drive。drive.mount(' ') 允许您的笔记本访问您导出到 Google Drive 的文件,从而使它们可供您的本地 Python 脚本使用。使用 rasterio 库,我将多波段 GeoTIFF 图像读入 NumPy 数组。图像最初的形状为 (bands, height, width),我将其重塑为二维数组,其中每行代表一个像素,每列代表一个波段值——这种结构是模型预测所必需的。接下来,我使用训练有素的随机森林分类器 (clf) 来预测图像中每个像素的土地覆盖类别。预测的标签被重塑回原始图像尺寸以创建分类图。最后,我使用 rasterio 将分类后的土地覆盖图保存为新的 GeoTIFF 文件,并保留了原始图像的空间元数据。此输出可以在任何 GIS 软件中可视化,也可以在 Python 中进一步分析。

可视化

为了可视化最终的土地覆盖分类图,我使用了 Matplotlib(一个流行的 Python 绘图库)。分类数组包含每个像素的预测土地覆盖标签,并使用 plt.imshow() 显示。最终的分类图如下所示。

没有任何

我将分类结果导入 ArcGIS Pro,应用“众数滤波”去除孤立像素并增强地图清晰度,然后将其与 ESA WorldCover 地图进行比较。为了获得更清晰的视觉对比,我还对两个图层应用了相同的配色方案和符号系统。结果如下:图 1:ESA WorldCover 2020;图 2:Python 生成的随机森林分类地图 2022

没有任何

没有任何

当我用 Sentinel-2 影像和随机森林分类器对 ESA 2020 年世界植被覆盖地图和 2022 年分类地图进行视觉比较时,发现一些差异。其中一些差异可以归因于两年的时间间隔,在此期间,土地覆盖可能确实发生了变化(例如,城市扩张、季节变化或作物轮作)。然而,一些不匹配可能是由于分类错误造成的,尤其是在农业区和草原区等混合土地覆盖区,这些区域的光谱特征经常重叠。

准确性评估

我计算了总体准确率,并展示了一个混淆矩阵,该矩阵总结了所有类别中正确分类的实例数量和错误分类的实例数量。我将数据集分为训练集(70%)和验证集(30%),分层抽样确保两个子集的类别分布保持一致。

没有任何

土地覆盖分类的总体准确率为67.2%,Kappa系数为0.5265,表明预测类别与地面真实数据之间的一致性中等。虽然一些土地覆盖类型分类良好,但其他类型却表现出明显的混淆,导致总体准确率较低。

准确率低可归因于以下几个因素:

  1. 类别之间的光谱相似性——尤其是植被类型或城市和裸露土壤之间的相似性。
  2. 训练样本不足或不平衡。
  3. 混合像素或过渡区域,尤其是中央谷地等破碎的景观。
  4. 存在孤立的噪声像素——尽管我应用了多数滤波器,但由于分类算法或分辨率的限制,一些错误可能会持续存在。

为了优化分类并更好地匹配参考数据,改进措施可以包括使用其他特征,例如纹理指标、时间合成图,或合并其他数据集(例如高程或雷达)和光谱指数。与其使用单幅影像,不如创建多时相合成图(例如不同季节的中值影像或月度合成图)来提升效果。土地覆盖类型通常具有独特的季节性模式(物候)。将这些时间变化(例如,生长旺季与旱季数据)作为特征,可以显著提高区分灌溉作物与雨养作物、落叶林与常绿林等类别的能力。此外,扩展训练数据集并为每个类别包含更多样化的样本可以显著提升性能。我还建议使用从高分辨率影像或外部来源(例如 Google Earth)收集的参考点进行独立的精度评估,这通常比仅针对训练数据进行验证能够提供更客观的估计值。

结束语

这个项目是一次宝贵的学习经历,让我探索了 GEE 和 Python 在土地覆盖分类方面的强大功能。虽然整体准确率(约 67%)仍有提升空间,但它为理解端到端工作流程——从数据预处理和训练样本收集到分类和准确率评估——提供了一个很好的起点。将我的结果与 ESA World Cover 2020 地图进行比较,让我深入了解了错误分类,并突出了需要进一步改进的地方。展望未来,我计划更加专注于收集质量更高、更均衡的训练样本,测试不同的分类器,并添加额外的光谱和地形特征,以提高分类准确率。

关键学习
  • 良好的训练数据集的重要性——平衡、有代表性和空间多样性。
  • 与已建立的数据集(如 ESA World Cover)进行视觉比较有助于识别优势和劣势。
  • 独立的准确性评估为模型性能提供了更客观的评价。
  • GEE 非常适合快速原型设计和可视化,而 Python 则具有更强大的深度分析和可重复性功能。
  • 土地覆盖分类可以完全在云端进行,无需在本地下载任何数据——节省时间、存储空间,并实现可扩展的地理空间工作流程。

更多推荐