0

I have code that calculates the NDVI for agriculture plots. now i'm trying to create raster that will be composed from 3 colores according to the NDVI values- red= if the value is lowe then-> Mean- (Standard Deviation/2) light green= if the value is between -> Mean- std/2 to Mean+std/2 Dark green= if the value is higher than mean+std/2

my code knows to calculate the statistics, my problem is the classification. I tried to choose each time the pixels that are greater than those ''limits'' but for some reason, when I try to choose the light green values ( between Mean-Std/2 to Mean+std/2) it choose the pixels that are in the red category.

before adding the light gren category After adding the mean


/**
 * Function to mask clouds using the Sentinel-2 QA band
 * @param {ee.Image} image Sentinel-2 image
 * @return {ee.Image} cloud masked Sentinel-2 image
 */
function maskS2clouds(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

  return image.updateMask(mask).divide(10000)
  .copyProperties(image, ['system:time_start']);
}

// Map the function over one year of data and take the median.
// Load Sentinel-2 TOA reflectance data.
var dataset = ee.ImageCollection('COPERNICUS/S2')
                  .filterDate('2019-06-01', '2019-06-30')
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
                  .select('B1','B2','B3','B4','B8','QA60')
                  .filterBounds(geometry)
                  .map(maskS2clouds);

var rgbVis = {
  min: 0.0,
  max: 0.3,
  bands: ['B4', 'B3', 'B2'],
};

var clippedCol=dataset.map(function(im){ 
   return im.clip(geometry);
});

//test if clipping the image collection worked
Map.centerObject(geometry,9);
Map.addLayer(clippedCol.median(), rgbVis, 'RGB');

//function to calculate NDVI
var addNDVI = function(image) {
  var ndvi = image.normalizedDifference(['B8', 'B4'])
  .rename('NDVI')
  .copyProperties(image,['system:time_start']);
  return image.addBands(ndvi);

};

//NDVI to the clipped image collection
var withNDVI = clippedCol.map(addNDVI).select('NDVI');


var colorizedVis = {
  min: 0.0,
  max: 1.0,
  palette: [
    'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
    '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
    '012E01', '011D01', '011301'
  ],
};


//analyze images from image collection collection
var listOfImages = withNDVI.toList(withNDVI.size());
var listOfNumbers =[0,1,2];

for (var i in listOfNumbers) {
  var image = ee.Image(listOfImages.get(listOfNumbers[i]));
  var meanDictionary = image.reduceRegion({
  reducer: ee.Reducer.mean(),
  geometry:geometry.geometry()
  });

 var STDDictionary = image.reduceRegion({
  reducer: ee.Reducer.stdDev(),
  geometry:geometry.geometry()

});

// print(i,'mean',meanDictionary,'standard deviation',STDDictionary);

var std2 = ee.Number(STDDictionary.get("NDVI")).divide(2);
var mean1 = ee.Number(meanDictionary.get("NDVI"));

var negBorder=mean1.subtract(std2);
var posBorder=mean1.add(std2);

var imageNDVI=image.select('NDVI');
var gtPOS=imageNDVI.gt(posBorder).selfMask().rename('PositiveBorder');
var ltNEG=imageNDVI.lt(negBorder).selfMask().rename('NegativeBorder');
var betMEAN=imageNDVI.gt(negBorder).lt(posBorder).selfMask().rename('MeanBorder');

var PositiveCOL = {
  palette: [
  '006622'
  ],
};

var NegativeCOL = {
  palette: [
  'ff0000'
  ],
};

var MeanCOL = {
  palette: [
  '00ff00'
  ],
};

Map.addLayer(gtPOS,PositiveCOL,i);
Map.addLayer(ltNEG,NegativeCOL,i);
Map.addLayer(betMEAN,MeanCOL,i);

 }

i'm also not sure if I can ''merge'' those 3 groups of pixels into 1 raster, so if you have any idea how to modify this code it will be great.

0

I could not run your script directly in GEE. But this might help you to solve your problem if I understand your question correctly. Whenever you use Map.addLayer you create a layer or a map independently. What you have to do is to save the layer information into a Variable and then combine your variables into a single Layer. E.g.

var im1 = gtPOS(PositiveCOL)
var im2 = ltNEG(NegativeCOL)
ver im3 = betMEAN(MeanCOL)
var combo = im1.merge(im2).merge(im3);

Map.addLayer(combo)

Otherwise, I think that you can also use mosaic to do this. Refer to https://developers.google.com/earth-engine/ic_composite_mosaic to find out more.

  • this code doesn't work because it's not a function – Reut Sep 1 at 12:04

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.