Google Earth Engine – How to Create a Buffer Around Canny Edges

buffergoogle-earth-enginemultipoint

In google earth engine I've managed to create a layer using the canny edge detection algorithm (which outputs an image). That layer takes on values of 0 or 1. Now I want to create a buffer around those edges.

My first thought was to find the pixel values in the image that have value of 1 and then use the coordinates to make a multi-point, and then apply the buffer to that layer. Unfortunately though I'm stuck at the first step of finding the coordinates of the pixels that have the corresponding value.

Here's my basic code for reproduction, note the bottom two lines will throw an error but I'm not sure how to achieve it.

// Create a geometry representing an export region
var geometry = /* color: #0b4a8b */ee.Geometry.Polygon(
        [[[62.942261953123534, 33.91959535929101],
          [62.931275624998534, 33.47629096859868],
          [63.870606679686034, 33.45337831094604],
          [64.00244261718603, 33.9742779426479]]]);

//To view exactly where
Map.centerObject(geometry,10);  
Map.addLayer(geometry, {color: 'FF0000'}, 'geodesic polygon');

// Load Landsat 5 data, filter by date and bounds.
var collection = ee.ImageCollection("LANDSAT/LE07/C01/T1")
  .filterDate('2003-01-01', '2003-05-01')
  .filterBounds(geometry);

// Also filter the collection by the IMAGE_QUALITY property.
var filtered = collection
  .filterMetadata('IMAGE_QUALITY', 'equals', 9);

// Create two composites to check the effect of filtering by IMAGE_QUALITY.
var goodComposite = ee.Algorithms.Landsat.simpleComposite(filtered, 75, 3);

// Add PC band
var Panchromatic = goodComposite.select(['B8']);
Map.addLayer(Panchromatic,
             {gain: 1.5},
             'Panchromatic');

//////////////////////////Edge Detection///////////////////////

// Detect edges in the panchromatic composite.
var canny = ee.Algorithms.CannyEdgeDetector(Panchromatic, 12, 2);

// Mask the image with itself to get rid of areas with no edges.
canny = canny.updateMask(canny);
Map.addLayer(canny, {min: 0, max: 1, palette: 'FF0000'}, 'CE Pan');

// definitely doesn't work
var canny_1 = (canny == 1).get(position); 
Map.addLayer(canny_1);

Best Answer

The easiest approach will be to keep the edges as an image and use a focal_max() with a given pixel window to buffer the edges. Here is working code with your example:

Map.addLayer(geometry, {color: 'FF0000'}, 'geodesic polygon');

// Load Landsat 5 data, filter by date and bounds.
var collection = ee.ImageCollection("LANDSAT/LE07/C01/T1")
  .filterDate('2003-01-01', '2003-05-01')
  .filterBounds(geometry);

// Also filter the collection by the IMAGE_QUALITY property.
var filtered = collection
  .filterMetadata('IMAGE_QUALITY', 'equals', 9);

// Create two composites to check the effect of filtering by IMAGE_QUALITY.
var goodComposite = ee.Algorithms.Landsat.simpleComposite(filtered, 75, 3);

// Add PC band
var Panchromatic = goodComposite.select(['B8']);
Map.addLayer(Panchromatic,
             {gain: 1.5},
             'Panchromatic');

//////////////////////////Edge Detection///////////////////////

// Detect edges in the panchromatic composite.
var canny = ee.Algorithms.CannyEdgeDetector(Panchromatic, 12, 2);

// Mask the image with itself to get rid of areas with no edges.
canny = canny.updateMask(canny);
Map.addLayer(canny, {min: 0, max: 1, palette: 'FF0000'}, 'CE Pan');

// working example
var bufferSize = 30 // in meters
var edgeBuffer = canny.focal_max(bufferSize, 'square', 'meters'); 
Map.addLayer(edgeBuffer.updateMask(edgeBuffer),{},'Buffered Edges');

And here is the link. Hope this helps!

Related Question