Question: How was the frequency response graph interpreted in @cfastie blogpost, and how the computation of the NDVI was derived?

manueldun is asking a question about ndvi
Follow this topic

by manueldun | October 04, 2018 14:10 | #17220

@cfastie made a blog post that intereses me as I need to measure NDVI with micro controllers.

The questions that a need to understand are:

  • How to interpret frequency response graphs?
  • How did you come up with the computation of the NDVI this code? (code bellow)

tsl1.getLuminosity (&broadband1, &infrareda); infrared1 = infrareda*1.5; float vis1 = broadband1-infrareda; NDVI1 = (infrared1 - vis1) / (infrared1 + vis1);

  • I could just use this code but i want to be sure I Know what I am doing, Thanks.


Are you referring to this research note?

Are you referring to this figure as "frequency response graphs"?
Above: The spectral response of the TSL2561 sensor. Channel 1 is mostly near infrared and channel 0 is the full range, but if you subtract 1 from 0 you can get a mostly visible light result.

Are you referring to the Arduino sketch that was linked in the above research note?

Making some assumptions about your questions, here are my responses.

The TSL2561 sensor produces two signals. One is an indication of brightness dominated by visible light (but including a lot of NIR) and the other is an indication of brightness dominated by NIR (but including some visible). To compute NDVI, values for the intensity of both visible and NIR light are required. Using the TSL2561 sensor to compute NDVI has a few serious drawbacks.

  1. Neither signal from the TSL2561 is what you need because both are contaminated with the other signal.
  2. The NIR sensitivity of the TSL2561 is less than half of its sensitivity to visible light.
  3. The response of the TSL2561 to light is not linear (when one signal is five times greater than another, that does not mean the light was five times brighter).
  4. NDVI is typically computed using the brightness of red light, not all visible light.


  1. There is not much you can do about this, but by subtracting the NIR signal (channel 1) from the other signal (channel 2) you can get a value that might be a better estimate of the brightness of visible light.
  2. If you know how much the NIR signal (channel 1) is under-measuring NIR light, you can use brute force to increase that signal. The code you included multiplies the NIR signal by 1.5. This is somewhat arbitrary and will produce artifacts (useless NDVI values) under some conditions.
  3. The Arduino library I used corrects the nonlinearity of the TSL2561 signal for visible light. It does not correct for the nonlinearity in the NIR signal. So the values in the NIR signal (channel 1) will be too big or too small at either or both the low or high ends of its range. You might be able to find a library that corrects for the nonlinearity of channel 1.
  4. A filter like Wratten 25 which blocks all blue and green light but passes all red and NIR light could be placed in front of the TSL2561 sensor.

It might work better to use two TSL2561 sensors. Use one with a narrow band red filter to get a measure of red light brightness from channel 2. Use the other with a narrow band NIR-only filter like Wratten 87 to get a measure of NIR brightness from channel 1. You would still want to inflate the NIR signal to compensate for the lower sensitivity to NIR. And this does not solve the nonlinearity problem.

It might be better to find other sensors which don't have the problems of the TSL2561.


Is this a question? Click here to post it to the Questions page.

Reply to this comment...

Log in to comment