0

I have created a mask band giving several band thresholds but I am unable to use this band for validation as there are no pixels outside the mask. So I would like to make a binary image with one value assigned to mask layer pixels [like 1] and others with one value [may be 2]. Is it possible to make binary image from mask band?

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']};
Map.centerObject(geometry,9.5);
var filtered1 = s2.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10))
  .filter(ee.Filter.date('2020-03-01', '2020-03-10'))
  .filter(ee.Filter.bounds(geometry))

var filtered2 = s2.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10))
  .filter(ee.Filter.date('2020-03-20', '2020-03-31'))
  .filter(ee.Filter.bounds(geometry))
   
// var composite1 = filtered1.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']);
  
  // 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 withIndices1 = filtered1.map(addIndices).map(addEVI);
var withIndices2 = filtered2.map(addIndices).map(addEVI);
var compositeA = withIndices1.median().clip(Bhopal);
var compositeB = withIndices2.median().clip(Bhopal);
print(compositeA);
print(compositeB); 

In this case I want to convert W21_mask to a binary image[1 2]. What I tried is simply mosaic,

var wh_mask =  compositeA.select(['W21_mask']);
var background = 0;
var im_back =  ee.Image(background).clip(area).rename('W21_mask');
var binary = ee.ImageCollection([im_back,wh_mask]).mosaic();

but it returns with following

    binary: Tile error: Expected a homogeneous image collection, but an image with an incompatible band was encountered. Mismatched type for band 'Burned1':
    Expected type: MaskOnly.
      Actual type: Byte<0, 1>.
         Image ID: 1
This band might require an explicit cast.

So i dont know if its working or not. what can be done to get binary image from mask ?

1 Answer 1

0

I figured it out. It's was error of casting, so I just added .toFloat(); to the bands.

var wh_mask =  compositeA.select(['W21_mask']).toFloat();
var background = 0;
var im_back =  ee.Image(background).clip(area).rename('W21_mask').toFloat();
var binary = ee.ImageCollection([im_back,wh_mask]).mosaic();

Now I'm getting an image with float but homogenous background and foreground (which will work for me).

My approach may be clumsy if anyone can suggest better solution please post. It will defiantly add a value.

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.