GEE错误:Dictionary does not contain key: bucketMeans.

简介: GEE错误:Dictionary does not contain key: bucketMeans.

问题:

ImageCollection (Error)

Error in map(ID=S1A_IW_GRDH_1SDV_20210305T102055_20210305T102120_036862_0455BC_F64C): Dictionary.get: Dictionary does not contain key: bucketMeans.

List (Error)

Collection.toList: Error in map(ID=S1A_IW_GRDH_1SDV_20210305T102055_20210305T102120_036862_0455BC_F64C): Dictionary.get: Dictionary does not contain key: bucketMeans.

问题主要应先更没有这个关键值,所以没办法获取,其实这里的本质我们刚开始看待程序的时候就是以为前面的function出了问题,但其实关键问题出在了影像筛选的过程中,这个筛选掉中因为我们多次筛选的时间结果不同给,所以会导致程序前面筛选的时间范围短,后面时间范围长,所以当你在执行程序的时候就出现了无法获取该指定影像的bucketmeans.

很多时候我们遇到这种问题一定要小心,往往这种问题不在于函数本身出错了。而在于我们应先该函数时间筛选的过程中是否有前后不一致的问题。

原有代码:

var imageVisParam = {"opacity":1,"bands":["VV"],"min":-25,"max":25,"gamma":1},
    imageVisParam3 = {"opacity":1,"bands":["water"],"palette":["1d0701","3812ff"]};
// 计算面积是geometre,roi是buffer后的
var geometry=ee.FeatureCollection("users/smowry1/hbsk").filter(ee.Filter.eq("id",1));
var buffer=geometry.first().get("buffer");
var roi=geometry.geometry().buffer(buffer)
var roiarea=ee.Number(roi.area()).divide(1000000)
// var bufferarea=roi.area.divide(1000000)
print(roi.area(),"buffer面")
print(buffer);
Map.centerObject(geometry, 8)
function clip(img){
  return img.clip(roi)
}
// 坡度校正
function slopeCorrection(image) { 
  var imgGeom =roi
  var srtm = ee.Image('JAXA/ALOS/AW3D30/V2_2').select('AVE_DSM').clip(imgGeom) 
  var sigma0Pow = ee.Image.constant(10).pow(image.divide(10.0))
 
  // Article ( numbers relate to chapters) 
  // 2.1.1 Radar geometry 
  var theta_i = image.select('angle')
  var phi_i = ee.Terrain.aspect(theta_i)
    .reduceRegion(ee.Reducer.mean(), theta_i.get('system:footprint'), 1000)
    .get('aspect')
 
  // 2.1.2 Terrain geometry
  var alpha_s = ee.Terrain.slope(srtm).select('slope')
  var phi_s = ee.Terrain.aspect(srtm).select('aspect')
 
  // 2.1.3 Model geometry
  // reduce to 3 angle
  var phi_r = ee.Image.constant(phi_i).subtract(phi_s)
 
  // convert all to radians
  var phi_rRad = phi_r.multiply(Math.PI / 180);
  var alpha_sRad = alpha_s.multiply(Math.PI / 180);
  var theta_iRad = theta_i.multiply(Math.PI / 180);
  var ninetyRad = ee.Image.constant(90).multiply(Math.PI / 180);
 
  // slope steepness in range (eq. 2)
  var alpha_r = (alpha_sRad.tan().multiply(phi_rRad.cos())).atan();
 
  // slope steepness in azimuth (eq 3)
  var alpha_az = (alpha_sRad.tan().multiply(phi_rRad.sin())).atan();
 
  // local incidence angle (eq. 4)
  var theta_lia = (alpha_az.cos().multiply((theta_iRad.subtract(alpha_r)).cos())).acos();
  var theta_liaDeg = theta_lia.multiply(180 / Math.PI);
  // 2.2 
  // Gamma_nought_flat
  var gamma0 = sigma0Pow.divide(theta_iRad.cos())
  var gamma0dB = ee.Image.constant(10).multiply(gamma0.log10());
  var ratio_1 = gamma0dB.select('VV').subtract(gamma0dB.select('VH'));
 
  // Volumetric Model
  var nominator = (ninetyRad.subtract(theta_iRad).add(alpha_r)).tan();
  var denominator = (ninetyRad.subtract(theta_iRad)).tan();
  var volModel = (nominator.divide(denominator)).abs();
 
  // apply model
  var gamma0_Volume = gamma0.divide(volModel);
  var gamma0_VolumeDB = ee.Image.constant(10).multiply(gamma0_Volume.log10());
 
  // we add a layover/shadow maskto the original implmentation
  // layover, where slope > radar viewing angle 
  var alpha_rDeg = alpha_r.multiply(180 / Math.PI);
  var layover = alpha_rDeg.lt(theta_i);
 
  // shadow where LIA > 90
  var shadow = theta_liaDeg.lt(85);
 
  // calculate the ratio for RGB vis
  var ratio = gamma0_VolumeDB.select('VV').subtract(gamma0_VolumeDB.select('VH'));
 
  var output = gamma0_VolumeDB.addBands(ratio).addBands(alpha_r).addBands(phi_s).addBands(theta_iRad)
    .addBands(layover).addBands(shadow).addBands(gamma0dB).addBands(ratio_1);
 
  return image.addBands(
    output.select(['VV', 'VH', 'slope_1', 'slope_2'], ['VV', 'VH', 'layover', 'shadow']),
    null,
    true
  ).addBands(image.select("angle"));
}
function PeronaMalik(I,iter, K, opt_method) {
  iter = iter || 10;
  K = K || 3;
  var method = opt_method || 1;
  // Define kernels
  var dxW = ee.Kernel.fixed(3, 3,
                           [[ 0,  0,  0],
                            [ 1, -1,  0],
                            [ 0,  0,  0]]);
  var dxE = ee.Kernel.fixed(3, 3,
                           [[ 0,  0,  0],
                            [ 0, -1,  1],
                            [ 0,  0,  0]]);
  var dyN = ee.Kernel.fixed(3, 3,
                           [[ 0,  1,  0],
                            [ 0, -1,  0],
                            [ 0,  0,  0]]);
  var dyS = ee.Kernel.fixed(3, 3,
                           [[ 0,  0,  0],
                            [ 0, -1,  0],
                            [ 0,  1,  0]]);
  var lambda = 0.2;
  var k1 = ee.Image(-1.0/K);
  var k2 = ee.Image(K).multiply(ee.Image(K));
  // Convolve
  for(var i = 0; i < iter; i++) {
    var dI_W = I.convolve(dxW);
    var dI_E = I.convolve(dxE);
    var dI_N = I.convolve(dyN);
    var dI_S = I.convolve(dyS);
  // Combine using choosen method
    switch(method) {
      case 1:
        var cW = dI_W.multiply(dI_W).multiply(k1).exp();
        var cE = dI_E.multiply(dI_E).multiply(k1).exp();
        var cN = dI_N.multiply(dI_N).multiply(k1).exp();
        var cS = dI_S.multiply(dI_S).multiply(k1).exp();
        I = I.add(ee.Image(lambda).multiply(cN.multiply(dI_N).add(cS.multiply(dI_S)).add(cE.multiply(dI_E)).add(cW.multiply(dI_W))));
        break;
      case 2:
        var cW = ee.Image(1.0).divide(ee.Image(1.0).add(dI_W.multiply(dI_W).divide(k2)));
        var cE = ee.Image(1.0).divide(ee.Image(1.0).add(dI_E.multiply(dI_E).divide(k2)));
        var cN = ee.Image(1.0).divide(ee.Image(1.0).add(dI_N.multiply(dI_N).divide(k2)));
        var cS = ee.Image(1.0).divide(ee.Image(1.0).add(dI_S.multiply(dI_S).divide(k2)));
        I = I.add(ee.Image(lambda).multiply(cN.multiply(dI_N).add(cS.multiply(dI_S)).add(cE.multiply(dI_E)).add(cW.multiply(dI_W))));
        break;
    }
  }
  return I;
};
function otsu(histogram) {
  // make sure histogram is an ee.Dictionary object
  histogram = ee.Dictionary(histogram);
  // extract relevant values into arrays
  var counts = ee.Array(histogram.get('histogram'));
  var means  = ee.Array(histogram.get('bucketMeans'));
  // calculate single statistics over arrays
  var size  = means.length().get([0]);
  var total = counts.reduce(ee.Reducer.sum(), [0]).get([0]);
  var sum   = means.multiply(counts).reduce(ee.Reducer.sum(), [0]).get([0]);
  var mean  = sum.divide(total);
  // compute between sum of squares, where each mean partitions the data
  var indices = ee.List.sequence(1, size);
  var bss     = indices.map(function(i) {
    var aCounts = counts.slice(0, 0, i);
    var aCount  = aCounts.reduce(ee.Reducer.sum(), [0]).get([0]);
    var aMeans  = means.slice(0, 0, i);
    var aMean   = aMeans.multiply(aCounts)
      .reduce(ee.Reducer.sum(), [0]).get([0])
      .divide(aCount);
    var bCount = total.subtract(aCount);
    var bMean  = sum.subtract(aCount.multiply(aMean)).divide(bCount);
    return aCount.multiply(aMean.subtract(mean).pow(2)).add(
        bCount.multiply(bMean.subtract(mean).pow(2)));
  });
  // return the mean value corresponding to the maximum BSS
  return means.sort(bss).get([-1]);
}
function edgeOtsu(img,kwargs) {
  var geom =roi
  
  // get list of band names used later
  var bandList = img.bandNames();
  var kwargKeys = [];
  for(var key in kwargDefaults) kwargKeys.push( key );
  var params;
  var i,k,v;
  // loop through the keywords and construct ee.Dictionary from them,
  // if the key is defined in the input then pass else use default
  params = ee.Dictionary(kwargs);
  for (i=0;i<kwargKeys.length;i++) {
    k = kwargKeys[i];
    v = kwargDefaults[k];
    params = ee.Dictionary(
      ee.Algorithms.If(params.contains(k),params,params.set(k,v))
    );
  }
  
  // parameters for all methods
  var initialThreshold = ee.Number( params.get('initialThreshold') ),
      reductionScale   = ee.Number( params.get('reductionScale') ),
      smoothing        = ee.Number( params.get('smoothing') ),
      bandName         = ee.String( params.get('bandName') ),
      connectedPixels  = ee.Number( params.get('connectedPixels') ),
      edgeLength       = ee.Number( params.get('edgeLength') ),
      smoothEdges      = ee.Number( params.get('smoothEdges') ),
      cannyThreshold   = ee.Number( params.get('cannyThreshold') ),
      cannySigma       = ee.Number( params.get('cannySigma') ),
      cannyLt          = ee.Number( params.get('cannyLt') ),
      maxBuckets       = ee.Number( params.get('maxBuckets') ),
      minBucketWidth   = ee.Number( params.get('minBucketWidth') ),
      maxRaw           = ee.Number( params.get('maxRaw') ),
      invert           = params.get('invert'),
      verbose          = params.get('verbose').getInfo();
      
  
  // get preliminary water
  var binary = img.lt(initialThreshold).rename('binary');
  // Map.addLayer(binary,{min:0,max:1},"binary threshold")
  // get canny edges
  var canny = ee.Algorithms.CannyEdgeDetector(binary, cannyThreshold, cannySigma);
  
  // Map.addLayer(canny,{},"Canny edge detection")
  
  // process canny edges
  var connected  = canny.updateMask(canny).lt(cannyLt).connectedPixelCount(connectedPixels, true);
  var edges      = connected.gte(edgeLength);
  edges          = edges.updateMask(edges);
  
  // Map.addLayer(edges,{},"edges")
  
  var edgeBuffer = edges.focal_max(smoothEdges, 'square', 'meters');
  
  // Map.addLayer(edgeBuffer,{},"Edge buffer")
  
  // get histogram for Otsu
  var histogram_image = img.updateMask(edgeBuffer);
  // histogram_image = histogram_image.clip(geometry2)
  var histogram = ee.Dictionary(histogram_image.reduceRegion({
    reducer:ee.Reducer.histogram(maxBuckets, minBucketWidth,maxRaw)
      .combine('mean', null, true).combine('variance', null,true),
    geometry: geom,
    scale: reductionScale,
    maxPixels: 1e13,
    tileScale:16
  }).get(bandName.cat('_histogram')));
  
  var threshold = otsu(histogram);
 
// var chart = constructHistChart(histogram,threshold)
//       .setOptions({
//         title: 'Edge Search Histogram',
//         hAxis: {
//           title: 'Values',
//         },
//         vAxis:{
//           title:'Count'
//         } 
//       });
// print('Algorithm parameters:',params);
// print("Calculated threshold:",threshold);
// print('Thresholding histogram:',chart);
 
  
  // segment image and mask 0 values (not water)
  var waterImg = ee.Image(ee.Algorithms.If(invert,img.gt(threshold),img.lt(threshold)));
  // Map.addLayer(waterImg,{palette:"white,blue"},"water image")
  return waterImg.set("threshold",threshold);
}
function constructHistChart(histogram,threshold){
  var counts = ee.List(histogram.get('histogram'));
  var buckets = ee.List(histogram.get('bucketMeans'));
  var segment = ee.List.repeat(0, counts.size());
  var maxFrequency   = ee.Number(counts.reduce(ee.Reducer.max()));
  var threshIndex    = buckets.indexOf(threshold);
  segment            = segment.set(threshIndex, maxFrequency);
  // var histChart = ui.Chart.array.values(ee.Array.cat([counts, segment], 1), 0, buckets)
  //   .setSeriesNames(['Values', 'Threshold'])
  //   .setChartType('ColumnChart');
    
  return histChart;
}  
var kwargDefaults = {
    'initialThreshold':-14,
    'reductionScale': 180,
    'smoothing': 100,
    'bandName': "VV",
    'connectedPixels': 100,
    'edgeLength': 30,
    'smoothEdges':buffer,
    'cannyThreshold': 1,
    'cannySigma': 1,
    'cannyLt': 0.05,
    'maxBuckets': 255,
    'minBucketWidth': 0.001,
    'maxRaw': 1e6,
    'invert':false,
    'verbose': false
};
var s1 = ee.ImageCollection("COPERNICUS/S1_GRD").filterDate("2021-01-01","2021-05-05").filterBounds(roi)
print("s1cccccccccccccccccc",s1)
// get a few sentinel1 images to run algorithms on
var s1 = ee.ImageCollection("COPERNICUS/S1_GRD")
         .filterDate("2018-01-01","2021-12-30")
                    .filterBounds(roi.centroid())
          .filter(ee.Filter.eq('orbitProperties_pass', 'ASCENDING'))
          .filter(ee.Filter.calendarRange(3, 11, 'month'))
              .filter(ee.Filter.calendarRange(2018, 2021, 'year'))
                    .filterDate("2018-01-01","2021-12-30")
                  .sort('system:time_start', true)
                    // .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
  .filter(ee.Filter.eq('instrumentMode', 'IW'))
