2

I've had this error come up. Unfortunately the answers to similar questions on stack exchange are not applicable to my particular script.

I'm trying to account for sunglint so that I can improve my observations of seagrass beneath the ocean.

the full error reads as such - Sunglint Corrected: Layer error: Image.constant: Parameter 'value' is required.

Here is a link to my script: https://code.earthengine.google.com/f822b2089777eb1fa9318f187793a469

Here is my script

var dataset = ee.ImageCollection('COPERNICUS/S2_SR')
                  .filterDate('2021-02-12', '2021-07-25')
                  
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',20))
                  .filterBounds(roi)
                  
                  
                  .select(['B2','B3','B4','B1', 'B8']); 

                   
                  
                   
                   
                  
                  
var rgbVis = {
 min: 0.0,
 max: 1000,
 bands: ['B3', 'B2', 'B4'],
};

Map.addLayer(dataset, rgbVis, 'Filtered Collection'); 
var mosaic = dataset.mosaic();


var medianComposite = dataset.min(); 
Map.addLayer(medianComposite, rgbVis, 'Median Composite', 0);

var hansenImage = ee.Image('UMD/hansen/global_forest_change_2015');
var datamask = hansenImage.select('datamask');
var mask = datamask.eq(2);
var maskedComposite = medianComposite.updateMask(mask);
Map.addLayer(maskedComposite, rgbVis, 'masked');

Map.addLayer(maskedComposite, {
  bands: ['B4', 'B3', 'B2',],
  min: 0,
  max: 1000,
  scale:16,
}, 'BOA'); 

var B2 = maskedComposite.select(['B8', 'B2']);
var B3 = maskedComposite.select(['B8', 'B3']);
var B4 = maskedComposite.select(['B8', 'B4']);

var lfitB2 = B2.reduceRegion({
  reducer: ee.Reducer.linearFit(),
  geometry: glint,
  scale: 10,
  //tileScale: 16, 
  //maxPixels: 1000,
  //bestEffort: true
});

var lfitB3 = B3.reduceRegion({
  reducer: ee.Reducer.linearFit(),
  geometry: glint,
  scale: 10,
 // min: 0.0, 
  //maxPixels: 1000
  //tileScale: 16, 
  //maxPixels: 40e9,
  //bestEffort: true, 
});

var lfitB4 = B4.reduceRegion({
  reducer: ee.Reducer.linearFit(),
  geometry: glint,
  scale: 10,
 // min: 0.0, 
  //maxPixels: 1000
  //tileScale: 16, 
  //maxPixels: 40e9,
  //bestEffort: true, 
});

print(lfitB4)

//print('B2 OLS estimates:', lfitB2);
//print('B2 y-intercept:', lfitB2.get('offset'));
//print('B2 Slope:', lfitB2.get('scale'));
//print('B3 Slope:', lfitB3.get('scale'));
//print('B4 Slope:', lfitB4.get('scale'));

var slope_B2 = ee.Image.constant(lfitB2.get('scale')).clip(roi).rename('slope_B2');
var slope_B3 = ee.Image.constant(lfitB3.get('scale')).clip(roi).rename('slope_B3');
var slope_B4 = ee.Image.constant(lfitB4.get('scale')).clip(roi).rename('slope_B4');
var min_B8 = ee.Image.constant(maskedComposite.select('B8').reduceRegion(ee.Reducer.min(),roi, 3).get('B8')).rename('min_B8');

var glint_factors = ee.Image([slope_B2, slope_B3, slope_B4, min_B8]);
var S2 = maskedComposite.addBands(glint_factors);

/*var deglint_B2 = S2.select('B8').subtract(min_B8);
var deglint_B2 = slope_B2.multiply(deglint_B2);
var deglint_B2 = S2.select('B2').subtract(deglint_B2);
Map.addLayer(deglint_B2);*/

var deglint_B2 = S2.expression(
    'Blue - (Slope * (NIR - MinNIR))', {
    'Blue': S2.select('B2'),
    'NIR': S2.select('B8'),
    'MinNIR': S2.select('min_B8'),
    'Slope': S2.select('slope_B2')
}).rename('B2');

var deglint_B3 = S2.expression(
    'Green - (Slope * (NIR - MinNIR))', {
    'Green': S2.select('B3'),
    'NIR': S2.select('B8'),
    'MinNIR': S2.select('min_B8'),
    'Slope': S2.select('slope_B3')
}).rename('B3');

