2

Say in this example, the classified results are: water (2), vegetation (1) and urban (0). I want to extract water only, i.e. pixels with the value 2. I couldn't find a function in GEE that would let me specifically extract out pixels of a certain value, so I tried to carry out the following:

  • utilised .lte() function to extract pixels of value 1 and 0 i.e. not water
  • mask out non-water pixels (i.e. 1 and 0) from the classified results such that only water pixels will show

However, it failed and I'm not sure where I went wrong. So my questions are as follows:

  1. Where did I go wrong with the above workflow?
  2. Is there a more straightforward way to directly extract pixels of a specific value, say in this case 2, without having to go through the hassle of masking etc? What if I wanted pixels within a certain range, say 1-2? Would it be the same function?

Many thanks.

// Make a cloud-free Landsat 8 TOA composite (from raw imagery).
var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1');

var image = ee.Algorithms.Landsat.simpleComposite({
  collection: l8.filterDate('2018-01-01', '2018-12-31'),
  asFloat: true
});

// Use these bands for prediction.
var bands = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B10', 'B11'];

// Load training points. The numeric property 'class' stores known labels.
var points = ee.FeatureCollection('GOOGLE/EE/DEMOS/demo_landcover_labels');

// This property stores the land cover labels as consecutive
// integers starting from zero.
var label = 'landcover';

// Overlay the points on the imagery to get training.
var training = image.select(bands).sampleRegions({
  collection: points,
  properties: [label],
  scale: 30
});

// Train a CART classifier with default parameters.
var trained = ee.Classifier.smileCart().train(training, label, bands);

// Classify the image with the same bands used for training.
var classified = image.select(bands).classify(trained);


var random = classified.lte(1);
//extracting out pixels less than or equals to 1, i.e. not water
var notWater = classified.updateMask(random);

var onlyWater = classified.updateMask(notWater);

// Display the inputs and the results.
Map.centerObject(points, 11);
Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], max: 0.4}, 'image');
Map.addLayer(notWater,
             {},
             'not water');
Map.addLayer(classified,
             {min: 0, max: 2, palette: ['red', 'green', 'blue']},
             'classification');
Map.addLayer(random,
             {},
             'random');
Map.addLayer(classified.updateMask(random),
             {},'classified masked with random');

// to display only water pixels 
Map.addLayer(onlyWater,
             {},
             'only water');

2
  • 1
    What do you mean by "extract pixels?" You want a mask or a list of lat,lon pixel centers or something else?
    – Jon
    Apr 28 '20 at 15:34
  • @Jon yup, i was referring to a mask! Apr 28 '20 at 15:36
6

I'm not completely sure this is exactly what you're asking for:

var onlyWater = classified.updateMask(
  classified.eq(2) // Only keep pixels where class equals 2
)

var notWater = classified.updateMask(
  classified.neq(2) // Only keep pixels where class not equals 2
)

If you need to define a range instead, you could do this (doesn't really make sense for this use case, if I get you right, but I'll show it anyway):

var onlyWater = classified.updateMask(
  classified.gt(1).and(classified.lt(3))
)

// eq() - equals
// neq() - not equals
// lt() - less than 
// gt() - greater than
// lte() - less than or equals
// gte() - greater than or equals
// and() - logical and
// or() - logical or
1
  • this was exactly what I was looking for. Thank you! :) Apr 29 '20 at 2:10

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.