Areas with NDVI less than a certain threshold for a growing season

We are trying to identify areas where NDVI values were below 0.3 throughout the active growing season. I have modified the script that I found on this forum to meet our need.

Currently, I (think) am averaging the NDVI values, which I am not certain is the correct approach. Also, the script uses four bands as input, which also should not be needed. How do I use only three bands (B4, B4, and dataMask) for generating the desired output?

Appreciate any help.


function setup () {
  return {
    input: ["B02", "B03", "B04", "B08", "dataMask"],
    output: {
      bands: 4,
      sampleType: 'UINT8'
    mosaicking: "ORBIT"

function calcNDVI(sample) {
  var denom = sample.B04+sample.B08;
  return ((denom!=0) ? (sample.B08-sample.B04) / denom : 0.0);

function avgSamples(s){
    var sum=0
    for(var i=0; i<s.length; i++)
    if (calcNDVI(s[i]) < .3)

  let avg = sum/s.length
    return avg

function evaluatePixel(s) {
    let val=avgSamples(s)
    return [255, 0, 0, ((val < 0.3) && (val > 0.01))* 255]

function preProcessScenes (collections) {
    collections.scenes.orbits = collections.scenes.orbits.filter(function (orbit) {
        return (new Date(orbit.dateFrom) < new Date("2022-05-01T00:00:00Z")) ||
               (new Date(orbit.dateFrom) >= new Date("2022-10-31T00:00:00Z"))
    return collections

Hi Kenny,

I just wanted to clarify if you want to take an average over the region for the active growing period or would a maximum NDVI value in this period be sufficient to check weather the value is below 0.3 throughout.

To calculate NDVI, you would need B04, B08 and dataMask as input and you can just retain these bands in the evalscript. But how do you want to visualize the rest of the pixels in your bounding box? If you want the rest of the image to be true color, you will have to take the B02 and B03 as inputs. Or you could just set it to a different color (say green) without taking in any other bands.

Let me know how you want to proceed and I could help you out with the code.

Let’s say a pixel has values consistently below 0.3 throughout the growing season; we would want to identify those pixels. We are not explicitly seeking an average value but more like a binary mask. Regarding the pixels that do not meet the criteria, we could set them to transparent.

So taking a maximum of NDVI over the entire period and considering the pixels which have NDVI less than 0.3 would work fine for your application.
The code below could give you a binary mask with all the areas with NDVI below 0.3 would appear in red and the rest in black. You could also remove the “B02” and “B03” bands from the input.

function evaluatePixel(samples) {
    var max = 0;
    for (var i=0;i<samples.length;i++) {
      var ndvi = calcNDVI(samples[i]);
      max = ndvi > max ? ndvi:max;
if (max<0.01) return [0,0,0,samples[0].dataMask];
else if (max<0.3) return [255,0,0,samples[0].dataMask];
else return [0,0,0,samples[0].dataMask]

But if you want “transparent” image, you might have to consider the other two bands to visualize the true color image.