[GIS] Counting number of pixel identified as water from a collection of landsat image using Google Earth Engine

google-earth-enginelandsat 8

My objective is to count the number of pixel identified as water from a collection of landsat images. The following function masks out non-water area for each image in the image collection, it also add a new band called 'NDWI' to each image:

var landsat8= ee.ImageCollection('LANDSAT/LC8_L1T_TOA').filterBounds(geometry)
   var waterThreshold = 0; 
// water function:
var waterfunction = function(image){
  //add the NDWI band to the image
  var ndwi = image.normalizedDifference(['B3', 'B6']).rename('NDWI');
  //isolate the water likelihood band
  var quality = ndwi.select('NDWI');
  //get pixels above the threshold
  var water01 = quality.gt(waterThreshold);
  //create a mask from high likelihood pixels
  var watermask = image.mask().and(water01 );
  //mask those pixels from the image
  return image.updateMask(watermask).addBands(ndwi);
};
var collection= landsat8.map(waterfunction);

Could you help me do the next steps?

  1. Count how many pixel identified as water (band NDWI >0) in each image within the polygon called "geometry" and then calculate the water area. Pixel scale = 30 (m)
  2. Print a time series of (1)

I know the cloud could be a problem, and we should clean it first, but leave it like this for now.

Best Answer

It's going to be something like this:

var landsat8= ee.ImageCollection('LANDSAT/LC8_L1T_TOA').filterBounds(geometry)
var waterThreshold = 0; 

// water function:
var waterfunction = function(image){
  //add the NDWI band to the image
  var ndwi = image.normalizedDifference(['B3', 'B6']).rename('NDWI');
  //get pixels above the threshold
  var water01 = ndwi.gt(waterThreshold);
  //mask those pixels from the image
  image = image.updateMask(water01).addBands(ndwi);

  var area = ee.Image.pixelArea();
  var waterArea = water01.multiply(area).rename('waterArea');

  image = image.addBands(waterArea);

  var stats = waterArea.reduceRegion({
    reducer: ee.Reducer.sum(), 
    geometry: geometry, 
    scale: 30,
  });

  return image.set(stats);
};
var collection = landsat8.map(waterfunction);
print(collection);

var chart = ui.Chart.image.series({
  imageCollection: collection.select('waterArea'), 
  region: geometry, 
  reducer: ee.Reducer.sum(), 
  scale: 30,
});
print(chart);

I took the liberty of removing some redundant code from your function. Watch out for a reduction inside a map() for the reasons described here. Also, note that you may get no pixels in the result (waterArea=0) if the region overlaps the image footprint, but no valid pixels.

Related Question