Compositing et mosaïque

En général, le compositing désigne le processus de combinaison d'images spatialement superposées en une seule image en fonction d'une fonction d'agrégation. La mosaïque désigne le processus d'assemblage spatial d'ensembles de données d'images pour produire une image spatiale continue. Dans Earth Engine, ces termes sont utilisés de manière interchangeable, bien que la composition et la mosaïque soient toutes deux prises en charge. Prenons l'exemple de la composition de plusieurs images au même endroit. Par exemple, en utilisant un DOQQ (Digital Orthophoto Quarter Quadrangle) du National Agriculture Imagery Program (NAIP) à différents moments, l'exemple suivant montre comment créer un composite de valeurs maximales:

Éditeur de code (JavaScript)

// Load three NAIP quarter quads in the same location, different times.
var naip2004_2012 = ee.ImageCollection('USDA/NAIP/DOQQ')
  .filterBounds(ee.Geometry.Point(-71.08841, 42.39823))
  .filterDate('2004-07-01', '2012-12-31')
  .select(['R', 'G', 'B']);

// Temporally composite the images with a maximum value function.
var composite = naip2004_2012.max();
Map.setCenter(-71.12532, 42.3712, 12);
Map.addLayer(composite, {}, 'max value composite');

Configuration de Python

Consultez la page Environnement Python pour en savoir plus sur l'API Python et l'utilisation de geemap pour le développement interactif.

import ee
import geemap.core as geemap

Colab (Python)

# Load three NAIP quarter quads in the same location, different times.
naip_2004_2012 = (
    ee.ImageCollection('USDA/NAIP/DOQQ')
    .filterBounds(ee.Geometry.Point(-71.08841, 42.39823))
    .filterDate('2004-07-01', '2012-12-31')
    .select(['R', 'G', 'B'])
)

# Temporally composite the images with a maximum value function.
composite = naip_2004_2012.max()
m.set_center(-71.12532, 42.3712, 12)
m.add_layer(composite, {}, 'max value composite')
m

Imaginons que vous deviez créer une mosaïque de quatre DOQQ différents en même temps, mais à des emplacements différents. L'exemple suivant montre que, avec imageCollection.mosaic():

Éditeur de code (JavaScript)

// Load four 2012 NAIP quarter quads, different locations.
var naip2012 = ee.ImageCollection('USDA/NAIP/DOQQ')
  .filterBounds(ee.Geometry.Rectangle(-71.17965, 42.35125, -71.08824, 42.40584))
  .filterDate('2012-01-01', '2012-12-31');

// Spatially mosaic the images in the collection and display.
var mosaic = naip2012.mosaic();
Map.setCenter(-71.12532, 42.3712, 12);
Map.addLayer(mosaic, {}, 'spatial mosaic');

Configuration de Python

Consultez la page Environnement Python pour en savoir plus sur l'API Python et l'utilisation de geemap pour le développement interactif.

import ee
import geemap.core as geemap

Colab (Python)

# Load four 2012 NAIP quarter quads, different locations.
naip_2012 = (
    ee.ImageCollection('USDA/NAIP/DOQQ')
    .filterBounds(
        ee.Geometry.Rectangle(-71.17965, 42.35125, -71.08824, 42.40584)
    )
    .filterDate('2012-01-01', '2012-12-31')
)

# Spatially mosaic the images in the collection and display.
mosaic = naip_2012.mosaic()
m = geemap.Map()
m.set_center(-71.12532, 42.3712, 12)
m.add_layer(mosaic, {}, 'spatial mosaic')

Notez que les DOQQ de l'exemple précédent se chevauchent. La méthode mosaic() compose les images superposées en fonction de leur ordre dans la collection (la dernière en haut). Pour contrôler la source des pixels dans une mosaïque (ou un composite), utilisez des masques d'image. Par exemple, l'exemple suivant utilise des seuils sur les indices spectraux pour masquer les données d'image dans une mosaïque:

Éditeur de code (JavaScript)

// Load a NAIP quarter quad, display.
var naip = ee.Image('USDA/NAIP/DOQQ/m_4207148_nw_19_1_20120710');
Map.setCenter(-71.0915, 42.3443, 14);
Map.addLayer(naip, {}, 'NAIP DOQQ');

// Create the NDVI and NDWI spectral indices.
var ndvi = naip.normalizedDifference(['N', 'R']);
var ndwi = naip.normalizedDifference(['G', 'N']);

