0

I'm working with Sentinel-1 data in GEE and exporting the filtered VH and VV polarization channels images in the end. But this always gives me an error

Error: Image.clipToBoundsAndScale, argument 'input': Invalid type. Expected type: Image. Actual type: ImageCollection.

My GEE code is described below - why is this error occurring?

// Load Sentinel-1 C-band SAR Ground Range collection (log scale, VV, descending)
   var collectionVV = ee.ImageCollection('COPERNICUS/S1_GRD')
   .filter(ee.Filter.eq('instrumentMode', 'IW'))
   .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
   .filter(ee.Filter.eq('orbitProperties_pass', 'ASCENDING')) .filterMetadata('resolution_meters',
   'equals' , 10)
   .filterDate('2016-10-01', '2016-10-05')
   .filterBounds(roi)
   .select('VV');
    print(collectionVV, 'Collection VV'); 

  // Load Sentinel-1 C-band SAR Ground Range collection (log scale, VH, descending)
  var collectionVH = ee.ImageCollection('COPERNICUS/S1_GRD')
  .filter(ee.Filter.eq('instrumentMode', 'IW'))
  .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
 .filter(ee.Filter.eq('orbitProperties_pass', 'ASCENDING'))
 .filterMetadata('resolution_meters', 'equals' , 10)
 .filterDate('2016-10-01', '2016-10-05')
 .filterBounds(roi)
 .select('VH');
 print(collectionVH, 'Collection VH');

 Map.addLayer(collectionVV, {min:-15,max:0}, '2016 VV', 0);
Map.addLayer(collectionVH, {min:-30,max:0}, '2016 VH', 0);


/////////////////////////////////////////////////////////////////////////////////
//Function to convert from dB
function toNatural(img) {
return ee.Image(10.0).pow(img.select(0).divide(10.0));
}
//Function to convert to dB
function toDB(img) {
return ee.Image(img).log10().multiply(10.0);
}

