NDVI values from SentinelHub different from the ones calculates in Qgis

Hi,
I’m worried i’m not getting the correct values for NDVI.
When I first downloaded NDVI from Sentinel Hub EO Browser and imported to Qgis, the result was 3 bands which didn’t seem to be neither band 4, 8 or NDVI as, when trying to calculate NDVI from each set of values, it didn’t result in neither of the values.
I’ve downloaded bands 4 and 8 and calculated NDVI in Qgis (values make since as they are from -1 to 1). However, I would like to confirm these values by downloading the NDVI raster with the correct values. I’ve already read the following links but nothing is matching my results. Could you please explain?
Thank you
https://www.sentinel-hub.com/faq/how-are-values-calculated-within-sentinel-hub-and-how-are-they-returned-output/
https://www.sentinel-hub.com/faq/how-do-i-get-actual-ndvi-values/

Hello,

The reason you got 3 bands when you downloaded the NDVI product from Sentinel Hub EO Browser is that the script is designed for visualisation purposes only. Indeed NDVI values are mapped to RGB values, so when you download the product, you get the 3 RGB bands.

To retrieve the NDVI values you need to use the Custom Script functionality of EO Browser. You can also use our Requests Builder tool, recently announced in the Forum. Thanks to its graphical interface, the tool makes querying data really easy, as most of the code is written for you!

Back to NDVI, you can either request the data as floats or as integers and convert them back to float values on your side (in QGIS for example). Since the latter requires less Processing Units and smaller files, I’ll post an example with integers.

Once you have set your date and location of interest for Sentinel-2, you can use the following evalscript either in EO Browser or in Requests Builder :

//VERSION=3
function setup() {
  return {
    input: ["B04", "B08"],
    output: { bands: 1, sampleType: "UINT16" }
  };
}

function evaluatePixel(sample) {
let ndvi = index(sample.B08, sample.B04);
return [10000 * ndvi + 10000];
}

The setup function specifies which bands you want to use and the output expected. Here we want 1 band as unsigned 16-bit integers.

In the evaluatePixel function, the ndvi is first computed. In the return statement, we then multiply the NDVI values by 10000 and add 10000. This way NDVI spans [0, 20000], and you can rescale back down to [-1,1] by doing:

ndvi_float = (ndvi - 10000.)/10000.

in QGIS or any other software.

Let me know if you run into any difficulties!

Maxim

1 Like

Hi Maxim, thanks for the quick reply!
Since I’ve already downloaded the raw data (bands 4 and 8), are they ok to calculate the ndvi directly in qgis?
Thank you so much

Since I’ve already downloaded the raw data (bands 4 and 8), are they ok to calculate the ndvi directly in qgis?

Yes, they are! The results will be the same (maybe some negligable numerical differences).

Maxim