Как сгладить кривую ndvi в Google Earth движке
0 ответов
Существует множество алгоритмов сглаживания ( здесь есть статья, в которой сравниваются некоторые из них). Мне нравится подходить к нему, чтобы получить список дат в коллекции изображений и сопоставить его с этим списком, фильтруя / выбирая данные, которые вам нужны для конкретного алгоритма сглаживания в то время. Вот быстрый пример использования окна с линейной регрессией:
var s2 = ee.ImageCollection("COPERNICUS/S2"),
point = ee.Geometry.Point([-122.15815487909191, 37.81983948091395]);
var filteredIC = s2.filterBounds(point)
.filterDate('2016-01-01', '2017-12-31')
.sort('CLOUD_COVER')
// function to add NDVI and time bands to image collection
var addDataBands = function(image) {
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
return image.addBands(ndvi)
.addBands(image.metadata('system:time_start').divide(1e18).rename('time'));
};
// Function to smooth time series
// stacks windows of linear regression results
// requires that a variable 'data' exists with NDVI and time bands
function smoother(t){
// helper function to apply linear regression equation
function applyFit(img){
return img.select('time').multiply(fit.select('scale')).add(fit.select('offset'))
.set('system:time_start',img.get('system:time_start')).rename('NDVI');
}
t = ee.Date(t);
var window = data.filterDate(t.advance(-windowSize,'day'),t.advance(windowSize,'day'));
var fit = window.select(['time','NDVI'])
.reduce(ee.Reducer.linearFit());
return window.map(applyFit).toList(5);
}
// function to reduce time stacked linear regression results
// requires that a variable 'fitIC' exists from the smooter function
function reduceFits(t){
t = ee.Date(t);
return fitIC.filterDate(t.advance(-windowSize,'day'),t.advance(windowSize,'day'))
.mean().set('system:time_start',t.millis()).rename('NDVI');
}
var data = filteredIC.map(addDataBands);
print(data);
var dates = ee.List(data.aggregate_array('system:time_start'));
var windowSize = 30; //days on either side
var fitIC = ee.ImageCollection(dates.map(smoother).flatten());
var smoothed = ee.ImageCollection(dates.map(reduceFits));
// merge original and smoothed data into one image collection for plotting
var joined = ee.ImageCollection(smoothed.select(['NDVI'],['smoothed'])
.merge(data.select(['NDVI'],['original'])));
var chart = ui.Chart.image.series({
imageCollection: joined,
region: point,
reducer: ee.Reducer.mean(),
scale: 30
}).setOptions({title: 'NDVI over time'});
print(chart);
Map.addLayer(ee.Image(smoothed.sort('system:time_start',false).first()),{min:0,max:0.25,bands:['NDVI']},'Smoothed')
Map.addLayer(ee.Image(data.sort('system:time_start',false).first()),{min:0,max:0.25,bands:['NDVI']},'Original')
И ссылка на код: https://code.earthengine.google.com/3e2e1c0dfdac28a9d4230ca32cb9d7f3
Вы можете написать свои собственные пользовательские функции, используя аналогичный подход, чтобы применить любой алгоритм сглаживания, который вы хотите.
Надеюсь, это поможет!