0

The code is running correctly but it doesn't give me a smoothened result. Anyone who can help me out?

var startDate = '2015-01-01';
var endDate = '2023-12-31';

var images = sentinel.filter(ee.Filter.date(startDate,endDate)).filterBounds(geometry)
print(images);

var ndvi = function(image){
  var ndv = image.normalizedDifference(['B8','B4']);
  return ndv.copyProperties(image,['system:index', 'system:time_start'])
}
var ndvi = images.map(ndvi);
var filtered = sentinel
  .filter(ee.Filter.date('2019-01-01', '2020-01-01'))
  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
  .filter(ee.Filter.bounds(geometry))
// Write a function for Cloud masking
function maskCloudAndShadowsSR(image) {
  var cloudProb = image.select('MSK_CLDPRB');
  var cloud = cloudProb.lt(5);
  var scl = image.select('SCL'); 
  var shadow = scl.eq(3); // 3 = cloud shadow
  var cirrus = scl.eq(10); // 10 = cirrus
  // Cloud probability less than 5% or cloud shadow classification
  var mask = (cloud.and(cirrus.neq(1)).and(shadow.neq(1)));
  return image.updateMask(mask).divide(10000)
      .select("B.*")
      .copyProperties(image, ["system:time_start"]);
}
var filtered = filtered.map(maskCloudAndShadowsSR)

var filtered = filtered.map(function(image) {
  var timeImage = image.metadata('system:time_start').rename('timestamp')
  var timeImageMasked = timeImage.updateMask(image.mask().select(0))
  return image.addBands(timeImageMasked)
})

var days = 30
var millis = ee.Number(days).multiply(1000*60*60*24)

var maxDiffFilter = ee.Filter.maxDifference({
  difference: millis,
  leftField: 'system:time_start',
  rightField: 'system:time_start'
})

var lessEqFilter = ee.Filter.lessThanOrEquals({
  leftField: 'system:time_start',
  rightField: 'system:time_start'
})
var greaterEqFilter = ee.Filter.greaterThanOrEquals({
  leftField: 'system:time_start',
  rightField: 'system:time_start'
})

var filter1 = ee.Filter.and(maxDiffFilter, lessEqFilter)
 
var join1 = ee.Join.saveAll({
  matchesKey: 'after',
  ordering: 'system:time_start',
  ascending: false})
   
var join1Result = join1.apply({
  primary: filtered,
  secondary: filtered,
  condition: filter1
})

var filter2 = ee.Filter.and(maxDiffFilter, greaterEqFilter)
 
var join2 = ee.Join.saveAll({
  matchesKey: 'before',
  ordering: 'system:time_start',
  ascending: true})
   
var join2Result = join2.apply({
  primary: join1Result,
  secondary: join1Result,
  condition: filter2
})

var interpolateImages = function(image) {
  var images = ee.Image(image)
  // We get the list of before and after images from the image property
  // Mosaic the images so we a before and after image with the closest unmasked pixel
  var beforeImages = ee.List(image.get('before'))
  var beforeMosaic = ee.ImageCollection.fromImages(beforeImages).mosaic()
  var afterImages = ee.List(image.get('after'))
  var afterMosaic = ee.ImageCollection.fromImages(afterImages).mosaic()
  // Get image with before and after times
  var t1 = beforeMosaic.select('timestamp').rename('t1')
  var t2 = afterMosaic.select('timestamp').rename('t2')
  var t = images.metadata('system:time_start').rename('t')
  var timeImage = ee.Image.cat([t1, t2, t])
  var timeRatio = timeImage.expression('(t - t1) / (t2 - t1)', {
    't': timeImage.select('t'),
    't1': timeImage.select('t1'),
    't2': timeImage.select('t2'),})

  // Compute an image with the interpolated image y
  var interpolated = beforeMosaic
    .add((afterMosaic.subtract(beforeMosaic).multiply(timeRatio)))
  // Replace the masked pixels in the current image with the average value
  var result = images.unmask(interpolated)
  return result.copyProperties(image, ['system:time_start'])
}

var interpolatedCol = ee.ImageCollection(
  join2Result.map(interpolateImages))


print(ndvi);

var nd = ndvi.first().clip(geometry);
Map.addLayer(nd,{min:0,max:1,palette:['white','Green']},'NDVI');


var chart = ui.Chart.image.seriesByRegion({
imageCollection: ndvi,
  regions:geometry,
  reducer: ee.Reducer.mean(),
  scale: 250
});
print(chart);

1 Answer 1

0

To make the time series smoother, use the moving average function that is available in the below link: https://www.open-geocomputing.org/OpenEarthEngineLibrary/#.ImageCollection.movingWindow

code example: https://code.earthengine.google.com/25c26ec2407966eea61a2621a104703b

3
  • Thanks a lot that is really helpful! Now I try to adapt this code for Sentinel as this data is better for my project. I have a problem with the reflectance bands and the memory capacity, would it be possible to solve this?
    – Eppez
    Commented Feb 21 at 12:19
  • Welcome. I think it would be better to calculate your desired index such as NDVI and then apply the smoothing function on. Commented Feb 21 at 12:28
  • I solved the error in reflactance bands but I keep having a problem with memory limit. Any way to solve this?
    – Eppez
    Commented Feb 21 at 13:30

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.