Google Earth Engine中按有效像素占比过滤地块统计植被指数
解决方案:在GEE中过滤有效像素占比不足50%的地块
核心思路
要实现有效像素占比过滤,需在统计地块植被指数前,先计算地块内未被云/阴影遮挡的有效像素占比,仅保留占比≥50%的地块统计结果。具体步骤:
- 为每个影像生成有效像素二进制掩码(有效像素为1,无效为0)
- 统计每个地块的有效像素占比
- 过滤占比<50%的地块记录
修改后的完整代码
var parcelas = ee.FeatureCollection('projects/resag-1/assets/PAR_22_Cebada') var convencional = ee.FeatureCollection(parcelas) .filter(ee.Filter.eq('Manejo','convencional')); var conservacion = ee.FeatureCollection(parcelas) .filter(ee.Filter.eq('Manejo','conservacion')); var addindices = function(image) { var ndvi = image.normalizedDifference(['B8','B4']).rename('NDVI'); var CRC1 = image.normalizedDifference(['B11','B2']).rename('CRC1'); var NDSVI = image.normalizedDifference(['B11','B4']).rename('NDSVI'); /// normalized Diff Moisture Index var NDI7 = image.normalizedDifference(['B8','B12']).rename('NDI7'); var NDI5 = image.normalizedDifference(['B8','B11']).rename('NDI5'); var NDRI = image.normalizedDifference(['B12','B3']).rename('NDRI'); var DFI = image.expression( '100*(1-B12/B11)*(B4/B8A)', { 'B11': image.select('B11'), 'B12': image.select('B12'), 'B4' : image.select('B4'), 'B8A': image.select('B8A') }).rename('DFI'); var NDI3 = image.normalizedDifference(['B4','B12']).rename('NDI3'); var NDI4 = image.normalizedDifference(['B8A','B12']).rename('NDI4'); var RATIO = image.expression( /// Triangle vegetation index 'B12/B11'/*10000*/, { 'B11': image.select('B11'), 'B12': image.select('B12') }).rename('RATIO'); var MCRC = image.normalizedDifference(['B11','B3']).rename('MCRC'); var SRNDI = image.normalizedDifference(['B12','B4']).rename('SRNDI'); var NDTI = image.normalizedDifference(['B11','B12']).rename('NDTI'); /// normalized Diff Red Edge Index var STI = image.expression( /// Triangle vegetation index 'B11/B12',{ // DIVIDIDO PARA 10000 POR LA REFLECTANCIA ADICIONAL 10 PARA RANGO 'B11': image.select('B11'), 'B12': image.select('B12') }).rename('STI'); // 添加有效像素占比计算用的二进制掩码 var validPixelMask = image.mask().reduce(ee.Reducer.max()).rename('valid_pixel_mask'); return image.addBands([ndvi,CRC1,NDSVI,NDI7,NDI5,MCRC,SRNDI,NDTI,STI,RATIO,DFI,NDI3,NDI4,NDRI, validPixelMask]); }; // Funcion mask clouds function maskclouds_scl(imagen) { var scl = imagen.select('SCL'); // Seleccionar las clases de vegetacion, suelo, agua y nieve var veg = 4; var soil = 5; var water = 6; var snow = 11; // Mascara var mask = scl.eq(veg).or(scl.eq(soil)).or(scl.eq(water)).or(scl.eq(snow)); var properties = imagen.propertyNames(); var imagen_mask = ee.Image(imagen.updateMask(mask).copyProperties(imagen,properties)); return imagen_mask; } //sentinel-2 LA2 var S2 = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED"); var dataset = S2.filter(ee.Filter.date('2022-01-01', '2022-12-31')) .filterBounds(parcelas) .map(maskclouds_scl) .map(addindices) .select('B2','B3','B4','B5','B6','B7','B8','B8A','B11','B12', 'NDVI','CRC1','NDSVI','NDI7','NDTI','STI','MCRC','SRNDI','NDI5','RATIO','DFI','NDI3','NDI4','NDRI','valid_pixel_mask'); print(dataset) // 封装统计函数,避免重复代码 var calculateStats = function(featureCollection, description) { var stats = dataset.map(function(image) { return featureCollection.map(function(f){ // 计算有效像素占比:有效像素数 / 总像素数 var validPixelStats = image.select('valid_pixel_mask').reduceRegion({ reducer: ee.Reducer.mean(), // 均值即为有效像素占比(有效为1,无效为0) geometry: f.geometry(), scale: 20, maxPixels: 1e10 // 避免大区域像素数超限 }); var validRatio = validPixelStats.get('valid_pixel_mask'); // 仅当有效像素占比≥0.5时计算植被指数统计值 var mean = ee.Algorithms.If(ee.Number(validRatio).gte(0.5), image.reduceRegion({ reducer: ee.Reducer.mean(), geometry: f.geometry(), scale: 20, maxPixels: 1e10 }), ee.Dictionary() // 占比不足时返回空字典 ); var std = ee.Algorithms.If(ee.Number(validRatio).gte(0.5), image.reduceRegion({ reducer: ee.Reducer.stdDev(), geometry: f.geometry(), scale: 20, maxPixels: 1e10 }), ee.Dictionary() ); return f.set({ 'date': image.date().format(), 'valid_pixel_ratio': validRatio, // 保存有效像素占比,方便后续验证 // MEDIA 'NDVI_mean': ee.Dictionary(mean).get('NDVI'), 'CRC1_mean': ee.Dictionary(mean).get('CRC1'), 'NDSVI_mean': ee.Dictionary(mean).get('NDSVI'), 'NDI7_mean': ee.Dictionary(mean).get('NDI7'), 'NDTI_mean': ee.Dictionary(mean).get('NDTI'), 'STI_mean': ee.Dictionary(mean).get('STI'), 'MCRC_mean': ee.Dictionary(mean).get('MCRC'), 'SRNDI_mean': ee.Dictionary(mean).get('SRNDI'), 'NDI5_mean': ee.Dictionary(mean).get('NDI5'), 'RATIO_mean': ee.Dictionary(mean).get('RATIO'), 'DFI_mean': ee.Dictionary(mean).get('DFI'), 'NDI3_mean': ee.Dictionary(mean).get('NDI3'), 'NDI4_mean': ee.Dictionary(mean).get('NDI4'), 'NDRI_mean': ee.Dictionary(mean).get('NDRI'), // DESVIACION ESTANDAR 'NDVI_std': ee.Dictionary(std).get('NDVI'), 'CRC1_std': ee.Dictionary(std).get('CRC1'), 'NDSVI_std': ee.Dictionary(std).get('NDSVI'), 'NDI7_std': ee.Dictionary(std).get('NDI7'), 'NDTI_std': ee.Dictionary(std).get('NDTI'), 'STI_std': ee.Dictionary(std).get('STI'), 'MCRC_std': ee.Dictionary(std).get('MCRC'), 'SRNDI_std': ee.Dictionary(std).get('SRNDI'), 'NDI5_std': ee.Dictionary(std).get('NDI5'), 'RATIO_std': ee.Dictionary(std).get('RATIO'), 'DFI_std': ee.Dictionary(std).get('DFI'), 'NDI3_std': ee.Dictionary(std).get('NDI3'), 'NDI4_std': ee.Dictionary(std).get('NDI4'), 'NDRI_std': ee.Dictionary(std).get('NDRI') }); }); }) .flatten() // 过滤有效像素占比不足50%的记录 .filter(ee.Filter.gte('valid_pixel_ratio', 0.5)) // 过滤空值统计结果(冗余但保险) .filter(ee.Filter.neq('NDVI_mean', null)); // 导出结果 Export.table.toDrive({ collection: stats, description: description, fileFormat: 'CSV', folder: '' }); return stats; }; // 处理常规管理地块 var statsConvencional = calculateStats(convencional, 'index_S2_cons'); // 处理保护性管理地块 var statsConservacion = calculateStats(conservacion, 'index_S2_con');
关键修改点说明
- 添加有效像素掩码:在
addindices函数中,通过image.mask().reduce(ee.Reducer.max())生成二进制掩码图层,有效像素标记为1,被遮挡的无效像素标记为0。 - 计算有效像素占比:用
Reducer.mean()统计掩码图层的均值,直接得到有效像素占比(1的均值即为占比)。 - 条件统计与过滤:
- 用
ee.Algorithms.If判断占比是否≥0.5,仅满足条件时才计算植被指数的均值和标准差 - 最终通过
.filter(ee.Filter.gte('valid_pixel_ratio', 0.5))过滤不合格记录
- 用
- 代码复用优化:将重复的统计逻辑封装为
calculateStats函数,减少冗余代码,提升可维护性
内容的提问来源于stack exchange,提问作者Asier Herrera
相关产品推荐
相关产品推荐