// Create some binary images from thresholds on the indices.
// This threshold is designed to detect bare land.
var bare1 = ndvi.lt(0.2).and(ndwi.lt(0.3));
// This detects bare land with lower sensitivity. It also detects shadows.
var bare2 = ndvi.lt(0.2).and(ndwi.lt(0.8));

// Define visualization parameters for the spectral indices.
var ndviViz = {min: -1, max: 1, palette: ['FF0000', '00FF00']};
var ndwiViz = {min: 0.5, max: 1, palette: ['00FFFF', '0000FF']};

// Mask and mosaic visualization images.  The last layer is on top.
var mosaic = ee.ImageCollection([
  // NDWI > 0.5 is water.  Visualize it with a blue palette.
  ndwi.updateMask(ndwi.gte(0.5)).visualize(ndwiViz),
  // NDVI > 0.2 is vegetation.  Visualize it with a green palette.
  ndvi.updateMask(ndvi.gte(0.2)).visualize(ndviViz),
  // Visualize bare areas with shadow (bare2 but not bare1) as gray.
  bare2.updateMask(bare2.and(bare1.not())).visualize({palette: ['AAAAAA']}),
  // Visualize the other bare areas as white.
  bare1.updateMask(bare1).visualize({palette: ['FFFFFF']}),
]).mosaic();
Map.addLayer(mosaic, {}, 'Visualization mosaic');

Configuration de Python

Consultez la page Environnement Python pour en savoir plus sur l'API Python et l'utilisation de geemap pour le développement interactif.

import ee
import geemap.core as geemap

Colab (Python)

# Load a NAIP quarter quad, display.
naip = ee.Image('USDA/NAIP/DOQQ/m_4207148_nw_19_1_20120710')
m = geemap.Map()
m.set_center(-71.0915, 42.3443, 14)
m.add_layer(naip, {}, 'NAIP DOQQ')

# Create the NDVI and NDWI spectral indices.
ndvi = naip.normalizedDifference(['N', 'R'])
ndwi = naip.normalizedDifference(['G', 'N'])

# Create some binary images from thresholds on the indices.
# This threshold is designed to detect bare land.
bare_1 = ndvi.lt(0.2).And(ndwi.lt(0.3))
# This detects bare land with lower sensitivity. It also detects shadows.
bare_2 = ndvi.lt(0.2).And(ndwi.lt(0.8))

# Mask and mosaic visualization images. The last layer is on top.
mosaic = ee.ImageCollection([
    # NDWI > 0.5 is water. Visualize it with a blue palette.
    ndwi.updateMask(ndwi.gte(0.5)).visualize(
        min=0.5, max=1, palette=['00FFFF', '0000FF']
    ),
    # NDVI > 0.2 is vegetation. Visualize it with a green palette.
    ndvi.updateMask(ndvi.gte(0.2)).visualize(
        min=-1, max=1, palette=['FF0000', '00FF00']
    ),
    # Visualize bare areas with shadow (bare_2 but not bare_1) as gray.
    bare_2.updateMask(bare_2.And(bare_1.Not())).visualize(palette=['AAAAAA']),
    # Visualize the other bare areas as white.
    bare_1.updateMask(bare_1).visualize(palette=['FFFFFF']),
]).mosaic()
m.add_layer(mosaic, {}, 'Visualization mosaic')
m

Pour créer un composite qui maximise une bande arbitraire dans l'entrée, utilisez imageCollection.qualityMosaic(). La méthode qualityMosaic() définit chaque pixel du composite en fonction de l'image de la collection qui a une valeur maximale pour la bande spécifiée. Par exemple, le code suivant montre comment créer un composite de pixels les plus verts et un composite de valeurs récentes:

Éditeur de code (JavaScript)

// Define a function that scales and masks Landsat 8 surface reflectance images.
function prepSrL8(image) {
  // Develop masks for unwanted pixels (fill, cloud, cloud shadow).
  var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);
  var saturationMask = image.select('QA_RADSAT').eq(0);

  // Apply the scaling factors to the appropriate bands.
  var getFactorImg = function(factorNames) {
    var factorList = image.toDictionary().select(factorNames).values();
    return ee.Image.constant(factorList);
  };
  var scaleImg = getFactorImg([
    'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']);
  var offsetImg = getFactorImg([
    'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']);
  var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg);

  // Replace original bands with scaled bands and apply masks.
  return image.addBands(scaled, null, true)
    .updateMask(qaMask).updateMask(saturationMask);
}

