0

I'm trying to extract the brightest 100 pixels of a single band image. More specifically,

  1. sort the pixel values of a single band image,

  2. extract the top 100 pixel values,

  3. put them into a list for further use.

Below is my solution based on a for-loop, but it's too slow and even failed when i > 100. Code link: https://code.earthengine.google.com/?scriptPath=users%2Fghongwei0309%2FGEE_ACO%3ABrightest_1000_Test

var dataset = ee.ImageCollection('COPERNICUS/S2')
                  .filterDate('2018-04-05', '2018-06-30')
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10));

var img = dataset.first().select('B3');
var ftpt = img.geometry();  //image footprint

var lst = ee.List([]);
for (var i=0; i<30; i++){
  var maxVal = img.reduceRegion({
    reducer: ee.Reducer.max(),
    geometry: ftpt,
    scale: 10,
    crs: 'EPSG: 4326',
    bestEffort: true
  }).getNumber('B3');
  img = img.updateMask(img.lt(maxVal));
  maxVal = img.reduceRegion({
    reducer: ee.Reducer.max(),
    geometry: ftpt,
    scale: 10,
    crs: 'EPSG: 4326',
    bestEffort: true
  }).getNumber('B3')
  lst = lst.add(maxVal);
};
print(lst.length());

How can I do this?

1 Answer 1

1

I didn't get your example to work because you didn't share your assets/scripts.

But here is something that might work for you. Although there might be a better solution, you could apply a reduceregion(), get the pixel values and return the +/- 100 highest values:

var reduce = image.select('B3').reduceRegion({
    reducer: ee.Reducer.frequencyHistogram(),
    geometry: geometry2,
    scale: 30,
    crs: 'EPSG: 4326',
    bestEffort: true
  })
  
print(reduce, 'reduce')

// # accumulate values
var values = ee.Dictionary(reduce.values().get(0)).toArray().accum(0)
print(values, 'values')


var max = ee.Number(values.project([0]).get([-1])).subtract(100).round()
print(max, 'max')

var valuesToMask = values.project([0]).round().gt(max);
print(valuesToMask, 'valuesToMask')

// Pixel values - returned as string
var filterList = ee.List(ee.Dictionary(reduce.get('B3')).keys())
print(filterList)//.multiply(valuesToMask))

// make it a number
var toNumbers =  filterList.map(function(q){
  var number = ee.Number.parse(q)
  
  return ee.Number(number)
})

// Now mask the original pixel values
var filteredValues = ee.Array(toNumbers).mask(valuesToMask)
print(filteredValues, 'filteredValues')

https://code.earthengine.google.com/008badec53cad63afd62dd859614b02d

1
  • Thank you very much, Jobbo. Your solution works well for me.
    – Hongwei
    Commented Dec 11, 2021 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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