I'm trying to create the Vegetation Condition Index with Landsat time series images in Earth Engine, but I get the error:
ImageCollection (Error) Error in map(ID=LC08_198032_20130813):
Image.constant: Parameter 'value' is required.
Below is the script code, maybe something I was doing wrong at the section "//Create VCI index":
var l8collection = l8.filterDate('2013-04-01','2019-11-30').filterBounds(roi);
print(l8collection);
// Mask pixels with clouds and cloud shadows using the 'pixel_qa' band
var maskClouds = function(image){
// make a new single band image from the pixel qa band
var pixel_qa = image.select('pixel_qa');
// retain clear (0) and water (1) pixels
return image.updateMask(pixel_qa.eq(322));
};
// use "map" to apply the function to each image in the collection
var l8masked = l8collection.map(maskClouds);
print(l8masked);
// create function to add NDVI using NIR (B5) and the red band (B4)
var getNDVI = function(img1){
return img1.addBands(img1.normalizedDifference(['B5','B4']).rename('NDVI'));
};
// map over image collection
var l8ndvi = l8masked.map(getNDVI);
// filter images not containing data in the study area
var filtered = l8ndvi.filter(ee.Filter.neq('count', 0));
print(filtered);
// Create VCI index
var vci = filtered.map(function(img){
var id = img.id();
var min = img.reduceRegion({reducer: ee.Reducer.min(),geometry:roi, bestEffort:true, scale: 30}).get('NDVI');
var max = img.reduceRegion({reducer: ee.Reducer.max(),geometry:roi, bestEffort:true, scale: 30}).get('NDVI');
var Index = img.expression("(NDVI-min)/(max-min)",
{"NDVI" : img,"max" : ee.Number(max),"min" : ee.Number(min),})
.rename('TCI')
.copyProperties(img,['system:time_start','system:time_end']);
return Index;
});
print(vci);
Best Answer
Here's how to understand the error message:
In Earth Engine, an argument being
null
is usually the same as it being omitted. Hence, a call toImage.constant
with the valuenull
will produce the errorImage.constant: Parameter 'value' is required.
This probably explains why you are getting this error despite not having written a misformed call toImage.constant
.But you don't have any
Image.constant
in your script, it seems. What you do have isimg.expression("(NDVI-min)/(max-min)", ...)
and you are passing in numbers. This implicitly creates a call toImage.constant
to convert those numbers to constant images.Therefore, we can conclude that either
min
ormax
were null. This could happen if for whatever reason there were no pixels intersecting the region of interest, so the minimum/maximum is undefined.I confirmed this theory by using your
reduceRegion
parameters withee.Reducer.count()
:img.reduceRegion({reducer: ee.Reducer.count(),geometry:roi, bestEffort:true, scale: 30})
and replacing the image computation with returning a feature holding these counts in the properties. This showed that some of the selected images (may not be the same as yours, since I didn't use the sameroi
which you did not include in your question) hadNDVI
bands that had zero pixels counted.In order to avoid this error, you can
map
to add the results of the reductions as properties to the features,filter
out features with null values withee.Filter.notNull
, thenmap
to compute the result you want (see Justin Braaten's answer for code).