// This function masks clouds and adds quality bands to Landsat 8 images.
var addQualityBands = function(image) {
  // Normalized difference vegetation index.
  var ndvi = image.normalizedDifference(['SR_B5', 'SR_B4']);
  // Image timestamp as milliseconds since Unix epoch.
  var millis = ee.Image(image.getNumber('system:time_start'))
                   .rename('millis').toFloat();
  return prepSrL8(image).addBands([ndvi, millis]);
};

// Load a 2014 Landsat 8 ImageCollection.
// Map the cloud masking and quality band function over the collection.
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
  .filterDate('2014-06-01', '2014-12-31')
  .map(addQualityBands);

// Create a cloud-free, most recent value composite.
var recentValueComposite = collection.qualityMosaic('millis');

// Create a greenest pixel composite.
var greenestPixelComposite = collection.qualityMosaic('nd');

// Display the results.
Map.setCenter(-122.374, 37.8239, 12); // San Francisco Bay
var vizParams = {bands: ['SR_B5', 'SR_B4', 'SR_B3'], min: 0, max: 0.4};
Map.addLayer(recentValueComposite, vizParams, 'Recent value composite');
Map.addLayer(greenestPixelComposite, vizParams, 'Greenest pixel composite');

// Compare to a cloudy image in the collection.
var cloudy = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140825');
Map.addLayer(cloudy, {bands: ['B5', 'B4', 'B3'], min: 0, max: 0.4}, 'Cloudy');

Configuration de Python

Consultez la page Environnement Python pour en savoir plus sur l'API Python et l'utilisation de geemap pour le développement interactif.

import ee
import geemap.core as geemap

Colab (Python)

# Define a function that scales and masks Landsat 8 surface reflectance images.
def prep_sr_l8(image):
  # Develop masks for unwanted pixels (fill, cloud, cloud shadow).
  qa_mask = image.select('QA_PIXEL').bitwiseAnd(int('11111', 2)).eq(0)
  saturation_mask = image.select('QA_RADSAT').eq(0)

  # Helper function to create image from scaling factors.
  def get_factor_img(factor_names):
    factor_list = image.toDictionary().select(factor_names).values()
    return ee.Image.constant(factor_list)

  # Apply the scaling factors to the appropriate bands.
  scale_img = get_factor_img(
      ['REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']
  )
  offset_img = get_factor_img(
      ['REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']
  )
  scaled = image.select('SR_B.|ST_B10').multiply(scale_img).add(offset_img)

  # Replace original bands with scaled bands and apply masks.
  return (
      image.addBands(scaled, None, True)
      .updateMask(qa_mask)
      .updateMask(saturation_mask)
  )


# This function masks clouds and adds quality bands to Landsat 8 images.
def add_quality_bands(image):
  # Normalized difference vegetation index.
  ndvi = image.normalizedDifference(['SR_B5', 'SR_B4'])
  # Image timestamp as milliseconds since Unix epoch.
  millis = (
      ee.Image(image.getNumber('system:time_start')).rename('millis').toFloat()
  )
  return prep_sr_l8(image).addBands([ndvi, millis])


# Load a 2014 Landsat 8 ImageCollection.
# Map the cloud masking and quality band function over the collection.
collection = (
    ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
    .filterDate('2014-06-01', '2014-12-31')
    .map(add_quality_bands)
)

# Create a cloud-free, most recent value composite.
recent_value_composite = collection.qualityMosaic('millis')

# Create a greenest pixel composite.
greenest_pixel_composite = collection.qualityMosaic('nd')

# Display the results.
m = geemap.Map()
m.set_center(-122.374, 37.8239, 12)  # San Francisco Bay
viz_params = {'bands': ['SR_B5', 'SR_B4', 'SR_B3'], 'min': 0, 'max': 0.4}
m.add_layer(recent_value_composite, viz_params, 'Recent value composite')
m.add_layer(greenest_pixel_composite, viz_params, 'Greenest pixel composite')

# Compare to a cloudy image in the collection.
cloudy = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140825')
m.add_layer(
    cloudy, {'bands': ['B5', 'B4', 'B3'], 'min': 0, 'max': 0.4}, 'Cloudy'
)
m

Utilisez l'outil d'inspection pour vérifier les valeurs de pixel à différents endroits des composites. Notez que la bande millis (code temporel) varie en fonction de l'emplacement, ce qui indique que les différents pixels proviennent de différentes périodes.