var deglint_B4 = S2.expression(
    'Red - (Slope * (NIR - MinNIR))', {
    'Red': S2.select('B4'),
    'NIR': S2.select('B8'),
    'MinNIR': S2.select('min_B8'),
    'Slope': S2.select('slope_B4')
}).rename('B4');

var S2_deglint = ee.Image([deglint_B2, deglint_B3, deglint_B4]);

Map.addLayer(S2_deglint, {
  bands: ['B4', 'B3', 'B2'],
  min: 0.0,
  max: 1000,
  scale: 16, 
  //tileScale: 16,
  bestEffort: true
}, 'Sunglint Corrected');

 var linkedMap = ui.Map();

//Map.addLayer(S2, {
//bands: ['B4', 'B3', 'B2'],
//min: 0.0,
//max: 40e9, 
//}, 'Top-of-Atmosphere Reflectance');

Map.addLayer(S2_deglint, {bands: ['B4', 'B3', 'B2'], min: 0.0, max: 1000, bestEffort: true, scale: 16}, 'Sunglint Corrected');

var linker = ui.Map.Linker([ui.root.widgets().get(0), linkedMap]);

var b2b3 = S2_deglint.select(['B2', 'B3']);
var b2b4 = S2_deglint.select(['B2', 'B4']);
var b3b4 = S2_deglint.select(['B3', 'B4']);

var lfitb2b3 = b2b3.reduceRegion({
  reducer: ee.Reducer.linearFit(),
  geometry: sand,
  scale: 16,
  bestEffort: true
});

var lfitb2b4 = b2b4.reduceRegion({
  reducer: ee.Reducer.linearFit(),
  geometry: sand,
  scale: 16,
});

var lfitb3b4 = b3b4.reduceRegion({
  reducer: ee.Reducer.linearFit(),
  geometry: sand,
  scale: 16,
});


var slope_b2b3 = ee.Image.constant(lfitb2b3.get('scale')).clip(roi).rename('slope_b2b3');
var slope_b2b4 = ee.Image.constant(lfitb2b4.get('scale')).clip(roi).rename('slope_b2b4');
var slope_b3b4 = ee.Image.constant(lfitb3b4.get('scale')).clip(roi).rename('slope_b3b4');

var dii_slopes = ee.Image([slope_b2b3, slope_b2b4, slope_b3b4]);
var S2_deglint = S2_deglint.addBands(dii_slopes);

var dii_b2b3 = S2_deglint.expression(
    'log(b2) - abs(slope * log(b3))', {
    'b2': S2_deglint.select('B2'),
    'b3': S2_deglint.select('B3'),
    'slope': S2_deglint.select('slope_b2b3')
}).rename('DII_b2b3');

var dii_b2b4 = S2_deglint.expression(
    'log(b2) - abs(slope * log(b4))', {
    'b2': S2_deglint.select('B2'),
    'b4': S2_deglint.select('B4'),
    'slope': S2_deglint.select('slope_b2b4')
}).rename('DII_b2b4');

var dii_b3b4 = S2_deglint.expression(
    'log(b3) - abs(slope * log(b4))', {
    'b3': S2_deglint.select('B3'),
    'b4': S2_deglint.select('B4'),
    'slope': S2_deglint.select('slope_b3b4')
}).rename('DII_b3b4');

var DII = ee.Image([dii_b2b3, dii_b2b4, dii_b3b4])

Map.addLayer(DII, {
  bands: ['DII_b2b4', 'DII_b3b4', 'DII_b2b3'],
  min: -7,
  max: -3
}, 'Depth-Invariant Index');

var training = maskedComposite.sample({
  region: roi,
  scale: 5,
  tileScale:   16, 
  numPixels: 3000
});

// Instantiate the clusterer and train it.
var clusterer = ee.Clusterer.wekaKMeans(5).train(training);

// Cluster the input using the trained clusterer.
var result = maskedComposite.cluster(clusterer);


// Display the clusters with random colors.
Map.addLayer(result.randomVisualizer(), {}, 'clusters');

1 Answer 1

1

Errors are produced because regression parameters are nulls (offset and scale) in some cases. It can be observed in following image for your original script:

enter image description here

So, I carefully tried out the script only for roi area, by implementing following modifications, and I got expected Sunglint Corrected image. You can modify the script for considering additional glint and sand geometries.

var dataset = ee.ImageCollection('COPERNICUS/S2_SR')
                  .filterDate('2021-02-12', '2021-07-25')
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',20))
                  .filterBounds(roi)
                  .select(['B2','B3','B4','B1', 'B8']); 

var rgbVis = {
 min: 0.0,
 max: 1000,
 bands: ['B3', 'B2', 'B4'],
};

