Search code examples
classificationrastersupervised-learninggoogle-earth-enginelandsat

Supervised classification with only one class with Google Earth Engine


I am a beginner with geospatial analysis and Google Earth Engine. I am trying to classify only one class of Landsat 5 image (swimming pool). I got several training sites and applied the classifier. As a result my classified image appeared totally red (so the classification did not give me the expected results). Is that because I should classify several classes and not just one? And how to ask to classify my defined class by my training sites and create another class that gather all the pixels that does not belong to the class previously defined? Below the code I used:

var bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7']

var image= ee.Image('LANDSAT/LT05/C01/T1_TOA/LT05_015036_20111025')
      .select(bands)

// Train is the feature collection containing my training sites (points)
var training = image.sampleRegions({
               collection: train,
               properties: ['class'],
               scale: 30
               });

var trained = ee.Classifier.cart().train(training, 'class', bands);

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

Solution

  • Just as @Val said, you will need to have at least two classes. That means you will either have to bring a dataset that is the "everything else" class or you can create a pseudo-nonoccurrence dataset in Earth Engine. The pseudo-nonoccurrence sampling assumes that you have a perfect occurrence sample of the first class because it will select regions that are not near the first sample to create the other sample (if that makes any sense at all...). It might look something like this in code:

    var bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7']
    
    var image= ee.Image('LANDSAT/LT05/C01/T1_TOA/LT05_015036_20111025')
      .select(bands)
    
    // Train is the feature collection containing my training sites (points)
    var occurrence = image.sampleRegions({
               collection: train,
               properties: ['class'],
               scale: 30
               }).map(function(feature){
                   return feature.set('class',ee.Number(1))
               });
    
    // Create geometry where there is no occurrence data
    var nonarea = image.geometry().difference(train.buffer(100))
    
    // Sample from region where there is no occurrence data
    var nonoccurrence = image.sample({
               region: nonarea,
               scale: 30
               }).map(function(feature){
                   return feature.set('class',ee.Number(0))
               });
    
    // Merge the occurrence and non-occurrence feature collections
    var training = ee.FeatureCollection(occurrence.merge(nonoccurrence))
    
    var trained = ee.Classifier.cart().train(training, 'class', bands);
    
    // Classify the image with the same bands used for training.
    var classified = image.select(bands).classify(trained);
    

    (You may have to fix some of the data types in the above code, it was hard to test without sample data...). This is a commonly used approach in species distribution and disaster hazard modeling and hopefully is helpful for your use case!