1

I tried standard scaling of each band of an image as follows:

var aoi = ee.Geometry.Polygon(
        [[[-98.3640625, 36.61967042308436],
          [-98.3640625, 32.86546781020435],
          [-92.91484375000002, 32.86546781020435],
          [-92.91484375000002, 36.61967042308436]]], null, false);
Map.addLayer(aoi);

var S2 = ee.ImageCollection('COPERNICUS/S2')
                    .filterBounds(aoi)
                    .filterDate('2019-07-01','2019-07-02')
                    .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',90))
                    .select('B.*').toBands();
print (S2);

var normalize = function(image) {
  var names = image.bandNames.map(function(name){
    var col = S2.select(name);
    var out = col.subtract(col.mean()).divide(col.stdDev())});
    return out.toBands()};
  
var normalized = ee.ImageCollection.fromImages(normalize).toBands();
print (normalized);

However, I got the following error.

Invalid argument specified for ee.List(): function normalize(_0) { return newF.apply(this, arguments); }

Can you help me?

3
  • Do you want to do this per band? So for every image every band should be corrected with col.subtract(col.mean()).divide(col.stdDev())? Where col.mean() is for example the mean for every band 2 in the collection?
    – JonasV
    Aug 4, 2020 at 14:56
  • yes, i want to do it per band separately.
    – mk1
    Aug 4, 2020 at 14:59
  • here is code, code.earthengine.google.com/176bb6e5da86f87386a9ab52c3034112
    – mk1
    Aug 4, 2020 at 15:03

1 Answer 1

1

Alright, so your code is a bit unusual for Earth Engine. I would heavily suggest you to do some of the tutorials available. They are pretty good for giving you an overview on how Earth Engine works.

Anyway, here's a more straightforward approach to what you want to do:

var S2 = ee.ImageCollection('COPERNICUS/S2')
                    .filterBounds(aoi)
                    .filterDate('2019-07-01','2019-07-02')
                    .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',90))
                    .select("B.*")
print (S2);

// Calculate mean, standard deviation and coefficient of variance
// for all Images in the collection per band
var meanS2 = S2.mean()
var stdDevS2 = S2.reduce(ee.Reducer.stdDev())
var coeffVarS2 = meanS2.divide(stdDevS2)

// Subtract every coefficient of variance by band for
// every image in the collection
var normalized = S2.map(function(image){
  return image.subtract(coeffVarS2).copyProperties(image)
})

print(normalized)

It works by first calculating the coefficient of variance (I think that's what you wanted to calculate) for every band in the Image Collection. Then you map (loop) over the Image Collection and subtract this coefficient from every Image in it.

9
  • I would like to re-explain my requirement. Here, I have an image (1830*1830 pixels) of 312 bands is given. I wanted to calculate mean and standard deviation across the bands and perform standard scaling, pixel-mean)/std. Not sure if you did the same??
    – mk1
    Aug 4, 2020 at 16:00
  • Ah yes right. I forgot that you called .toBands() on the ImageCollection. If you do not call .toBands() my code does exactly what you want it to do. I edited my answer to reflect that
    – JonasV
    Aug 4, 2020 at 16:04
  • In my real case, given condition is an image of many bands.
    – mk1
    Aug 4, 2020 at 16:06
  • What do you mean in your real case?
    – JonasV
    Aug 4, 2020 at 16:07
  • I have done some processing (not shown due to lengthy code) and got an image with bands, which is to be standardized now.
    – mk1
    Aug 4, 2020 at 16:08

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.