Map.centerObject(roi, 16);
//Map.addLayer(dataset, rgbVis, 'Filtered Collection'); 
var mosaic = dataset.mosaic();

var medianComposite = dataset.min(); 
//Map.addLayer(medianComposite, rgbVis, 'Median Composite', 0);

var hansenImage = ee.Image('UMD/hansen/global_forest_change_2015');
var datamask = hansenImage.select('datamask');
var mask = datamask.eq(2);
var maskedComposite = medianComposite.updateMask(mask);
//Map.addLayer(maskedComposite, rgbVis, 'masked');
/*
Map.addLayer(maskedComposite, {
  bands: ['B4', 'B3', 'B2',],
  min: 0,
  max: 1000,
  scale:16,
}, 'BOA'); */

var B2 = maskedComposite.select(['B8', 'B2']);
var B3 = maskedComposite.select(['B8', 'B3']);
var B4 = maskedComposite.select(['B8', 'B4']);

var lfitB2 = B2.reduceRegion({
  reducer: ee.Reducer.linearFit(),
  geometry: roi,
  scale: 10,
  //tileScale: 16, 
  //maxPixels: 1000,
  //bestEffort: true
});

print(lfitB2);

var lfitB3 = B3.reduceRegion({
  reducer: ee.Reducer.linearFit(),
  geometry: roi,
  scale: 10,
 // min: 0.0, 
  //maxPixels: 1000
  //tileScale: 16, 
  //maxPixels: 40e9,
  //bestEffort: true, 
});

print(lfitB2);

var lfitB4 = B4.reduceRegion({
  reducer: ee.Reducer.linearFit(),
  geometry: roi,
  scale: 10,
 // min: 0.0, 
  //maxPixels: 1000
  //tileScale: 16, 
  //maxPixels: 40e9,
  //bestEffort: true, 
});

print(lfitB4);

var slope_B2 = ee.Image.constant(lfitB2.get('scale')).clip(roi).rename('slope_B2');
var slope_B3 = ee.Image.constant(lfitB3.get('scale')).clip(roi).rename('slope_B3');
var slope_B4 = ee.Image.constant(lfitB4.get('scale')).clip(roi).rename('slope_B4');
var min_B8 = ee.Image.constant(maskedComposite.select('B8').reduceRegion(ee.Reducer.min(),roi, 3).get('B8')).rename('min_B8');

var glint_factors = ee.Image([slope_B2, slope_B3, slope_B4, min_B8]);
var S2 = maskedComposite.addBands(glint_factors);

var deglint_B2 = S2.select('B8').subtract(min_B8);
var deglint_B2 = slope_B2.multiply(deglint_B2);
var deglint_B2 = S2.select('B2').subtract(deglint_B2);

var imageVisParam = {"opacity":1,
                     "bands":["B2"],
                     "min":-142.42184342256695,
                     "max":361,
                     "gamma":1};

//Map.addLayer(deglint_B2, imageVisParam, 'deglint_B2');

var deglint_B2 = S2.expression(
    'Blue - (Slope * (NIR - MinNIR))', {
    'Blue': S2.select('B2'),
    'NIR': S2.select('B8'),
    'MinNIR': S2.select('min_B8'),
    'Slope': S2.select('slope_B2')
}).rename('B2');

var deglint_B3 = S2.expression(
    'Green - (Slope * (NIR - MinNIR))', {
    'Green': S2.select('B3'),
    'NIR': S2.select('B8'),
    'MinNIR': S2.select('min_B8'),
    'Slope': S2.select('slope_B3')
}).rename('B3');

var deglint_B4 = S2.expression(
    'Red - (Slope * (NIR - MinNIR))', {
    'Red': S2.select('B4'),
    'NIR': S2.select('B8'),
    'MinNIR': S2.select('min_B8'),
    'Slope': S2.select('slope_B4')
}).rename('B4');

var S2_deglint = ee.Image([deglint_B2, deglint_B3, deglint_B4]);

Map.addLayer(S2_deglint, {
  bands: ['B4', 'B3', 'B2'],
  min: 0.0,
  max: 1000,
  scale: 16, 
  //tileScale: 16,
  bestEffort: true
}, 'Sunglint Corrected');

After running complete script in GEE code editor, it was obtained 'Sunglint Corrected' image; as it can be observed in following picture:

enter image description here

2
  • Perfect! Thanks so much! Absolute life saver! Jul 22, 2022 at 8:14
  • So, could you mark this answer as accepted? Thanks.
    – xunilk
    Jul 22, 2022 at 9:37

Your Answer

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

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