TransWikia.com

Is Google Earth Engine SNIC Segmentation algorithm inconsistent?

Geographic Information Systems Asked by Wakeme UpNow on May 14, 2021

I have been using GEE for about a month now and I ran into some issue

I am trying to use OBIA classification based on this presentation by Sai Cheemalapati, EEAI 2019.

The main problem is when I perform SNIC algorithm on sattlite image, everytime I change scale, it recalculate and give me a new result. I tested my hypothesis that SNIC is sensitive to scale by exporting region in 2 scales. And to my surprise, both image did show inconsistency (large area segmentation on scale of 10 vs small area segmentation on scale of 2)

Is it possible to specify scale to make SNIC algorithm segmentation on that scale only?

Is this a bug?

Or I am missing something in the documentation, and if so can you advise?

Example Image

scale of 2 export
SNIC with scale size 2

enter image description here
SNIC with scale size 10

The simplified demo code can be found here

var S2 = ee.ImageCollection("COPERNICUS/S2_SR"),
    ROI = ee.Geometry.Polygon(
        [[[10.093076096894833, 55.45897533022183],
          [10.093076096894833, 55.407161055045385],
          [10.231778489472958, 55.407161055045385],
          [10.231778489472958, 55.45897533022183]]], null, false);

// Prepare Image
function maskS2clouds(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

  return image.updateMask(mask).divide(10000);
}

var image = S2
  .filterDate("2019-03-01", "2019-04-01")
  .filterBounds(ROI)
  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 80))
  .map(maskS2clouds)
  .median()
  .clip(ROI)

// Prepare SNIC
var kernel = ee.Kernel.gaussian(3);
image = image.convolve(kernel);

var seeds = ee.Algorithms.Image.Segmentation.seedGrid(36);
var snic = ee.Algorithms.Image.Segmentation.SNIC({
  image: image,
  compactness: 0,
  connectivity: 8,
  neighborhoodSize: 64,
  size: 3,
  seeds: seeds
});

// Visualize
Map.addLayer(image, {
  bands: ["B4", "B3", "B2"],
  min: 0,
  max: 0.255
}, "RGB")
// Map.addLayer(snic.randomVisualizer(), null, "snic")

// // Run this on 1st time
// Export
Export.image.toAsset({
  image: snic.select(["clusters"]),
  description: "cluster_scale-10",
  assetId: "cluster_scale-10",
  region: ROI,
  scale: 10,
  maxPixels: 1e13
})
Export.image.toAsset({
  image: snic.select(["clusters"]),
  description: "cluster_scale-2",
  assetId: "cluster_scale-2",
  region: ROI,
  scale: 2,
  maxPixels: 1e13
})

// // For other time
// var user = "your-user-name"
// var snic_s_2 = ee.Image("users/" + user + "/cluster_scale-2");
// var snic_s_10 = ee.Image("users/" + user + "/cluster_scale-10");

// Map.addLayer(snic_s_2.randomVisualizer(), null, "SNIC 2 m")
// Map.addLayer(snic_s_10.randomVisualizer(), null, "SNIC 10 m")

One Answer

I just found out that there exists a reproject method in ee.Image. So when I change my code to the following, the result image is consistent

var snic = ee.Algorithms.Image.Segmentation.SNIC({
  image: image,
  compactness: 0,
  connectivity: 8,
  neighborhoodSize: 64,
  size: 3,
  seeds: seeds
}).reproject({
  crs: 'EPSG:4326',
  scale: 5
});

Correct answer by Wakeme UpNow on May 14, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP