In this tutorial, we will learn how to create a water mask using Synthetic Aperture Radar (SAR) imagery from the Sentinel-1 satellite and Google Earth engine; GEE. The water mask will help us identify areas of open water within a specific region of interest. This educational simple tutorial is inspired by the one of the trainings hold by the Applied Remote Sensing Training Program ARSET.

Prerequisites

Before getting started with this tutorial, make sure you have the following:

  • Basic knowledge of remote sensing concepts
  • Access to Google Earth Engine (GEE) platform
  • Familiarity with JavaScript programming language
  • GEE account (create one at GEE website)

–> Once you have an account, you can start writing the code by visiting code.earthengine.google.com/.

Let’s get started with the code:

Set up Area of Interest (AOI)

var polygon = ee.Geometry.Polygon([
  [[-60.31,-4.52], [-57.81,-4.52], [-57.81,-2.92], [-60.31,-2.92], [-60.31,-4.52]]
]);

var aoi = ee.FeatureCollection(polygon);

Map.addLayer(aoi, {}, 'AOI');
Map.centerObject(aoi);

Get Sentinel 1 GRD data

var S1_img = ee.ImageCollection('COPERNICUS/S1_GRD')
    .filter(ee.Filter.eq('instrumentMode', 'IW'))
    .filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))
    .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
    .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
    .filterMetadata('resolution_meters', 'equals',10)
    .filterBounds(aoi)
    .filterDate('2015-04-25','2015-04-29')
    .select(['VV','VH'])
    .first();

print(S1_img, "S1_col");

// Adding the VV layer to the map
Map.addLayer(S1_img.select(['VV']), {min: -20, max: -7}, 'VV no filter');
Map.addLayer(S1_img.select(['VH']), {min: -20, max: -7}, 'VH no filter');

Apply a filter to reduce speckle

var SMOOTHING_RADIUS = 20;
var S1 = S1_img.focal_mean(SMOOTHING_RADIUS, 'circle', 'meters').int32();
print(S1, 'S1');
Map.addLayer(S1, {min: -20, max: -7}, 'S1');
Map.addLayer(S1.select(['VV']), {min: -20, max: -7}, 'VV filtered');
Map.addLayer(S1.select(['VH']), {min: -20, max: -7}, 'VH filtered');

Display as a SAR composite

var VV = S1.select('VV');
var VH = S1.select('VH');
var VV_VH = VV.divide(VH).int32().rename('VV_VH');
var S1_composite = S1.addBands(VV_VH);

print(S1_composite,'S1_composite');

Map.addLayer(S1_composite , {min: [-25, -20, -25], max: [0, 10, 0]}, 'S1 composite');

Create a water mask

// Applying a threshold to determine water/non-water areas:
var VH_binary = S1.select('VH').gte(-18);
Map.addLayer(VH_binary,{},'vh_binary');

var water_isolated = VH_binary.selfMask();
Map.addLayer(water_isolated, {'palette':['#2ca25f']}, 'Water Mask');

Voila!!

Sentinel-1 composite.

Water mask


References: