4. GEE核心对象(下):统计器、过滤器、连接器、卷积核与算法库

好,咱们接着聊GEE的核心对象。上一章我把Image和FeatureCollection这些“数据容器”讲透了,这一章咱们来聊聊怎么“折腾”这些数据。

说白了,GEE里最值钱的不是数据本身,而是你处理数据的能力。而Reducer、Filter、Join、Kernel、Algorithms这五个家伙,就是你手里的五把利器。

4.1 Reducer(统计器):把一堆数算成一个数

Reducer这个名字起得好,就是“归约”的意思。你有一堆像素值,想算个均值?用ee.Reducer.mean()。想算个总和?用ee.Reducer.sum()。就是这么直白。

核心思想:Reducer把一组数值“压缩”成一个统计量。它不挑食,Image、FeatureCollection、List都能用。

我刚开始用GEE时,总觉得Reducer是个黑盒子。后来发现,它其实就是个“统计函数生成器”。你给它一个统计需求,它给你一个函数,然后你把这个函数丢给reduceRegion()reduceColumns()就行。

举个例子,你想知道某个区域NDVI的平均值:

// 加载一个Landsat影像
var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318');

// 计算NDVI
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');

// 定义一个感兴趣区(多边形)
var roi = ee.Geometry.Polygon([
  [-122.5, 37.5],
  [-122.3, 37.5],
  [-122.3, 37.7],
  [-122.5, 37.7]
]);

// 用Reducer算均值
var meanNdvi = ndvi.reduceRegion({
  reducer: ee.Reducer.mean(),
  geometry: roi,
  scale: 30,
  maxPixels: 1e9
});

print('平均NDVI:', meanNdvi);

你看,ee.Reducer.mean()就是那个“统计函数”。它告诉GEE:“嘿,帮我把这个区域里所有NDVI像素值加起来,除以像素个数。”

常用的Reducer有哪些?

Reducer 作用 适用场景
ee.Reducer.mean() 计算均值 植被指数、温度等连续变量
ee.Reducer.sum() 计算总和 降雨量、人口等累加变量
ee.Reducer.minMax() 同时返回最小值和最大值 极值分析
ee.Reducer.percentile([p]) 计算百分位数 异常值检测、分位数分析
ee.Reducer.stdDev() 计算标准差 数据离散程度分析

我的小技巧:如果你需要同时算多个统计量,可以用ee.Reducer.mean().combine(ee.Reducer.stdDev())。这样一次遍历就能拿到均值和标准差,效率翻倍。

4.2 Filter(过滤器):从数据堆里挑出你要的

Filter这东西,说白了就是“筛子”。你有一堆影像或一堆矢量,想只保留某个时间范围、某个区域、某个属性值的?用Filter就对了。

我记得有一次做项目,需要筛选2015年到2020年之间、云量低于20%的Landsat影像。用Filter一筛,几百张影像瞬间变成几十张,爽得很。

// 加载Landsat 8影像集合
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA');

// 用Filter筛选
var filtered = collection
  .filterDate('2015-01-01', '2020-12-31')  // 时间过滤
  .filterBounds(roi)                        // 空间过滤
  .filter(ee.Filter.lt('CLOUD_COVER', 20)); // 云量过滤

print('筛选后的影像数量:', filtered.size());

常用的Filter类型:

  • 时间过滤:filterDate(),指定起止日期
  • 空间过滤:filterBounds(),指定几何区域
  • 属性过滤:filterMetadata()ee.Filter.eq()ee.Filter.lt()
  • 字符串过滤:ee.Filter.stringContains()ee.Filter.startsWith()

避坑指南:我曾经犯过一个错误——先加载了整个ImageCollection,再慢慢筛选。结果数据量太大,浏览器直接卡死。正确的做法是:先筛选,再处理。把Filter写在最前面,让GEE在服务器端就把数据量降下来。

4.3 Join(连接器):把两张表拼在一起

Join这个概念,如果你用过SQL,应该不陌生。就是把两个FeatureCollection按照某个字段“粘”在一起。

嗯,这里要注意:GEE的Join不是万能的。它只能做“一对一”或“一对多”的连接,不支持“多对多”。而且连接条件必须基于属性字段,不能基于空间关系(空间连接得用别的方法)。

// 创建两个FeatureCollection
var stations = ee.FeatureCollection([
  ee.Feature(null, {id: 'A', name: '站点A'}),
  ee.Feature(null, {id: 'B', name: '站点B'})
]);

var measurements = ee.FeatureCollection([
  ee.Feature(null, {station_id: 'A', value: 25}),
  ee.Feature(null, {station_id: 'A', value: 30}),
  ee.Feature(null, {station_id: 'B', value: 28})
]);

// 定义连接条件
var filter = ee.Filter.equals({
  leftField: 'id',
  rightField: 'station_id'
});

// 执行连接
var joined = ee.Join.saveAll('measurements').apply({
  primary: stations,
  secondary: measurements,
  condition: filter
});

print('连接结果:', joined);

你看,ee.Join.saveAll()把匹配到的所有测量值都存到了一个叫measurements的列表里。这样每个站点就带上了它所有的测量数据。

常用的Join类型:

Join类型 作用 示例
ee.Join.saveFirst() 只保存第一个匹配项 每个站点只保留最近一次测量
ee.Join.saveAll() 保存所有匹配项 每个站点保留所有测量记录
ee.Join.inner() 只保留有匹配的记录 只保留有测量数据的站点

4.4 Kernel(卷积核):图像处理的“滤镜”

Kernel,说白了就是一个“小矩阵”。你把它滑过整张影像,每个像素的值就被它周围的像素“加权平均”了。这就是卷积操作。

我刚开始学遥感时,总觉得卷积很神秘。后来发现,它其实就是“看邻居的脸色办事”。每个像素的新值,取决于它和周围像素的关系。

// 创建一个3x3的高斯核
var gaussianKernel = ee.Kernel.gaussian({
  radius: 3,
  sigma: 1,
  units: 'pixels'
});

// 对影像做卷积
var smoothed = image.convolve(gaussianKernel);

// 显示结果
Map.addLayer(smoothed, {bands: ['B4', 'B3', 'B2'], min: 0, max: 0.3}, '平滑后影像');

常用的Kernel类型:

  • 高斯核:ee.Kernel.gaussian(),用于平滑、去噪
  • 拉普拉斯核:ee.Kernel.laplacian(),用于边缘检测
  • 索贝尔核:ee.Kernel.sobel(),用于梯度计算
  • 自定义核:ee.Kernel.fixed(),自己定义权重矩阵

我的经验:做图像平滑时,高斯核的sigma参数很关键。sigma越大,平滑效果越强,但细节丢失也越多。我一般从sigma=1开始试,不够再调大。

4.5 Algorithms(算法库):GEE的“瑞士军刀”

Algorithms是GEE提供的一组预定义算法。它们不是某个对象的方法,而是独立的函数。你直接调用ee.Algorithms.xxx()就行。

我个人觉得,Algorithms是GEE里最被低估的功能。很多人只知道用Image的方法,却不知道Algorithms里藏着很多宝贝。

// 使用Canny边缘检测算法
var edges = ee.Algorithms.CannyEdgeDetector({
  image: smoothed,
  threshold: 0.5,
  sigma: 1
});

// 使用水体指数计算
var waterMask = ee.Algorithms.Landsat.simpleComposite({
  collection: filtered,
  asFloat: true
});

常用的Algorithms分类:

类别 算法示例 用途
图像处理 CannyEdgeDetector, HoughTransform 边缘检测、直线检测
地形分析 Terrain.slope, Terrain.aspect 坡度、坡向计算
时间序列 Interpolate, TemporalSegmentation 数据插值、时间分割
分类 RandomForest, SVM 机器学习分类

注意:Algorithms里的算法有些是实验性的,比如ee.Algorithms.TemporalSegmentation。用之前最好看看文档,确认它是不是稳定版本。我曾经踩过坑,用了一个实验性算法,结果第二天GEE更新后代码就报错了。

知识体系总览

为了让你更直观地理解这五个核心对象的关系,我画了一张图:

GEE核心对象(下)知识体系 GEE核心对象 Reducer(统计器) Filter(过滤器) Join(连接器) Kernel(卷积核) Algorithms(算法库) 数据归约与统计 数据筛选与过滤 数据连接与合并 图像卷积与滤波 预定义算法集合 这五个对象是GEE数据处理的核心工具 掌握它们,你就能灵活处理遥感数据

这张图把五个核心对象的关系梳理得很清楚。你看,它们各自负责不同的任务,但又可以组合使用。比如,先用Filter筛选出符合条件的影像,再用Reducer计算统计量,最后用Join把结果拼接到矢量数据上。

好了,这一章的内容就到这里。记住,这五个工具是GEE的“基本功”。练好了它们,后面的路就好走了。


公众号:蓝海资料掘金营,微信deep3321