2

I am trying to sample points from a classified raster using Google Earth Engine, but am running into some problems. I developed a script based on the Classification video located here.

Here is a toy script that attempts to randomly sample a stratified raster.

var ROI = ee.Geometry.Rectangle(-82.562342, 35.589551,-82.562342, 35.589551); // define area

var features = [
    ee.Feature(ee.Geometry.Rectangle(-82.56123, 35.59053,-82.55213, 35.59674),{class: 0}),
    ee.Feature(ee.Geometry.Rectangle(-82.54245, 35.591453, -82.537172, 35.596496),{class:1})
];

var vect = ee.FeatureCollection(features);
print(vect);
Map.addLayer(vect);

var image = vect
  .filter(ee.Filter.neq('class', null))
  .reduceToImage({
    properties: ['class'],
    reducer: ee.Reducer.first()
});

Map.addLayer(image,{min:0,max:1,palette: ['black','white']});

var counts = {
  0:1000,
  1:1000,
};

print(counts)

var stratified = ee.Dictionary(counts)
    .map(function(klass,count) {
    klass = ee.Number.parse(klass)
    var masked = image.updateMask(image.eq(klass))
    return masked.addBands(ee.Image.pixelLonLat())
        .sample({
          region: ROI, 
          numPixels: 5000, 
          seed: klass})
        .randomColumn('x')
        .sort('x')
        .limit(ee.Number(count).min(100))
        .map(function(f) {
            var location = ee.Geometry.Point([f.get('longitude'),f.get('latitude')])
            return ee.Feature(location,f.toDictionary())
            })
    }).values()

stratified = ee.FeatureCollection(stratified).flatten(); 

print (stratified.reduceColumns(ee.Reducer.frequencyHistogram(),['Class']));
Map.addLayer(stratified);
print(stratified)

Unfortunately, I receive the error message: The default WGS84 projection is invalid for aggregations. Specify a scale or crs & crs_transform.

This error is mentioned on the projections page, but, doesn't offer any real solutions. Does anyone know how to aggregate using the aerial imagery in WGS84 on Google Earth Engine?

2

Why aren't you just using the stratifiedSample algorithm? https://code.earthengine.google.com/e061f92736d8261f812db1dc2bfa8934

var ROI = ee.Geometry.Rectangle(-82.56277, 35.58935,-82.53436, 35.59996); // define area

var features = ee.FeatureCollection([
    ee.Feature(ee.Geometry.Rectangle(-82.56123, 35.59053,-82.55213, 35.59674),{class: 0}),
    ee.Feature(ee.Geometry.Rectangle(-82.54245, 35.591453, -82.537172, 35.596496),{class:1})
])

var classes = ee.Image().byte().paint(features, "class").rename("class")

Map.centerObject(ROI);
Map.addLayer(classes,{min:0,max:1,palette: ['grey','white']});

var stratified = classes.addBands(ee.Image.pixelLonLat())
    .stratifiedSample({
      numPoints: 1000,
      classBand: 'class',
      projection: 'EPSG:3665',
      scale: 10,
      region: features.geometry()
    }).map(function(f) {
      return f.setGeometry(ee.Geometry.Point([f.get('longitude'), f.get('latitude')]))
    })

print (stratified.reduceColumns(ee.Reducer.frequencyHistogram(),['class']));
Map.addLayer(stratified);
  • Thanks. I didn't know about the stratified Sample algorithm. I developed the code that I submitted based on the great video that you put together. – user44796 Mar 16 '18 at 20:02
1

I was able to edit the above script and get it to work by reprojecting the image, even though Google told me not to do it.

var ROI = ee.Geometry.Rectangle(-82.56277, 35.58935,-82.53436, 35.59996); // define area

var features = [
    ee.Feature(ee.Geometry.Rectangle(-82.56123, 35.59053,-82.55213, 35.59674),{class: 0}),
    ee.Feature(ee.Geometry.Rectangle(-82.54245, 35.591453, -82.537172, 35.596496),{class:1})
];

var vect = ee.FeatureCollection(features);

var image_orig = vect
  .filter(ee.Filter.neq('class', null))
  .reduceToImage({
    properties: ['class'],
    reducer: ee.Reducer.first()
});

var image = image_orig.reproject('EPSG: 3665').clip(ROI); //reproject to UTM
print('Band names: ', image.bandNames()); // ee.List of band names
Map.centerObject(ROI);
Map.addLayer(image,{min:0,max:1,palette: ['grey','white']});

/*
var counts = image.reduceRegion(ee.Reducer.frequencyHistogram().unweighted())
    .get('first');
*/

var counts = {
  0:1000,
  1:1000,
};

print(counts)

var stratified = ee.Dictionary(counts)
    .map(function(klass,count) {
    klass = ee.Number.parse(klass)
    var masked = image.updateMask(image.eq(klass))
    return masked.addBands(ee.Image.pixelLonLat())
        .sample({
          region: ROI, 
          numPixels: 5000, 
          seed: klass})
        .randomColumn('x')
        .sort('x')
        .limit(ee.Number(count).min(100))
        .map(function(f) {
            var location = ee.Geometry.Point([f.get('longitude'),f.get('latitude')])
            return ee.Feature(location,f.toDictionary())
            })
    }).values()

stratified = ee.FeatureCollection(stratified).flatten(); 
print (stratified.reduceColumns(ee.Reducer.frequencyHistogram(),['first']));
Map.addLayer(stratified);

The creation of the counts object that is commented out is because GEE does not like the null key in the dictionary, and I don't know how to remove the null key in the dictionary. If anyone knows how to do this, please share.

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.