问题:
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")
修复后的结果: