Google Earth Engine – Adding Band Values from CSV to Image Collection for Classification

classificationcsvgoogle-earth-enginemulti-bandrandom forest

I am currently working with GEDI data and Random Forest Classification in Google Earth Engine. I have a csv file which contains 42 bands and about 3600 points. My aim is to import this csv into GEE and do the Random Forest Classification and then take the regression map. The problem happened when I tried to run the regression map by ee.Image.classify and error occured Regression: Layer error: Image.select: Pattern 'Blue' did not match any bands.. How could I add the bands value from CSV file to the Image Collection to avoid this error and run the code?
My code is as follow:

var table = ee.FeatureCollection("projects/ee-vietfix14/assets/GEDIdatapoints1");
var training = table.distinct('system:index');
// AOI 
var aoi = ee.Geometry.Polygon(
    [[[-53.727841320713424, 5.4107641852798425],
      [-53.727841320713424, 2.605426055652731],
      [-51.640438976963424, 2.605426055652731],
      [-51.640438976963424, 5.4107641852798425]]], null, false).buffer(1e4);
var heightBand = 'rh99'

Map.addLayer(table)
Map.centerObject(aoi, 12)
////////////////////////////////////////////////////////
var filter = ee.Filter.and(
  ee.Filter.bounds(aoi),
  ee.Filter.date('2019-01-01', '2021-01-01')

  )
var S2composite = ee.ImageCollection(
    ee.Join.saveFirst('cloudProbability').apply({
        primary: ee.ImageCollection('COPERNICUS/S2_SR').filter(filter),
        secondary: ee.ImageCollection('COPERNICUS/S2_CLOUD_PROBABILITY').filter(filter),
        condition: ee.Filter.equals({leftField: 'system:index', rightField: 'system:index'})
    })
  ).map(function (image) {
  var cloudFree = ee.Image(image.get('cloudProbability')).lt(30)
  return image.updateMask(cloudFree).divide(10000)
  })


var bands =['Blue','Green','Red','NIR','SWIR1','SWIR2','NDVI','EVI','NDWI','MSAVI','SAVI','GNDVI','CVI','DVI','NDMI','GRVI','MSR','GSAVI','GARI','GLI','NDGI','NBR','NDII','SWIR1_Ratio_SWIR2','NIR_Ratio_SWIR1', 'RVI','VVdb','VHdb','ratio_VV_VH','RVIpal','HVdb','HHdb','ratio_HV_HH'];
var S2_composite = S2composite.median();
print(S2_composite)
/////////////////////////////////////////////////////////////////////
// Train a random forest classifier for regression 
var classifier = ee.Classifier.smileRandomForest(50)
  .setOutputMode('REGRESSION')
  .train({
    features: training, 
    classProperty: heightBand,
    inputProperties: bands
    });
print(classifier)
var regression = S2_composite.select(bands).classify(classifier, 'predicted').clip(aoi);
// Load and define a continuous palette
var palettes = require('users/gena/packages:palettes');

// Choose and define a palette
var palette = palettes.colorbrewer.YlGn[5];
var viz = {palette: palette, min: 0,max:60};
Map.addLayer(regression, viz, 'Regression'); 

My code link: [https://code.earthengine.google.com/14825f7350139a75d1f02796e3c817a3]

My table: [https://code.earthengine.google.com/?asset=projects/ee-vietfix14/assets/GEDIdatapoints1]

Best Answer

The image you're trying to classify must contain the same bands as the training data used when training the classifier. It doesn't. You have to rename the bands include the indexes in your composite. This should give you an idea, using only a subset of your bands (to same me some time, you'll have to complete this yourself):

var S2composite = ee.ImageCollection(
    ee.Join.saveFirst('cloudProbability')
      .apply({
          primary: ee.ImageCollection('COPERNICUS/S2_SR').filter(filter),
          secondary: ee.ImageCollection('COPERNICUS/S2_CLOUD_PROBABILITY').filter(filter),
          condition: ee.Filter.equals({leftField: 'system:index', rightField: 'system:index'})
      })
    )
    .select(
      ['B2', 'B3', 'B4', 'B8'],
      ['Blue','Green','Red', 'NIR']
    )
    .map(function (image) {
      var cloudFree = ee.Image(image.get('cloudProbability')).lt(30)
      var indexes = ee.Image([
        image.normalizedDifference(['Red', 'NIR']).rename('NDVI')
    ])
    return image
      .addBands(indexes)
      .updateMask(cloudFree).divide(10000)
    })


var bands = ['Blue', 'Green', 'Red', 'NIR', 'NDVI']
Related Question