print(s1,"s1raw")
// 获取时间
function gettimeand(img)
{
  var date = ee.Date( (ee.Image(img).get('system:time_start')));
var year = date.get('year');
var month = date.get('month');
var day = date.get('day');
  return img.set("data",date.millis())
            .set("year",year)
            .set("month",month)
              .set("day",day)
              .set("data1",img.date().format('YYYY-MM-dd'))
              
}
s1=s1.map(gettimeand)
print(s1.aggregate_array("data1"))
s1=s1.sort('system:time_start', true)
///预处理
s1=s1.map(slopeCorrection).map(PeronaMalik)
print(s1,"预处理后的s1")
var s1list= s1.toList(s1.size())
print(s1list,"s1list")
Map.addLayer(ee.Image(s1list.get(0)).clip(roi),imageVisParam,"raw")
Map.addLayer(ee.Image(s1list.get(1)).clip(roi),imageVisParam,"raw1")
Map.addLayer(ee.Image(s1list.get(2)).clip(roi),imageVisParam,"raw2")
Map.addLayer(ee.Image(s1list.get(3)).clip(roi),imageVisParam,"raw3")
// // // Map.addLayer(ee.Image(s1list.get(5)).clip(roi),imageVisParam,"raw5")
/OTSU函数无法获取bucketMeans///
var imageWateryear = s1.map(function(img){
    var imageWater = edgeOtsu(img.select("VV"),kwargDefaults).rename('water');
    return imageWater;
  })
 print(imageWateryear)
  
  
