如何在Google Earth Engine JavaScript API中实现差值绝对值之和的图像卷积
Great question! Calculating the sum of absolute differences (SAD) between each pixel in a convolution window and the central pixel is a common image processing task, and it’s totally achievable in Google Earth Engine’s JavaScript API. Let’s walk through two reliable approaches to get this done.
Approach 1: Using reduceNeighborhood with Custom Reducer
This method is flexible for any arbitrary kernel shape (not just square windows) and works by processing each pixel’s neighborhood as a list of values, then computing the SAD directly.
Step-by-Step Code
// 1. Load your input image (single-band example here) var inputImg = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20200601').select('B4'); // 2. Define your convolution window (3x3 square window, radius = 1 pixel) var kernel = ee.Kernel.square({ radius: 1, units: 'pixels', normalize: false // We don't want to normalize values }); // 3. Create a custom reducer to calculate SAD var sadReducer = ee.Reducer.toList().map({ inputNames: ['list'], outputNames: ['sad'], function: function(pixelList) { // Get the central pixel value (for 3x3 window, index 4 is the center) var centerVal = ee.List(pixelList).get(4); // Calculate absolute difference between each window pixel and center var absDiffs = ee.List(pixelList).map(function(pixelVal) { return ee.Number(pixelVal).subtract(centerVal).abs(); }); // Sum all absolute differences return absDiffs.reduce(ee.Reducer.sum()); } }); // 4. Apply the reducer to the image var sadResult = inputImg.reduceNeighborhood({ reducer: sadReducer, kernel: kernel }); // 5. Visualize the result (optional) Map.addLayer(sadResult, {min: 0, max: 10}, 'SAD Result (3x3 Window)');
Notes
- For non-square windows (e.g., circular), adjust the
kernel(likeee.Kernel.circle()) and update the central pixel index. For a window with N total pixels, the center index isMath.floor(N/2). - To use this with multi-band images, wrap the logic in a
map()call over the image’s bands.
Approach 2: Image Translation + Summation (More Efficient)
If you’re working with regular square/rectangular windows, this method leverages GEE’s optimized image operations for better performance. The idea is to shift the image in every direction of the window, compute absolute differences with the original image, then sum all those difference images.
Step-by-Step Code
// 1. Load your input image var inputImg = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20200601').select('B4'); // 2. Define all pixel offsets for a 3x3 window (center included) var windowOffsets = [ [-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 0], [0, 1], [1, -1], [1, 0], [1, 1] ]; // 3. Generate absolute difference images for each offset var absDiffCollection = ee.ImageCollection(windowOffsets.map(function(offset) { var dx = offset[0]; var dy = offset[1]; // Shift the image by the offset, subtract original, take absolute value return inputImg.translate(dx, dy).subtract(inputImg).abs(); })); // 4. Sum all difference images to get the total SAD var sadResult = absDiffCollection.sum(); // 5. Visualize (optional) Map.addLayer(sadResult, {min: 0, max: 10}, 'SAD Result (Translation Method)');
Notes
- This method is faster for large images because it uses vectorized image operations instead of list processing.
- To adjust window size (e.g., 5x5), generate all corresponding (dx, dy) offsets for the window. For a window of size
(2r+1)x(2r+1)(r = radius), offsets range from-rtorfor both x and y. - For multi-band images, use
inputImg.map()to apply the logic to each band individually.
Which Approach to Choose?
- Use Approach 1 if you need non-regular window shapes (circular, custom polygons) or want more control over neighborhood processing.
- Use Approach 2 for standard square/rectangular windows—it’s more efficient and easier to read for simple cases.
内容的提问来源于stack exchange,提问作者yu dong

