0

From the following code I would like to mask the edges of my sentinel 1 composites.

@Daniel provided the code.

var roi = Map.getBounds(true)
var startDate = ee.Date('2015-01-01')
var endDate = ee.Date('2015-03-01')
var deltaDays = 16

var myCollection = ee.ImageCollection('COPERNICUS/S1_GRD')
    .filter(ee.Filter.eq('instrumentMode', 'IW'))
    .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
    .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
    .filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))
    .filterBounds(roi);

var days = endDate.difference(startDate, 'days')
var composites = ee.ImageCollection(
  ee.List.sequence(0, days.subtract(1), deltaDays)
    .map(function (offsetDays) {
      var start = startDate.advance(offsetDays, 'days')
      var end = start.advance(deltaDays, 'days')
      var masked = ee.Image([ee.Image(), ee.Image()]).rename(['VV', 'VH'])
      var composite = myCollection
        .filterDate(start, end)
        .median()
      var empty = composite.bandNames().size().eq(0)
      composite = masked.addBands(composite, null, true)
      return composite
        .addBands(
          composite.expression('c.VV - c.VH', {c: composite})
            .rename('VV-VH')
        )
        .select(['VV', 'VH', 'VV-VH'])
        .set('start', start.format('yyyy-MM-dd')) // Include dates of composite
        .set('end', end.format('yyyy-MM-dd'))
        .set('empty', empty)
        .clip(roi)
    })
  )
  .filterMetadata('empty', 'equals', 0) // Drop empty images
  .toList(1000)

I tried this but it did not bring me to any solutions:

exports.maskEdge = function(img) {
  var mask = img.select(0).unitScale(-25, 5).multiply(255).toByte().connectedComponents(ee.Kernel.rectangle(1,1), 100);
  return img.updateMask(mask.select(0)).set('system:time_start', img.get('system:time_start'));  
};
1

I usually use the angle band to mask the sides of the scenes, only allowing angles between 31 and 45 degrees. There's often some noise at the beginning and end of each track, so I mask that out too. This might lead to gaps in your composites though, so you might want to skip that in some cases.

function maskBorder(image) {
  var totalSlices = ee.Number(image.get('totalSlices'))
  var sliceNumber = ee.Number(image.get('sliceNumber'))
  var middleSlice = ee.Image(sliceNumber.gt(1).and(sliceNumber.lt(totalSlices)))
  var mask = image.select(['VV', 'VH']).mask().reduce(ee.Reducer.min()).floor()
  var pixelsToMask = mask.not()
    .fastDistanceTransform(128, 'pixels').sqrt()
  var metersToMask = pixelsToMask  
    .multiply(ee.Image.pixelArea().sqrt())    
    .rename('metersToMask')
  var notBorder = metersToMask.gte(500).and(pixelsToMask.gt(2))
  var angle = image.select('angle')
  return image
      .updateMask(
          angle.gt(31).and(angle.lt(45))
          .and(middleSlice.or(notBorder))
      )    
}

https://code.earthengine.google.com/97698941ca6e15516ae890a0c2676e0c

| improve this answer | |

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.