1

I want to reduce every single image in a collection, but I have not been able to make it. The process is really easy and works with a single image, but I need to do the same for every image in the collection.

My code:

// Statistics function
var stats = function(img) {
            var image = ee.Image(img);
            var reducers = ee.Reducer.mean().combine({
                reducer2: ee.Reducer.stdDev(),
                sharedInputs: true
                });
            var stats = image.reduceRegion({
                reducer: reducers,
                //geometry: geometry(),
                bestEffort: true,
                });
            return stats;
}

//Load collection
var collection = ee.ImageCollection('COPERNICUS/S2');

// Extract the image index from collection and make a list
var index = ee.List(['20190101T160509_20190101T160509_T17RNJ',
                    '20190104T160649_20190104T161509_T17RLH',
                    '20190104T160649_20190104T161509_T17RMJ',
                    '20190104T160649_20190104T161509_T17RMK']);

// Filter collection by image id list
var coll = collection
          .filter(ee.Filter.inList('system:index',index));

The reducer works perfectly for a single image

// Apply the statistics function over the whole extent of a single image
var one_stats = stats(coll.first());
print('One Stats',one_stats)

But, it does not work properly for every image in a collection

// Apply the statistics function over the whole extent of every image
var all_stats = coll.map(stats);
print('All Stats',all_stats)

2 Answers 2

3

You will have to return a feature or Image. Currently, you return a dictionary from the function. Set the output for example as properties to each image:

// Statistics function
var getStats = function(img) {
            var image = ee.Image(img);
            var reducers = ee.Reducer.mean().combine({
                reducer2: ee.Reducer.stdDev(),
                sharedInputs: true
                });
            var stats = image.reduceRegion({
                reducer: reducers,
                //geometry: geometry(),
                bestEffort: true,
                });
            return image.set(stats);
}
0
2

The error message is:

Collection.map: A mapped algorithm must return a Feature or Image.

This tells you what the problem is: you have to return a Feature or Image, but you have returned a Dictionary instead. A convenient solution in this case is to just make the contents of the dictionary be properties of the image: instead of return stats;, do

return image.setMulti(stats);

But you can also choose to return a newly created Feature that has only the properties you want and nothing of the original image.

By the way, you might want to select the bands you're interested in before the reduceRegion so that you're not computing statistics for bands you're not interested in.

0

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.