I want to select the image with lowest median NDVI to represent bare ground cover from Sentinel-2 image collection for my region of interest (<5% cloud).

I have a boundary file pre-loaded on Asset called boundary.

I started with:

var start = ee.Date('2017-05-01'); //Dates of interest
var finish = ee.Date('2018-10-31'); 
var sentinel = ee.ImageCollection('COPERNICUS/S2')
.filterDate(start, finish)
.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 5)); 
//to get imagery with cloud coverage below 5%

//compute NDVI for each image
var NDVI = sentinel.map(
    function(img) {
        return img.normalizedDifference(['B8','B4'])

// now compute median for each NDVI image
var Dict = NDVI.map(
   return img.set('NDVI', 
     reducer: ee.Reducer.median(),
     geometry: boundary,
     scale: 10})

var best = ee.Image(Dict.sort('NDVI').first()); 

It turns out Image (Error) Collection.first: Cannot compare values '{NDVI=0.254702177047319}' (Type<Dictionary<Object>>) and '{NDVI=0.18543783789000937}' (Type<Dictionary<Object>>).

Ideally, I want it to return the index of that image from the sentinel image collection in response to the lower NDVI median so I can select it automatically.


To compute normalized difference in Google Earth Engine over an ImageCollection you have to map a function over it:

var NDVI = sentinel.map(
    function(img) {
        return img.normalizedDifference(['B8','B4'])

// now compute median of the collection
var median_NDVI = NDVI.median()
  • Thanks, good to learn new codes. However, I think you have misunderstood my question. print(NDVI) gives me 22 NDVI images and print(median_NDVI) gives me the median NDVI layer at each pixel. But what I want is to compute the median value for each layer and then select the image with lowest NDVI, then export that original image with bands. So treat NDVI as a threshold for image selection. Sep 10 '18 at 23:18
  • I get it, I think you should edit your question (the whole question) trying to express better what you mean, and I'll edit my answer too. Sep 11 '18 at 1:44

Here I answer my own question:

var Dict = NDVI.map(function(img) {
  var median = img.reduceRegion({reducer: ee.Reducer.median(), geometry:boundary, scale: 10});
  return img.set({median: median.get('NDVI')});

var best = ee.Image(Dict.sort('median', true).first()); 
print('Index: best image with the lowest NDVI median:', best.get('system:index'));

var bestImage = sentinel.filter(ee.Filter.equals('system:index', best.get('system:index'))); 

print('best image', bestImage);

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.