You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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');

关键修改点说明

  1. 添加有效像素掩码:在addindices函数中,通过image.mask().reduce(ee.Reducer.max())生成二进制掩码图层,有效像素标记为1,被遮挡的无效像素标记为0。
  2. 计算有效像素占比:用Reducer.mean()统计掩码图层的均值,直接得到有效像素占比(1的均值即为占比)。
  3. 条件统计与过滤:
    • 用ee.Algorithms.If判断占比是否≥0.5,仅满足条件时才计算植被指数的均值和标准差
    • 最终通过.filter(ee.Filter.gte('valid_pixel_ratio', 0.5))过滤不合格记录
  4. 代码复用优化:将重复的统计逻辑封装为calculateStats函数,减少冗余代码,提升可维护性

内容的提问来源于stack exchange,提问作者Asier Herrera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 04:18:08