NDVI using Pi Noir Camera

Hello…
I am an engineering student working on a project based on NDVI calculation to monitor the crop health. I used the PiNoIR camera with blue filter for my experiment in order to obtain the values of NIR and Red region. I used the following code to extract the required values and to calculate the NDVI. But in the output image, the empty regions (area where no leaves are present as shown in the below figure) and ground have higher NDVI values. The shadowed regions are shown in the range 0.5 to 0.6. I wanted to know whether the output is correct and what corrections can be done in the -code in order to correct the error. The code is given below.
from PIL import Image
import numpy as np
import cv2
from cv2 import imread
from matplotlib import cm
rgb_matrix =cv2.imread(‘inputimg.jpg’)
w=rgb_matrix.shape[1] #columns
h=rgb_matrix.shape[0] #rows
print(w)
print(h)
#Compute ndvi values for each pixel
#NDVI=(NIR-R)/(NIR+R)
res=
for i in range(h):
row=
for j in range(w):
val=rgb_matrix[i][j]
n=val[2]
r=val[1]
num=((int(n)-int®))
den=((int(n)+int®))
if(den == 0):
r=0.0
else:
r=np.divide(num,den)
row.append®
res.append(row)
print(‘Done’)
#based on NDVI values, give different colors for easier identification
for i in range(h):
for j in range(w):
if(res[i][j] >=-1 and res[i][j] <0):
rgb_matrix[i][j]=[128,128,128] #grey
elif(res[i][j]>=0 and res[i][j]<0.2):
rgb_matrix[i][j]=[64,255,0] #parrot green
elif(res[i][j]>=0.2 and res[i][j]<0.3):
rgb_matrix[i][j]=[125,255,255] #yellow
elif(res[i][j]>=0.3 and res[i][j]<0.4):
rgb_matrix[i][j]=[0,128,128] #dark green
elif(res[i][j]>=0.4 and res[i][j]<0.5):
rgb_matrix[i][j]=[255,255,0] #sky blue
elif(res[i][j]>=0.5 and res[i][j]<0.6):
rgb_matrix[i][j]=[255,51,153] #purple
elif(res[i][j]>=0.6 and res[i][j]<0.7):
rgb_matrix[i][j]=[0,128,255] #orange
elif(res[i][j]>=0.7 and res[i][j]<0.8):
rgb_matrix[i][j]=[255,43,255] #pink
elif(res[i][j]>=0.8 and res[i][j]<0.9):
rgb_matrix[i][j]=[40,40,255] #red
else:
rgb_matrix[i][j]=[255,0,0] #dark blue
cv2.imwrite(‘outputimg.jpg’,rgb_matrix)
print(“Completed!!”)
(Ignore the indentation errors)

1 Like

A few suggestions.

  1. My guess is that most of the readers of this forum won’t know what NDVI, is so a definition could be useful for helping people better understand your problem.

  2. Your code will be much more readable if you put inside triple backquotes (```).

import math

def myFn(a):
     return math.sin(a) * 2.0

Now, not knowing that much about this area myself, I wonder about the following.

  1. Does the blue filter skew the Red and NIR channels in a way that makes the math not work as you expected?

  2. Maybe there is some channel normalization that needs to be done to correct for sensitivity differences between the channels for the NDVI calculation? For example the NIR channel value needs to be multiplied by 1.5 first? Or there is a background value for one or both channels that needs to be subtracted?

1 Like

Hello,
The NDVI image looks correct from patterns, however we cannot know unless we also have a unprocessed image to judge. NDVI is slightly different than other processing techniques and strongly affected by temp., sun angle, topography etc. We can judge if your calculations are correct with a sample image or ground data.
Bob

1 Like

[Uploading: rp12.jpg…] This our unprocessed image

Hello, sorry for the delay,
We did not receive the unprocessed image, however your math is correct. It should give you the information you are looking for, but if not let us know if we may be of some help further.
Bob

O.K. I found it!! Yes the image corresponds to the colormap. Now just what is it you are looking for? This can be used in many different ways. The NDVI data is usually used to determine the amount of water the plant system holds. It does not give an actual indication of a plants health which can vary widely through out the seasons. This is really pretty close to the ground to tell what it is you are trying to find. The moisture content is very uniform throughout the image. Are you looking for something else?
Bob

@smith_robertj but the place in that image was a completely dry place and we are getting higher values in ground regions

1 Like

Hello again harshitha,
I sent a slightly modified image with the changes made in the comments to your project page, where it is explained what and how to do them. Any more advice, just ask. If this was less complicated, everyone would be doing it.
Bob
:grinning:

If you don’t mind me asking do you use a blue filter to filter out all the blue light if so is that why int r = green value