2

I want to extract wheat pixels from the sentinel 2 image in google earth engine. Based on field analysis pixel should satisfy 3 conditions: NDVI value between 0.6 to 0.7, NDWI value between -0.5 to -0.58 and EVI value between 0.1 to 0.18. If the pixel is true for these conditions then only its a wheat pixel of my spp. of interest. I have written a java script link , but its not doing what I want. Is there any way to fulfill all the conditions? Also is it possible to apply it to image composite rather than image collection?

var s2 = ee.ImageCollection("COPERNICUS/S2");
var admin2 = ee.FeatureCollection("FAO/GAUL_SIMPLIFIED_500m/2015/level2");
var Bhopal = admin2.filter(ee.Filter.eq('ADM2_NAME', 'Bhopal'))
var geometry = Bhopal.geometry()
var rgbVis = {min: 0.0, max: 3000, bands: ['B4', 'B3', 'B2']};
var filtered = s2.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10))
.filter(ee.Filter.date('2020-03-01', '2020-03-31'))
.filter(ee.Filter.bounds(geometry))
var composite = filtered.median().clip(Bhopal)
// Map.addLayer(composite, rgbVis, 'Bhopal Composite') 
// This function calculates both NDVI an d NDWI indices
// and returns an image with 2 new bands added to the original image.
function addIndices(image) {
 var ndvi = image.normalizedDifference(['B8', 'B4']).rename('ndvi');
var ndwi = image.normalizedDifference(['B3', 'B8']).rename('ndwi');
return image.addBands(ndvi).addBands(ndwi);
}
function addEVI(image){
var NIR = image.select('B5').divide(10000);
var RED = image.select('B4').divide(10000);
var BLUE = image.select('B2').divide(10000);
return image.addBands(image.expression(  
'2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', 
{NIR:NIR,RED:RED,BLUE:BLUE}).rename('evi'));
}
var maskedW21 = function(image) {
var NDVI = image.select(['ndvi']);
var NDWI = image.select(['ndwi']);var EVI = image.select(['evi']);
 return image.addBands(ee.Image(1).updateMask((NDVI.lte(0.6).gte(0.7)).where(NDWI,NDWI.lte(-0.5)).where(EVI,EVI.gte(0.1))).rename('W21_mask'));
// return image.addBands(ee.Image(1).updateMask((NDVI.lte(0.6).gte(0.7)).where(NDWI,NDWI.lte(-0.5).gte(-0.6))).rename('W21_mask'));};
// var maskedW21 = function(image) {
//   var NDVI = image.select(['ndvi']);//     return image.addBands(ee.Image(1).updateMask(NDVI.lte(0.5).gte(0.7)).rename('W21_mask'));};
// Map the function over the collection
var withIndices = filtered.map(addIndices).map(addEVI).map(maskedW21);
var maskBands = function(image) {return image.updateMask(image.select('W21_mask'));//.updateMask(image.select('NDVI_mask'))};
var mask_indices = withIndices.map(maskBands)  
// Composite
var composite2 = mask_indices.median().clip(Bhopal)
print(composite2)
Map.addLayer(composite2, rgbVis, 'Bhopal Composite')
var palette = ['FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718','74A901', '66A000', '529400', '3E8601', '207401', '056201','004C00', '023B01', '012E01', '011D01', '011301'];
var ndviVis = {min:0, max:0.5, palette: palette }
var NDVI = composite2.select('ndvi')
Map.addLayer(NDVI,ndviVis,'NDVI')
var NDWI = composite2.select('ndwi')
Map.addLayer(NDWI,ndviVis,'NDWI')
// Extract the 'ndwi' band and display a NDWI map
// use the palette ['white', 'blue']

1 Answer 1

3

The problem with your script was the definition of the mask according to the values of interest in the NDVI, NDWI and EVI bands. In order to create a mask based on several conditions and bands you should use the function and. Here's a working version of your function.

var maskedW21 = function(image) {
  var NDVI = image.select(['ndvi']);
  var NDWI = image.select(['ndwi']);
  var EVI = image.select(['evi']);
  
  // Define masks according to the desired thresholds
  var maskNDVI = NDVI.lte(0.7).and(NDVI.gte(0.6));
  var maskNDWI = NDWI.lte(-0.5).and(NDWI.gte(-0.58));
  var maskEVI = EVI.lte(0.18).and(EVI.gte(0.1));
  
  // Make a mask that fulfills the three masks and rename the band
  var mask = maskNDVI.and(maskNDWI)
  .and(maskEVI)
  .rename('W21_mask');

  // Add the mask as a band to the image and update the mask for the image
  return image.addBands(mask)
  .updateMask(mask);
};

var withIndices = filtered.map(addIndices).map(addEVI);

var mask_indices = withIndices.map(maskedW21);

Finally, if you wish to apply the function to an image composite rather than an ImageCollection, you can do that by calling directly the function over the image. For example.

maskedW21(Image);

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.