Does anyone have a good way to pansharpen an entire mosaic of landsat 8 images? I would use the Panchromatic band (band 8). I have found tutorials on how to pansharpen a single image, but not for a mosaic (or, essentially, an entire ImageCollection).Preferably, I would carry this out in Google Earth Engine.


You can mosaic a collection of pan-sharpened images as follows:

// Function to mask clouds using the quality band of Landsat 8.
var maskL8 = function(image) {
  var qa = image.select('BQA');
  /// Check that the cloud bit is off.
  // See https://landsat.usgs.gov/collectionqualityband
  var mask = qa.bitwiseAnd(1 << 4).eq(0);
  return image.updateMask(mask);

// HSV-based Pan-Sharpening of Landsat 8 TOA images.
var panSharpenL8 = function(image) {
  var rgb = image.select('B4', 'B3', 'B2');
  var pan = image.select('B8');
  // Convert to HSV, swap in the pan band, and convert back to RGB.
  var huesat = rgb.rgbToHsv().select('hue', 'saturation');
  var upres = ee.Image.cat(huesat, pan).hsvToRgb();
  return image.addBands(upres);

// Map the function over one year of Landsat 8 TOA data and take the median.
var composite = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
    .filterDate('2016-01-01', '2016-12-31')

// There are many fine places to look; here is one.  Comment
// this out if you want to twiddle knobs while panning around.
Map.setCenter(-59.61577, 6.80943, 15);

// Display before and after layers using the same vis parameters.
Map.addLayer(composite, {bands:['B4', 'B3', 'B2'], max: 0.3}, 'Original');
Map.addLayer(composite, {bands:['red','green','blue'], max: 0.3}, 'Pansharpened');

Code link: https://code.earthengine.google.com/269648d7ecc77d2491e3b3513f7ed3f4

Note that the preceding code is a combination of the CloudMasking/Landsat8TOAReflectanceQABand.js and Image/HSVPanSharpening.js examples.

While you could apply the panSharpen function to a previously mosaicked image and get results, that approach does not make physical sense to me because the high and low spatial resolution data in the mosaic might have been collected at different times/dates.


Here's a variant that you may find useful/different (continuing Tyler's example):

var pansharpen1 = function(scene, kernel) {
  // Compute the per-pixel means of the unsharpened bands.
  var bgr = scene.select(['B4', 'B3', 'B2']);
  var pan = scene.select('B8');
  var bgr_mean = bgr.reduce('mean').rename('mean');
  // Compute the aggregate mean of the unsharpened bands and the pan band.
  var mean_values = pan.addBands(bgr_mean).reduceNeighborhood({
    reducer: ee.Reducer.mean(), 
    kernel: kernel,
  var gain = mean_values.select('mean_mean').divide(mean_values.select('B8_mean'));
  return bgr.divide(bgr_mean).multiply(pan).multiply(gain);

var kernel = ee.Kernel.square({
  radius: 90, 
  units: 'meters'

var sharp1 = pansharpen1(composite, kernel);
Map.addLayer(sharp1, {bands: ['B4', 'B3', 'B2'], max: 0.3}, 'sharp1');

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.