function RefinedLee(img) {
// img must be in natural units, i.e. not in dB!
// Set up 3x3 kernels

// convert to natural.. do not apply function on dB!
var myimg = toNatural(img);

var weights3 = ee.List.repeat(ee.List.repeat(1,3),3);
var kernel3 = ee.Kernel.fixed(3,3, weights3, 1, 1, false);

var mean3 = myimg.reduceNeighborhood(ee.Reducer.mean(), kernel3);
var variance3 = myimg.reduceNeighborhood(ee.Reducer.variance(), kernel3);

// Use a sample of the 3x3 windows inside a 7x7 windows to determine gradients and directions
var sample_weights = ee.List([[0,0,0,0,0,0,0], [0,1,0,1,0,1,0],[0,0,0,0,0,0,0], [0,1,0,1,0,1,0], [0,0,0,0,0,0,0], [0,1,0,1,0,1,0],[0,0,0,0,0,0,0]]);

var sample_kernel = ee.Kernel.fixed(7,7, sample_weights, 3,3, false);

// Calculate mean and variance for the sampled windows and store as 9 bands
var sample_mean = mean3.neighborhoodToBands(sample_kernel);
var sample_var = variance3.neighborhoodToBands(sample_kernel);

// Determine the 4 gradients for the sampled windows
var gradients = sample_mean.select(1).subtract(sample_mean.select(7)).abs();
gradients = gradients.addBands(sample_mean.select(6).subtract(sample_mean.select(2)).abs());
gradients = gradients.addBands(sample_mean.select(3).subtract(sample_mean.select(5)).abs());
gradients = gradients.addBands(sample_mean.select(0).subtract(sample_mean.select(8)).abs());

// And find the maximum gradient amongst gradient bands
var max_gradient = gradients.reduce(ee.Reducer.max());

// Create a mask for band pixels that are the maximum gradient
var gradmask = gradients.eq(max_gradient);

// duplicate gradmask bands: each gradient represents 2 directions
gradmask = gradmask.addBands(gradmask);

// Determine the 8 directions
var directions = sample_mean.select(1).subtract(sample_mean.select(4)).gt(sample_mean.select(4).subtract(sample_mean.select(7))).multiply(1);
directions = directions.addBands(sample_mean.select(6).subtract(sample_mean.select(4)).gt(sample_mean.select(4).subtract(sample_mean.select(2))).multiply(2));
directions = directions.addBands(sample_mean.select(3).subtract(sample_mean.select(4)).gt(sample_mean.select(4).subtract(sample_mean.select(5))).multiply(3));
directions = directions.addBands(sample_mean.select(0).subtract(sample_mean.select(4)).gt(sample_mean.select(4).subtract(sample_mean.select(8))).multiply(4));
// The next 4 are the not() of the previous 4
directions = directions.addBands(directions.select(0).not().multiply(5));
directions = directions.addBands(directions.select(1).not().multiply(6));
directions = directions.addBands(directions.select(2).not().multiply(7));
directions = directions.addBands(directions.select(3).not().multiply(8));

// Mask all values that are not 1-8
directions = directions.updateMask(gradmask);

// "collapse" the stack into a singe band image (due to masking, each pixel has just one value (1-8) in it's directional band, and is otherwise masked)
directions = directions.reduce(ee.Reducer.sum());

var sample_stats = sample_var.divide(sample_mean.multiply(sample_mean));

// Calculate localNoiseVariance
var sigmaV = sample_stats.toArray().arraySort().arraySlice(0,0,5).arrayReduce(ee.Reducer.mean(), [0]);

// Set up the 7*7 kernels for directional statistics
var rect_weights = ee.List.repeat(ee.List.repeat(0,7),3).cat(ee.List.repeat(ee.List.repeat(1,7),4));

var diag_weights = ee.List([[1,0,0,0,0,0,0], [1,1,0,0,0,0,0], [1,1,1,0,0,0,0],
[1,1,1,1,0,0,0], [1,1,1,1,1,0,0], [1,1,1,1,1,1,0], [1,1,1,1,1,1,1]]);

var rect_kernel = ee.Kernel.fixed(7,7, rect_weights, 3, 3, false);
var diag_kernel = ee.Kernel.fixed(7,7, diag_weights, 3, 3, false);

// Create stacks for mean and variance using the original kernels. Mask with relevant direction.
var dir_mean = myimg.reduceNeighborhood(ee.Reducer.mean(), rect_kernel).updateMask(directions.eq(1));
var dir_var = myimg.reduceNeighborhood(ee.Reducer.variance(), rect_kernel).updateMask(directions.eq(1));

dir_mean = dir_mean.addBands(myimg.reduceNeighborhood(ee.Reducer.mean(), diag_kernel).updateMask(directions.eq(2)));
dir_var = dir_var.addBands(myimg.reduceNeighborhood(ee.Reducer.variance(), diag_kernel).updateMask(directions.eq(2)));

// and add the bands for rotated kernels
for (var i=1; i<4; i++) {
dir_mean = dir_mean.addBands(myimg.reduceNeighborhood(ee.Reducer.mean(), rect_kernel.rotate(i)).updateMask(directions.eq(2*i+1)));
dir_var = dir_var.addBands(myimg.reduceNeighborhood(ee.Reducer.variance(), rect_kernel.rotate(i)).updateMask(directions.eq(2*i+1)));
dir_mean = dir_mean.addBands(myimg.reduceNeighborhood(ee.Reducer.mean(), diag_kernel.rotate(i)).updateMask(directions.eq(2*i+2)));
dir_var = dir_var.addBands(myimg.reduceNeighborhood(ee.Reducer.variance(), diag_kernel.rotate(i)).updateMask(directions.eq(2*i+2)));
}

// "collapse" the stack into a single band image (due to masking, each pixel has just one value in it's directional band, and is otherwise masked)
dir_mean = dir_mean.reduce(ee.Reducer.sum());
dir_var = dir_var.reduce(ee.Reducer.sum());

// A finally generate the filtered value
var varX = dir_var.subtract(dir_mean.multiply(dir_mean).multiply(sigmaV)).divide(sigmaV.add(1.0));

var b = varX.divide(dir_var);

var result = dir_mean.add(b.multiply(myimg.subtract(dir_mean)));
//return(result);
return(img.addBands(ee.Image(toDB(result.arrayGet(0))).rename("filter")));
}

var VVFiltered = collectionVV.map(RefinedLee);
var VVFiltered_2016 = ee.ImageCollection(VVFiltered.select("filter"));
Map.addLayer(VVFiltered_2016, {min:-15,max:0}, 'VV filtered', 0);

var VHFiltered = collectionVH.map(RefinedLee);
var VHFiltered_2016 = ee.ImageCollection(VHFiltered.select("filter"));
Map.addLayer(VHFiltered_2016, {min:-30,max:0}, 'VH filtered', 0);





// Export the image, specifying scale and region.
Export.image.toDrive({
image: VVFiltered_2016,
description: 'VVS1_2016_filtered',
scale: 100,
region: roi,
fileFormat: 'GeoTIFF',
});

1 Answer 1

2

This is because VVFiltered_2016 is an ImageCollection, which is not exportable. You'll need to mosaic this together before you export. There are multiple ways to do that, but the simplest would be to call .mosaic() on the collection.

// Export the image, specifying scale and region.
Export.image.toDrive({
   image: VVFiltered_2016.mosaic(),
   description: 'VVS1_2016_filtered',
   scale: 100,
   region: roi,
   fileFormat: 'GeoTIFF',
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.