Google Earth Engine Sentinel Collocation – Fixing Errors When Collocating Sentinel 2 and Sentinel 1 Imageries

google-earth-enginesarsentinel

I am trying to collocate Sentinel 1 and Sentinel 2 images for supervised classification in Google Earth Engine. Synergistic use of optical and SAR images. I am trying this code:

// Load Sentinel-1 and Sentinel-2 Image Collections
var sentinel1Collection = ee.ImageCollection('COPERNICUS/S1_GRD');
var sentinel2Collection = ee.ImageCollection('COPERNICUS/S2');

// Define the study area (e.g., a region of interest)
var studyArea = ee.Geometry.Polygon(
  [[[-80.0, -2.0],
    [-80.0, 2.0],
    [-70.0, 2.0],
    [-70.0, -2.0]]]);

// Filter Sentinel-1 collection for the study area and time range
var sentinel1Filtered = sentinel1Collection
  .filterBounds(studyArea)
  .filterDate('2019-01-01', '2019-12-31');

// Filter Sentinel-2 collection for the study area and time range
var sentinel2Filtered = sentinel2Collection
  .filterBounds(studyArea)
  .filterDate('2019-01-01', '2019-12-31')
  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 5));

// Define a function to collocate Sentinel-1 and Sentinel-2 images
var collocateImages = function(image) {
  var date = image.date();
  
  // Filter Sentinel-1 collection for the specific date
  var sentinel1Image = sentinel1Filtered
    .filterDate(date, date.advance(1, 'day'))
    .first();
  
  // Return null if no Sentinel-1 image is found for the date
  if (sentinel1Image === null) {
    return null;
  }
  
  // Collocate the two images using the closest in time principle
  var collocatedImage = image.addBands(sentinel1Image.select(['VV', 'VH']), null, true);
  
  return collocatedImage.copyProperties(sentinel1Image); // Copy properties from the Sentinel-1 image
};

// Map over the Sentinel-2 images and collocate with Sentinel-1
var collocatedImages = sentinel2Filtered.map(collocateImages);

// Function to create a composite from a collocated image
var createComposite = function(collocatedImage) {
  // Select bands from Sentinel-2 and Sentinel-1 images
  var s2Bands = collocatedImage.select(['B2', 'B3']); // Select Sentinel-2 bands B2 and B3
  var s1Bands = collocatedImage.select(['VV', 'VH']); // Select Sentinel-1 bands VV and VH
  
  // Calculate the band ratio of VV and VH from Sentinel-1 image
  var vvRatioVH = s1Bands.select('VV').divide(s1Bands.select('VH'));
  
  // Create a composite by blending Sentinel-2 bands, Sentinel-1 band ratio, and VH band
  var composite = ee.Image.cat([s2Bands, vvRatioVH, s1Bands.select('VH')]);
  
  return composite.copyProperties(collocatedImage); // Copy properties from the original collocated image
};

// Map over the collocated images and create composites
var composites = collocatedImages.map(createComposite);

// Export the collocated image as an Earth Engine asset
var assetId = 'users/your_username/path_to_asset/collocated_composite'; // Update with your own asset path
Export.image.toAsset({
  image: ee.Image(composites.first()), // Export the first composite as an example
  description: 'Collocated_Composite_Export',
  assetId: assetId,
  scale: 10, // Adjust the scale as needed
  maxPixels: 1e9 // Adjust the maximum number of pixels as needed
});

// Print a message to confirm the export task
print('Exporting collocated image to asset: ' + assetId);

// Display an example composite on the map
var exampleComposite = ee.Image(composites.first()); // Select the first composite as an example
Map.addLayer(exampleComposite, {bands: ['B2', 'B3', 'VV', 'VH'], max: 3000}, 'Example Composite');
Map.centerObject(studyArea, 8); // Center the map on the study area

// Print the resulting collocated image collection
print('Collocated Images:', collocatedImages);

// Print the resulting composites
print('Composites:', composites);

However, it shows the error:

Collocated Images: ImageCollection (Error) Error in
map(ID=20190123T150719_20190123T150955_T18NZG): Image.select:
Parameter 'input' is required. Composites: ImageCollection (Error)
Error in map(ID=20190123T150719_20190123T150955_T18NZG): Image.select:
Parameter 'input' is required. Example Composite: Layer error:
Image.visualize: Must specify between 1 and 3 bands to visualize.

What can I do?

Best Answer

The issue is produced because you are using following lines in collocateImages function.

// Return null if no Sentinel-1 image is found for the date
  if (sentinel1Image === null) {
    return null;
  }

You have to use GEE methods as follows.

// Define a function to collocate Sentinel-1 and Sentinel-2 images
var collocateImages = function(image) {
  var date = ee.Image(image).date();
  
  // Filter Sentinel-1 collection for the specific date
  var sentinel1Image = sentinel1Filtered
    .filterDate(date, date.advance(1, 'day'))
    .first();
  
  // Collocate the two images using the closest in time principle
  var collocatedImage = ee.Image(image).addBands(sentinel1Image.select(['VV', 'VH']))
                                       .copyProperties(sentinel1Image); // Copy properties from the Sentinel-1 image
  
  return ee.Algorithms.If(sentinel1Image, collocatedImage, 0); 

};

// Map over the Sentinel-2 images and collocate with Sentinel-1
var collocatedImages = ee.ImageCollection(sentinel2Filtered.toList(sentinel2Filtered.size())
                                        .map(collocateImages)
                                        .removeAll([0]));

After running the complete code at GEE code editor, I got the result of following picture without any error.

enter image description here