Google Earth Engine实战:5步搞定Sentinel-2影像的植被覆盖度计算(附完整代码)

张开发
2026/4/12 16:54:18 15 分钟阅读

分享文章

Google Earth Engine实战:5步搞定Sentinel-2影像的植被覆盖度计算(附完整代码)
Google Earth Engine实战5步搞定Sentinel-2影像的植被覆盖度计算附完整代码遥感技术正在重塑生态监测的格局。想象一下无需跋山涉水坐在电脑前就能获取全球任意区域的植被生长状况——这正是Google Earth EngineGEE赋予研究者的超能力。本文将手把手带您用Sentinel-2数据在GEE平台上完成从数据获取到植被覆盖度可视化的全流程操作。无论您是刚接触遥感的生态学学生还是需要快速评估项目区植被状况的环保从业者这套方法论都能让您在15分钟内获得专业级分析结果。1. 环境准备与数据基础植被覆盖度Fractional Vegetation Cover, FVC是衡量生态系统健康的核心指标之一其物理意义是植被冠层垂直投影面积占总面积的百分比。传统地面测量方法耗时费力而Sentinel-2卫星提供的10米分辨率影像配合GEE的云计算能力让大范围高频次监测成为可能。必备工具清单谷歌账号用于登录GEE平台浏览器访问 Earth Engine代码编辑器基础JavaScript语法知识GEE使用JS API提示首次使用GEE需申请访问权限审批通常需要1-2个工作日。建议提前完成账号注册和平台熟悉。Sentinel-2 MSI传感器的主要植被监测波段波段名称中心波长(nm)空间分辨率(m)典型用途B2 (Blue)49010水体穿透B3 (Green)56010植被活力B4 (Red)66510叶绿素吸收B8 (NIR)84210生物量评估B8A (窄NIR)86520冠层结构2. 数据获取与预处理核心步骤从定义研究区域开始。以下代码展示了如何用坐标点绘制多边形ROIRegion of Interest并加载2019年全年的Sentinel-2地表反射率数据// 定义研究区域以武汉周边为例 var roi ee.Geometry.Polygon([ [[113.731, 30.658], [113.739, 30.431], [113.830, 30.083], [114.337, 29.919], [114.773, 30.039], [115.056, 30.283], [115.056, 30.473], [114.605, 30.905], [113.778, 30.773]] ]); // 去云函数定义 function maskS2clouds(image) { var qa image.select(QA60); var cloudBitMask 1 10; var cirrusBitMask 1 11; var mask qa.bitwiseAnd(cloudBitMask).eq(0) .and(qa.bitwiseAnd(cirrusBitMask).eq(0)); return image.updateMask(mask).divide(10000); } // 加载2019年Sentinel-2数据 var dataset ee.ImageCollection(COPERNICUS/S2_SR) .filterDate(2019-01-01,2019-12-31) .filterBounds(roi) .map(maskS2clouds);关键操作要点云掩膜处理使用QA60波段的质量标识divide(10000)将DN值转换为真实反射率中值合成(.median())可有效减少异常值影响注意大面积区域分析时建议添加.filterMetadata(CLOUDY_PIXEL_PERCENTAGE,less_than,20)筛选低云量影像。3. 植被指数计算与优化NDVI归一化植被指数是FVC计算的基础其公式为(NIR - Red)/(NIR Red)。在GEE中实现如下// 生成中值合成影像 var image dataset.median().clip(roi); // 计算NDVI使用B8和B4波段 var NDVI image.normalizedDifference([B8,B4]).rename(NDVI); // 可视化参数 var ndviParams {min:-1, max:1, palette:[white, green]}; // 添加图层 Map.addLayer(NDVI, ndviParams, NDVI); Map.centerObject(roi, 9);NDVI值域解释0水体或非植被表面0-0.2裸土或稀疏植被0.2-0.5中等植被覆盖0.5茂密植被为提高计算精度建议先进行水体掩膜// 创建水体掩膜NDVI0视为水体 var waterMask NDVI.gt(0); var maskedImage image.updateMask(waterMask); var mask_water_NDVI NDVI.updateMask(waterMask);4. 像元二分模型实现像元二分模型假设每个像元由植被和土壤两部分组成FVC计算公式为FVC (NDVI - NDVI_soil) / (NDVI_veg - NDVI_soil)其中NDVI_soil和NDVI_veg分别代表纯土壤和纯植被的NDVI值。实际操作中常用5%和95%分位数作为近似function calFVC(BestVI, region, scale){ var num BestVI.reduceRegion({ reducer: ee.Reducer.percentile([5,95]), geometry: region, scale: scale, maxPixels: 1e13 }); var min ee.Number(num.get(NDVI_p5)); var max ee.Number(num.get(NDVI_p95)); var greaterPart BestVI.gt(max); var lessPart BestVI.lt(min); var middlePart ee.Image(1).subtract(greaterPart).subtract(lessPart); var tempf1 BestVI.subtract(min).divide(max.subtract(min)); var FVC ee.Image(1).multiply(greaterPart) .add(ee.Image(0).multiply(lessPart)) .add(tempf1.multiply(middlePart)); return FVC.rename(FVC); } var FVC calFVC(mask_water_NDVI, roi, 10);模型优化技巧对于不同生态系统可调整百分位阈值如干旱区用2%/98%添加地形校正DEM数据可提升山区精度季节差异大的地区应分季度计算5. 结果可视化与分析最后阶段将FVC结果分级展示并生成统计图表// 加载配色方案 var palettes require(users/gena/packages:palettes); var palette palettes.colorbrewer.RdYlGn[9]; // 添加FVC图层 Map.addLayer(FVC, {min:0.0, max:1.0, palette:palette}, FVC); // 分级显示 var L1 FVC.lt(0.3); // 低覆盖 var L2 FVC.lt(0.45).updateMask(FVC.gt(0.3)); var L3 FVC.lt(0.6).updateMask(FVC.gt(0.45)); var L4 FVC.lt(0.75).updateMask(FVC.gt(0.6)); var L5 FVC.lt(1.0).updateMask(FVC.gt(0.75)); Map.addLayer(L1, {palette: d7191c}, L1); Map.addLayer(L2, {palette: fdae61}, L2); Map.addLayer(L3, {palette: ffffbf}, L3); Map.addLayer(L4, {palette: a6d96a}, L4); Map.addLayer(L5, {palette: 1a9641}, L5); // 生成统计图表 var chart ui.Chart.image.histogram({ image: FVC, region: roi, scale: 250, maxPixels: 1e13 }); print(chart);典型问题解决方案结果异常值处理// 限制FVC在0-1之间 FVC FVC.where(FVC.lt(0), 0).where(FVC.gt(1), 1);批量导出结果Export.image.toDrive({ image: FVC, description: FVC_Export, scale: 10, region: roi, maxPixels: 1e13 });时间序列分析// 按月份计算FVC var monthlyFVC dataset.map(function(image){ var ndvi image.normalizedDifference([B8,B4]); return calFVC(ndvi, roi, 10).set(month, image.date().get(month)); });

更多文章