// 去掉山体阴影
function move(img){
var hand = ee.ImageCollection('users/gena/global-hand/hand-100');
var hand30 = hand.mosaic().focal_mean(0.1).rename('elevation');
var hillShadowMask = hand30.select('elevation').lte(30);
var dem = ee.Image("JAXA/ALOS/AW3D30/V2_2").select(0)
var slope = ee.Terrain.slope(dem);
var img1= ee.Image(img).unmask(0).clip(roi);
img1 = img1
.updateMask(hillShadowMask)
.updateMask(slope.lt(25))
return img1}  //mask外 is NoData
imageWateryear=imageWateryear
.map(move)
  
  
// print(imageWateryear)
var s1waterlist= imageWateryear.toList( imageWateryear.size())
print("s1waterlist",s1waterlist)
Map.addLayer(ee.Image(s1waterlist.get(0)),imageVisParam3,"0")
Map.addLayer(ee.Image(s1waterlist.get(1)),imageVisParam3,"1")
Map.addLayer(ee.Image(s1waterlist.get(2)),imageVisParam3,"2")
Map.addLayer(ee.Image(s1waterlist.get(3)),imageVisParam3,"3")
// // Map.addLayer(ee.Image(s1waterlist.get(4)),imageVisParam3,"4")
// // Map.addLayer(ee.Image(s1waterlist.get(5)),imageVisParam3,"5")
// // Map.addLayer(ee.Image(s1waterlist.get(6)),imageVisParam3,"6")
// // Map.addLayer(ee.Image(s1waterlist.get(62)),imageVisParam3,"62")
// // Map.addLayer(ee.Image(s1waterlist.get(5)),imageVisParam3,"5")
// // Map.addLayer(ee.Image(s1waterlist.get(10)).clip(roi),imageVisParam3,"10")
// // Map.addLayer(ee.Image(s1waterlist.get(11)).clip(roi),imageVisParam3,"11")
// // Map.addLayer(ee.Image(watercol.get(0)),{palette:"white,blue"},"water image");
// // print(watercol);
// // // // // 计算面积
var water_area = imageWateryear
                .map(function(img){
                  var area = ee.Image(img).select("water").eq(1).multiply(ee.Image.pixelArea())
                                          .reduceRegion({
                                            reducer: ee.Reducer.sum(),
                                            geometry: geometry, 
                                            scale: 20,
                                            maxPixels:1e16,
                                            tileScale:16
                                          });
                  var dthareakm2=ee.Number(area.get("water")).divide(1e6);
                  return img.set('area',dthareakm2);
                });
 print('water_area',water_area);
