1

I'm new to GEE and Java scripts. I'm trying to do something that seems simple, but cannot find any way to do it.

I’ve an image (which is not that big, say 100 km * 100 km) with ~ 12 bands (and a 30 m spatial resolution in this case). My goal is to obtain the mean of each band (in order to center the bands, before a PCA). This is much harder than anticipated, because of user memory limit.

I tried several strategies, from the most naïve one (considering all the pixels and a ‘reduceRegion’ function) to a less computer-intensive one (considering a random subsample of pixels), and now trying to loop it band by band… in order to avoid reaching the user memory limit… while trying to obtain the output format of the initial “reduceRegion” function strategy.

Here is an example : [link] (https://code.earthengine.google.com/11e0e4b9f7ca71c42774f390ddecf0af)

In my last attempt, I've defined a simple function that returns the mean of a given band in a satellite image, and applied it with map() on the multi-band image:

var listofbands = ee.List(['B1', 'B2']);  // say i focus on 2 bands, named B1 and B2

var map_m = function(i) {

  i = ee.String(i)

  var Band_i = image.select(i)  // select the band i in the image

  var Mean_i = Band_i.reduceRegion({ // compute the mean over "sample", with sample e.g. 10 sample points

  reducer: ee.Reducer.mean(),

  geometry: sample.geometry(),

});

return Mean_i} // return this mean

var listOfResults = listofbands.map(map_m).flatten()  // apply the function to listofbands

print(listOfResults)  

enter image description here

It returns a "List", which contains one object per band in the image (and each object as the band name and the mean value). So it's not too bad but I do not want a "List", i want a single "Object" with all the band names and mean values in it:

enter image description here

I'm therefore trying to "unlist" this "List" (so that i obtain a single "object"), or convert the list to a single object (Dictionary)... without luck so far. This should be quite straightfoward... any idea?

Best

1 Answer 1

1

The simplest way to do this is to not use a map at all. Whenever you have an image with multiple bands, most operations will just process all the bands together, and that's what you want here.

print(image
  .select(['B1', 'B2'])  // Select ALL bands of interest.
  .reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: sample.geometry(),
  }));

This will give you one dictionary with keys B1 and B2 (corresponding to the band names).

Demo: https://code.earthengine.google.com/b77b2476f53c9959d9b1020f92596046


In order to reduce memory consumption, pass a tileScale parameter to reduceRegion. Larger numbers (greater than 1) divide the reduction into smaller pieces, allowing it to complete using less memory but with more processing overhead time.

2
  • Thank you Kevin for your answer. I updated a bit my post to better explain my problem…
    – Pleauthon
    Apr 10, 2020 at 23:54
  • @Pleauthon Ah, you should use tileScale for that, not break up the reduction, if at all possible.
    – Kevin Reid
    Apr 11, 2020 at 0:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.