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更新后代码就报错了。
知识体系总览
为了让你更直观地理解这五个核心对象的关系,我画了一张图:
这张图把五个核心对象的关系梳理得很清楚。你看,它们各自负责不同的任务,但又可以组合使用。比如,先用Filter筛选出符合条件的影像,再用Reducer计算统计量,最后用Join把结果拼接到矢量数据上。
好了,这一章的内容就到这里。记住,这五个工具是GEE的“基本功”。练好了它们,后面的路就好走了。
公众号:蓝海资料掘金营,微信deep3321