print("water_areanumber-fill",water_area.aggregate_array('area'));
var list=water_area.toList(water_area.size())

这里所有的影像直到2021年2月底,之后是没有影像的,所以没办法,后面的没数据所以没法做。

另外,我们在继续宁时间筛选的时候,不要三番五次进行时间筛选,有一次时间筛选就够了

修改后的代码:

// get a few sentinel1 images to run algorithms on
var s1 = ee.ImageCollection("COPERNICUS/S1_GRD")
         //.filterDate("2018-01-01","2021-12-31")
                    .filterBounds(roi.centroid())
          .filter(ee.Filter.eq('orbitProperties_pass', 'ASCENDING'))
                    .filterDate("2018-01-01","2021-03-01")
                  .sort('system:time_start', true)
                    // .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
  .filter(ee.Filter.eq('instrumentMode', 'IW'))
print(s1,"s1raw")

修复后的结果:

相关文章
|
3月前
|
数据处理
Google Earth Engine(GEE)——sentinel-1数据处理过程中出现错误Dictionary does not contain key: bucketMeans
Google Earth Engine(GEE)——sentinel-1数据处理过程中出现错误Dictionary does not contain key: bucketMeans
30 0
|
4月前
|
Python
在Python中,字典(dictionary)的键(key)具有唯一标识性
在Python中,字典(dictionary)的键(key)具有唯一标识性
49 1
C# Dictionary通过value获取对应的key值[转发]
1:最直白的循环遍历方法,可以分为遍历key--value键值对以及所有的key两种表现形式 2:用Linq的方式去查询(当然了这里要添加对应的命名空间 using System.Linq)  如下为一个十分简单的代码示例: private void GetDicKeyByValue() ...
1630 0
Dictionary<Key,Value>的用法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.
761 0
|
4月前
|
存储 Swift
在Swift编程语言中,字典(Dictionary)
在Swift编程语言中,字典(Dictionary)
34 3
|
7月前
|
存储 Java Python
多重字典(Multi-Level Dictionary)
多重字典(Multi-Level Dictionary)是一种将多个字典组合在一起的数据结构,用于解决需要在多个维度上查找数据的问题。多重字典可以看作是一个嵌套的字典,每个字典都可以作为其他字典的键。 使用多重字典的场景:
50 3
|
2月前
|
存储 算法 数据库
Python字典(Dictionary)
Python字典(Dictionary)
11 0
|
4月前
|
存储 缓存 数据库
python中的字典(Dictionary)
python中的字典(Dictionary)
19 0