目录
2.2.3 影像融合与Pansharpening:融合空间与光谱信息
4.1.3 面向不平衡数据的指标:Kappa系数、马修斯相关系数
4.1.4 面向概率预测的指标:ROC曲线、AUC、PR曲线
5.1 使用Matplotlib和GeoPandas进行静态可视化
第一章:引言:基线——所有科学进步的基石
在科学和工程的任何一个领域,进步都不是凭空产生的。它建立在一个坚实的、可验证的基础之上。这个基础,就是我们所说的基线。在遥感AI这个日新月异的领域,尤其是在我们即将深入探讨大模型这一前沿技术之前,花时间来理解、构建并精通一个基于“传统”方法的基线系统,是至关重要的。本章将作为连接我们已掌握的“工具”与即将学习的“模型”之间的桥梁,确保我们的每一步前行都有据可依。
1.1 什么是基线?为什么它至关重要?
基线,在最简单的定义中,是一个用作比较标准的简单模型或系统。它是在没有使用任何高级、复杂技术的情况下,能够达到的最低性能水平。在药物试验中,新药的疗效必须与安慰剂(一种零阶基线)进行比较;在计算机视觉中,一个新的图像识别算法必须与手工设计的特征加上传统分类器(一种二阶基线)进行比较。
在遥感AI项目中,建立一个强大的基线模型至关重要,原因如下:
- 量化改进: 基线提供了一个客观的度量衡。当我们花费巨大努力训练了一个复杂的深度学习或大模型后,我们如何知道它真的“更好”?只有通过与基线模型在相同的测试集上进行性能比较,我们才能量化地说:“我们的新模型将总体精度从85%提升到了92%。”没有基线,任何关于“性能提升”的说法都只是主观臆断,缺乏科学依据。
- 防止“幻觉”: 大模型技术充满了令人兴奋的“魔力”,很容易让人陷入一种技术崇拜,认为模型越复杂,效果就一定越好。一个扎实的基线是防止这种“技术幻觉”的清醒剂。如果一个耗资百万、训练数周的巨型模型,其性能仅仅比一个用几十行代码、几分钟就能训练好的随机森林模型高出1%,那么我们就必须反思,这种微小的提升是否值得其巨大的成本和复杂性。
- 提供问题诊断的起点: 当一个复杂的模型表现不佳时,我们很难判断问题出在哪里:是模型架构的问题?是训练数据的问题?还是超参数设置的问题?而一个简单的基线模型通常更容易调试和理解。如果连基线模型都无法在数据上学到任何有意义的模式,那么问题很可能出在数据本身,而不是模型。
- 快速迭代的工具: 在项目初期,一个简单的基线模型可以快速搭建和部署,为业务提供一个“可用”的初步解决方案。与此同时,研发团队可以并行开发更复杂的模型。这种策略使得业务不会等待技术,而技术可以基于一个已经运行的系统进行迭代。
1.2 遥感AI中的基线模型谱系:从零阶到三阶
基线并非单一的概念,它存在一个谱系,我们可以根据其复杂度和性能将其分为几个层次:
- 零阶基线: 这是最简单的基线,通常基于一些简单的统计规则或随机猜测。例如,对于一个土地覆盖分类任务,一个零阶基线可以是“将所有像素都预测为最常见的类别”。这个基线的性能通常很低,但它提供了一个绝对的性能下限。
- 一阶基线: 这类基线基于一些专家知识和简单的规则。例如,在农业监测中,一个一阶基线可以是:“如果NDVI > 0.6,则该区域为‘健康作物’;否则为‘不健康作物’”。这类基线通常比零阶基线要好,并且具有很好的可解释性,但其规则是固定的,缺乏适应性。
- 二阶基线: 这是我们本章将要重点构建的基线。它使用经典的机器学习模型(如随机森林、支持向量机、梯度提升树)结合人工设计的特征(如NDVI、纹理等)来进行预测。这类基线在过去二十年中是遥感应用的主流,性能强大,并且通常具有很好的可解释性。
- 三阶基线: 这指的是使用深度学习模型(如CNN、U-Net)的基线。这些模型能够自动从原始数据中学习特征,避免了繁琐的人工特征工程。通常,一个三阶基线的性能会优于二阶基线,但它的训练成本更高,且可解释性较差。而我们最终要构建的“遥感大模型”,则可以看作是三阶基线的进一步扩展,它通过在海量无标签数据上进行预训练,获得了更强的泛化能力和少样本学习能力。
本系列的目标,最终是构建一个超越所有传统基线的“生产级大模型”。但为了做到这一点,我们必须首先在二阶基线上打下坚实的基础。
1.3 本章与全系列的衔接:从“已知”到“未知”
本章是整个系列承上启下的关键。它将充分利用我们在前三章中搭建的一切:
- 基础设施(文章2): 我们将在Docker容器中运行所有的Python代码,确保环境的一致性。
- 数据湖(文章3): 我们将从我们自己构建的Silver层数据湖中读取预处理好的、标准化的数据。
- 工具链: 我们将使用
rasterio,geopandas,scikit-learn等成熟的Python库来完成所有工作。
我们将把这些“已知”的、可靠的工具和流程,组合成一个完整的、端到端的、可运行的“智慧农业作物分类”系统。通过这个实战项目,你将亲身体会到,即使不使用任何深度学习技术,我们也能构建出一个性能相当不错的生产级应用。
更重要的是,本章的结尾将是对这个“已知”系统的深刻反思。我们将系统地分析其优点和局限性,特别是它在特征工程、泛化能力和数据依赖上的瓶颈。这些局限性,正是催生后续章节将要介绍的自监督预训练、多模态融合、时空建模等大模型技术的根本原因。因此,本章不仅是一个终点(一个完整的基线系统),更是一个起点(通往大模型之路的起点)。
1.4 实战项目概述:为智慧农业构建一个作物分类基线
为了将理论与实践紧密结合,本章将围绕一个具体的生产级项目展开:为智慧农业构建一个作物分类基线模型。
项目目标: 给定一个区域的Sentinel-2影像和对应的土地覆盖真实标签,训练一个机器学习模型,能够将影像中的每个像素分类为不同的作物类型(如玉米、大豆、棉花等)或非作物类别(如水体、建筑、裸地)。
技术路线:
- 数据源: 从我们的数据湖的Silver层读取已经过预处理(大气校正、坐标系统统一)的Sentinel-2影像。
- 特征提取: 编写一个Python脚本,对影像进行像素级的特征提取,包括:
- 光谱特征: 计算多个波段(如红、绿、近红外、短波红外)的反射率值。
- 光谱指数: 计算NDVI、EVI、NDWI、NDBI等多种指数。
- 纹理特征: 基于灰度共生矩阵(GLCM)计算对比度、相关性、熵等纹理特征。
- 模型训练: 使用
scikit-learn库训练一个随机森林分类器。选择随机森林是因为它在表格型数据上通常表现优异,训练速度快,并且能提供特征重要性,便于模型解释。 - 模型评估: 使用独立的测试集评估模型性能,计算总体精度、Kappa系数,并绘制混淆矩阵。
- 结果可视化: 将分类结果渲染成一张彩色的土地覆盖地图。
通过这个项目,你将完整地走完一个传统遥感AI项目的全过程,并对其中每个环节的挑战和解决方案有深刻的理解。
第二章:传统遥感分析工作流:从像素到特征
传统遥感分析工作流是一个结构化的过程,它将原始的、充满噪声的卫星数据,转化为有意义的、可供分析的信息。这个过程的核心是特征工程,它被誉为遥感应用的“艺术”,因为它需要深厚的领域知识来设计和选择能够最好地描述地物特征的计算指标。本章将详细拆解这个工作流,并为我们的基线项目准备数据。
2.1 工作流概览:一个经典案例
一个典型的遥感应用(如土地覆盖分类)的经典工作流可以概括为以下步骤:
- 数据获取: 获取原始的卫星影像(Level-1或Level-2级)。
- 数据预处理: 对原始影像进行一系列校正,以消除传感器、大气和地形带来的误差。
- 特征提取: 从预处理后的影像中,通过计算,提取出能够区分不同地物的特征。
- 模型训练与分类: 使用提取的特征和对应的标签,训练一个分类器,并用它对整幅影像进行分类。
- 后处理与精度评估: 对分类结果进行平滑、过滤等后处理,并使用地面真实数据评估分类精度。
2.2 数据预处理:为分析“铺平道路”
原始的卫星影像(Level-1级)记录的是传感器接收到的辐射亮度值,这些值受到大气散射、太阳高度角、传感器响应等多种因素的影响,并不能直接反映地物的真实物理属性。因此,在进行任何有意义的分析之前,必须进行严格的预处理。
2.2.1 辐射定标与大气校正:从DN到地表反射率
- 辐射定标:将影像的原始数字值转换为具有物理单位的大气顶层辐射亮度。
- 大气校正:消除大气散射和吸收对辐射亮度的影响,将其转换为地表反射率。地表反射率是一个无量纲的值(0-1),它表示地表反射的太阳辐射能量与到达地表的太阳总辐射能量的比值。
为什么它至关重要?
只有转换为地表反射率,不同时间、不同传感器获取的影像才具有可比性。例如,同一片森林,在夏季和冬季的太阳高度角不同,其原始DN值会差异巨大,但其地表反射率是相对稳定的。没有大气校正,我们无法进行可靠的时序分析或多源数据融合。
实战代码示例:
虽然我们的数据湖中的数据可能已经过大气校正,但理解其原理和实现方式至关重要。py6S是一个可以模拟大气校正过程的Python库。然而,在实际生产中,我们通常使用已经过校正的数据(如Sentinel-2 L2A级产品)。
import rasterio
import numpy as np
import matplotlib.pyplot as plt
# 假设我们有一个L1级影像和一个L2级影像
# 这里我们只是模拟读取一个L2级影像来展示
# 在我们的项目中,数据湖中的数据已经是L2级
# 读取一个波段
with rasterio.open('path/to/sentinel2_l2a_band.tif') as src:
red_band = src.read(4) # 读取红光波段
profile = src.profile
# 显示影像
plt.figure(figsize=(10, 8))
plt.imshow(red_band, cmap='gray')
plt.title("Red Band (Surface Reflectance)")
plt.colorbar(label="Reflectance")
plt.show()
print(f"Data type: {red_band.dtype}")
print(f"Reflectance range: {np.min(red_band)} to {np.max(red_band)}")
这段代码展示了如何读取一个已经过大气校正的波段,并可视化其反射率值。我们可以看到,其值通常在0到0.5之间,这是地表反射率的典型范围。
2.2.2 几何校正与正射校正:消除几何畸变
- 几何校正:消除由于地球曲率、地形起伏和传感器扫描方式等引起的几何畸变,使得影像上的像元具有正确的地理坐标。
- 正射校正:几何校正的一种高级形式,它将影像投影到一个地图投影坐标系(如UTM),生成一幅具有地图精度的正射影像。
为什么它至关重要?
没有经过正射校正的影像,就像一张通过哈哈镜看到的地图,存在扭曲、变形和比例失调。在这样的影像上,我们无法进行准确的距离、面积量算,也无法与其他地理数据(如矢量边界)精确叠加。
在我们的项目中,我们数据湖中的所有影像都已经被精确地配准到WGS84地理坐标系,这为我们后续的分析提供了坚实的基础。
2.2.3 影像融合与Pansharpening:融合空间与光谱信息
许多卫星(如Landsat 8, Sentinel-2)同时提供两种数据:
- **多光谱影像:**具有多个光谱波段,但空间分辨率较低(如10m, 30m)。
- **全色影像:**只有一个很宽的光谱波段,但空间分辨率很高(如15m, 15m)。
**Pansharpening(全色锐化)**是一种技术,它将高分辨率的全色影像的空间细节与多光谱影像的光谱信息融合起来,生成一幅既具有高空间分辨率又具有多光谱信息的影像。
为什么它至关重要?
Pansharpened影像能够让我们看到更精细的地物细节(如田埂、小型道路),同时保留了进行地物识别所需的光谱信息,这对于精细化的农业监测至关重要。
在我们的项目中,我们可以选择使用原始的10m分辨率数据,或者使用Pansharpened后的更高分辨率数据(如果可用),这取决于我们的具体需求。
2.3 特征工程:遥感分析的“艺术”
特征工程是传统遥感工作流的核心和灵魂。它的目标是设计出一组能够有效区分不同地物类别的计算指标。这些特征是基于像素的DN值(或反射率值)及其邻域关系计算出来的。
2.3.1 光谱特征:植被指数、水体指数与土壤指数
光谱特征利用不同地物在不同波长下的反射率差异来区分它们。其中,植被指数是最著名和最广泛应用的一类。
- 归一化植被指数:
NDVI是监测植物生长状态和植被覆盖度的最佳指标。它利用了植被在近红外波段(NIR)有高反射,而在红光波段有低反射的特性。
公式:NDVI = (NIR - Red) / (NIR + Red)
值域: [-1, 1]。对于植被,NDVI值通常在0.2到0.8之间。 - 增强型植被指数:
EVI是对NDVI的改进,它通过引入蓝色波段来校正大气和土壤背景的影响,对高植被密度区域更敏感。
公式:EVI = G * ((NIR - Red) / (NIR + C1 * Red - C2 * Blue + L))(G, C1, C2, L为经验系数)
值域: [-1, 1]。 - 归一化差异水体指数:
NDWI利用水体在近红外波段吸收和绿光波段反射的特性来识别水体。
公式:NDWI = (Green - NIR) / (Green + NIR)
值域: [-1, 1]。对于水体,NDWI值通常大于0。 - 归一化差异建筑指数:
NDBI利用建筑在短波红外波段有高反射的特性来识别人工建筑。
公式:NDBI = (SWIR - NIR) / (SWIR + NIR)
值域: [-1, 1]。
实战代码示例:
让我们编写一个函数来计算这些指数。
def calculate_indices(image_array):
"""
计算多种光谱指数。
:param image_array: 一个numpy数组,形状为。
:return: 一个包含多个指数的字典。
"""
# 假设波段顺序为 Blue, Green, Red, NIR, SWIR1, SWIR2
blue = image_array[1].astype(float)
green = image_array[2].astype(float)
red = image_array[3].astype(float)
nir = image_array[4].astype(float)
swir1 = image_array[5].astype(float)
swir2 = image_array[6].astype(float)
# 添加一个小常数以避免分母为零
epsilon = 1e-8
ndvi = (nir - red) / (nir + red + epsilon)
evi = 2.5 * (nir - red) / (nir + 6 * red - 7.5 * blue + 1)
ndwi = (green - nir) / (green + nir + epsilon)
ndbi = (swir1 - nir) / (swir1 + nir + epsilon)
return {
'ndvi': ndvi,
'evi': evi,
'ndwi': ndwi,
'ndbi': ndbi
}
# 假设我们已经读取了一个多波段的影像数组
# indices = calculate_indices(multiband_image_array)
# plt.imshow(indices['ndvi'], cmap='RdYlGn', vmin=-1, vmax=1)
# plt.title("NDVI Map")
# plt.colorbar()
# plt.show()
这个函数展示了如何从多波段影像中计算出四种关键的指数。这些指数将成为我们机器学习模型的重要输入特征。
22.3.2 纹理特征:描述像素的空间排列
光谱特征只考虑单个像素的光谱值,忽略了其空间上下文。纹理特征则描述了像素在空间上的排列模式,对于区分那些光谱相似但纹理不同的地物(如不同类型的森林、农田)非常重要。
最常用的纹理描述方法是灰度共生矩阵。
GLCM原理:
GLCM是一个二维矩阵,其元素 (i, j) 表示在图像中的一个特定方向和距离上,灰度值为 i 的像素与灰度值为 j 的像素相邻出现的概率。
从GLCM中提取的纹理特征:
- 对比度:
sum(i-j)^2 * p(i,j),衡量局部灰度变化的程度。 - 相关性:
sum((i-μi)(j-μj)p(i,j)) / (σiσj),衡量局部纹理的线性相关性。 - 同质性/逆差矩:
sum(p(i,j)^2 / (1 + |i-j|)),衡量局部纹理的均匀性。 - 熵:
-sum(p(i,j) * log2(p(i,j))),衡量纹理的随机性或复杂度。
实战代码示例:
我们可以使用skimage库来计算GLCM和纹理特征。
from skimage.feature import greycomatrix, greycoprops
from skimage import io
import numpy as np
def calculate_glcm_features(band, distances=[1], angles=[0, np.pi/4, np.pi/2, 3*np.pi/4]):
"""
计算基于GLCM的纹理特征。
:param band: 单波段的2D numpy数组。
:param distances: 计算GLCM的像素距离。
:param angles: 计算GLCM的方向。
:return: 包含纹理特征的字典。
"""
# 将像素值量化到0-255以减少GLCM的大小
band_uint8 = band.astype(np.uint8)
# 计算GLCM
glcm = greycomatrix(band_uint8, distances=distances, angles=angles, levels=256, symmetric=True, normed=True)
# 从GLCM中计算特征
properties = ['contrast', 'dissimilarity', 'homogeneity', 'correlation', 'ASM', 'energy']
features = greycoprops(glcm, properties=properties)
# 对不同角度和距离的特征取平均
avg_features = {prop: np.mean(features[prop]) for prop in properties}
return avg_features
# 假设我们有一个红光波段的数组
# red_band = ...
# texture_features = calculate_glcm_features(red_band)
# print("Texture Features:", texture_features)
这段代码展示了如何为单个波段计算多种纹理特征。在我们的项目中,


425

被折叠的 条评论
为什么被折叠?



