Выбор изображения из коллекции ee.ImageCollection на основе медианного значения атрибута - PullRequest
1 голос
/ 18 марта 2020

Я приписываю коллекцию изображений со значением, я хочу выбрать изображение со срединным значением этой коллекции изображений.

В настоящее время я делаю это, создавая список изображений со значением clientide, заполнение списка до нечетного, затем использование медианы, чтобы получить Id и значение, которое я хочу, а затем фильтрация коллекции по этому идентификатору. Это работает, но мне приходится делать вызовы, получать значения на стороне клиента, чтобы определить медианный идентификатор, а затем фильтровать коллекцию. Я чувствую, что это возможно без создания клиентского списка.

Поэтому мой вопрос заключается в том, могу ли я сделать это без получения клиентского списка, всей серверной части в EE, и как мне это сделать?

'' '

# returns a list of image data scores
client_list = get_attribute_and_id_client_side_list(ts_collection, 'datascore')

# padding so we always get a value rather than an average of 2
if len(client_list) % 2 == 0:
    client_list.append(['padding', 0])

median_datscore = np.median([item[1] for item in client_list])
median_score_coll = ts_collection.filterMetadata('data_score', 'equals', median_datscore)

' ''

Поэтому, по сути, для коллекции изображений со значением в метаданных я хочу выбрать только изображение с метаданной значение без использования стороны клиента getInfo ()

1 Ответ

0 голосов
/ 18 марта 2020

Вы можете использовать алгоритм ImageCollection.reduceColumns для получения медианного значения свойства коллекции. Затем вы можете использовать фильтр, чтобы выбрать элемент с этим значением.

Я подготовил пример в JavaScript, но, поскольку это полностью операции на стороне сервера, его не должно быть слишком сложно перевести:

var landsat = ee.ImageCollection("LANDSAT/LC08/C01/T1_TOA");
var pointOfInterest = ee.Geometry.Point([-115.10699177547879, 40.56521148064664]);

var images = landsat
    .filterDate('2017-05-01', '2017-09-01')
    .filterBounds(pointOfInterest)
    .map(function(img) {
      // Add a numeric property for the example: the value of B2 at a point.
      return img.setMulti(img.select(['B2'], ['B2_at_point']).reduceRegion({
        reducer: ee.Reducer.mean(),
        geometry: pointOfInterest,
      }));
    });

// Display the list of values, just for the example (this is not used further).
print(images.reduceColumns(ee.Reducer.toList(), ['B2_at_point']).get('list'));

// Compute the median.
var median = ee.Number(
  images.reduceColumns(ee.Reducer.median(), ['B2_at_point'])
    .get('median'));
print(median);

// Find the image or images that had the median.
var exactlyEqualsMedian = images.filter(ee.Filter.equals('B2_at_point', median));
var equalsOrNextToMedian = ee.ImageCollection(ee.Algorithms.If(
  exactlyEqualsMedian.first(),  // Is exactlyEqualsMedian nonempty?
  exactlyEqualsMedian,          // Then return it.
  images                        // Otherwise find the nearest 2 images.
    .map(function (i) {
      return i.set('median_distance', median.subtract(i.get('B2_at_point')).abs());
    })
    .limit(2, 'median_distance')));
print(equalsOrNextToMedian);

Map.setCenter(-115.08, 40.56, 9);
Map.addLayer(equalsOrNextToMedian, {bands: ['B4', 'B3', 'B2'], max: 0.4, gamma: 1.6});

https://code.earthengine.google.com/4e0d3d59535722f55425618e7defefff

(Пожалуйста, обратите внимание, что нет научного c достоинства для вычислений, сделанных здесь; это всего лишь пример поиска медианы в коллекции изображений.)

Обратите внимание, что я не воспользовался подходом заполнения ввода для медианы (). Скорее, я фильтрую потом, чтобы выбрать либо изображение точного совпадения, либо два ближайших совпадения. Это потому, что я ожидаю, что это будет более эффективно, чем пытаться настроить заполнение заранее (потому что это требует дополнительных запросов к коллекции, чтобы выяснить, насколько она велика). Вы, конечно, можете выбрать любое изображение в полученной коллекции из 2 изображений, которое соответствует вашим потребностям - если вам все равно, просто возьмите equalsOrNextToMedian.first().

...