合成和馬賽克

一般來說,合成是指根據匯總函式,將空間重疊的圖片合併為單一圖片的程序。馬賽克處理是指將圖片資料集以空間方式組合,產生空間連續圖像的程序。在 Earth Engine 中,這兩個詞彙可互通使用,但兩者都支援合成和馬賽克。舉例來說,請考慮在同一個位置合成多張圖片的工作。舉例來說,使用同一張 National Agriculture Imagery Program (NAIP) 數位正射圖四分之一方格 (DOQQ) 在不同時間拍攝的圖像,以下範例說明如何製作最大值組合:

程式碼編輯器 (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');

Python 設定

請參閱「 Python 環境」頁面,瞭解 Python API 和如何使用 geemap 進行互動式開發。

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

請考量同時需要在四個不同位置使用 DOQQ 馬賽克圖案。以下範例說明如何使用 imageCollection.mosaic()

程式碼編輯器 (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');

Python 設定

請參閱「 Python 環境」頁面,瞭解 Python API 和如何使用 geemap 進行互動式開發。

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')

請注意,上例中的 DOQQ 有些重疊。mosaic() 方法會根據集合中的順序 (最後一個在最上方) 合成重疊的圖片。如要控制馬賽克 (或組合) 中的像素來源,請使用圖片遮罩。例如,以下程式碼會使用光譜索引的閾值,遮蓋馬賽克中的圖像資料:

程式碼編輯器 (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');

Python 設定

請參閱「 Python 環境」頁面,瞭解 Python API 和如何使用 geemap 進行互動式開發。

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

如要製作可將輸入內容中任意頻帶最大化的合成影像,請使用 imageCollection.qualityMosaic()qualityMosaic() 方法會根據集合中哪張圖片在指定頻帶中具有最大值,設定合成圖中的每個像素。例如,下列程式碼示範如何製作最綠色像素組合和最近值組合:

程式碼編輯器 (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');

Python 設定

請參閱「 Python 環境」頁面,瞭解 Python API 和如何使用 geemap 進行互動式開發。

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

使用檢查器工具,查看合成的不同位置的像素值。請注意,millis 頻帶 (時間戳記) 會因位置而異,表示不同的像素來自不同時間。