-1

I want to do the following convolution operations on the image: the sum of the absolute values of the difference between each value in the calculation window and the value of the central pixel.

How could I do that in Google earth engine Javascript API?

Thanks a lot !

yu dong
  • 1
  • 1

1 Answers1

0

I believe you can use the .neighborhoodToBands() method on an image to get what you want. I learned this from the Texture page on the Google Earth Engine API tutorial.

First, load an image and select a single band:

// Load a high-resolution NAIP image.
var image = ee.Image('USDA/NAIP/DOQQ/m_3712213_sw_10_1_20140613');

// Zoom to San Francisco, display.
Map.setCenter(-122.466123, 37.769833, 17);
Map.addLayer(image, {max: 255}, 'image');

// Get the NIR band.
var nir = image.select('N');

Then create a kernel:

// Create a list of weights for a 9x9 kernel.
var list = [1, 1, 1, 1, 1, 1, 1, 1, 1];
// The center of the kernel is zero.
var centerList = [1, 1, 1, 1, 0, 1, 1, 1, 1];
// Assemble a list of lists: the 9x9 kernel weights as a 2-D matrix.
var lists = [list, list, list, list, centerList, list, list, list, list];
// Create the kernel from the weights.
// Non-zero weights represent the spatial neighborhood.
var kernel = ee.Kernel.fixed(9, 9, lists, -4, -4, false);

Alternative way to create a kernel... This is a function that I've been using to create a kernel with a 0 weight at the center and with a user-defined radius:

var create_kernel = function(pixel_radius) {
  var pixel_diameter = 2 * pixel_radius + 1;
  var weight_val = 1;
  var weights = ee.List.repeat(ee.List.repeat(weight_val, pixel_diameter), pixel_diameter);

  var mid_row = ee.List.repeat(weight_val, pixel_radius)
    .cat([0])
    .cat(ee.List.repeat(weight_val, pixel_radius));

  weights = weights.set(pixel_radius, mid_row);

  var kernel = ee.Kernel.fixed({
    height: pixel_diameter,
    width: pixel_diameter,
    weights: weights
  });

  return kernel;
};

var kernel = create_kernel(4);

Convert the neighborhood to bands and then perform the calculation:

// Convert the neighborhood into multiple bands.
var neighs = nir.neighborhoodToBands(kernel);
print(neighs);

// Compute convolution; Focal pixel (represented by original nir image)
// Subtract away the 80 bands representing the 80 neighbors
// (9x9 neighborhood = 81 pixels - 1 focal pixel = 80 neighbors)
var convolution = nir.subtract(neighs).abs().reduce(ee.Reducer.sum());
print(convolution);
Map.addLayer(convolution,
             {min: 20, max: 2500, palette: ['0000CC', 'CC0000']},
             "Convolution");

Does this get you what you want?

Here's the link to the GEE code:

mikoontz
  • 592
  • 5
  • 11