Расчет значения NDVI и обработка изображений - PullRequest
2 голосов
/ 14 января 2020

we have attached our input and processed image[![][1]][1] Я студент инженерного факультета, работающий над проектом, основанным на расчете NDVI для мониторинга здоровья сельскохозяйственных культур. Я использовал камеру PiNoIR с синим фильтром для своего эксперимента, чтобы получить значения NIR и Red Region . Я использовал следующий код, чтобы извлечь необходимые значения и рассчитать NDVI. Но на выходном изображении пустые области (области, где нет листьев, как показано на рисунке ниже) и земля имеют более высокие значения NDVI. Затененные области показаны в диапазоне от 0.5 до 0.6. Я хотел знать, является ли вывод правильным и какие исправления можно внести в -код, чтобы исправить ошибку. Код приведен ниже.

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(r)))   
 den=((int(n)+int(r)))
if(den == 0):
 r=0.0    
 else:
  r=np.divide(num,den)
  row.append(r)
    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 induntation errors)

1 Ответ

0 голосов
/ 14 января 2020

Несколько вещей ... во-первых, имейте в виду, что OpenCV использует BGR-порядок, а не RGB, как, кажется, предполагает ваш код. Это, вероятно, означает, что вы выбрали неправильные каналы как Red и NearIR - в этом случае мой код будет иметь ту же ошибку.

Во-вторых, вы действительно, действительно хотите попробовать и избежать обработки изображений в Python с Циклы for - они очень медленные, трудно читаемые и подвержены ошибкам в пределах l oop. Ниже приведен непроверенный код, поскольку вы не предоставили изображение, но оно должно дать вам представление:

import numpy as np
import cv2

# Load image and convert to float - for later division
im = cv2.imread('inputimg.jpg').astype(np.float)

# Split into 3 channels, discarding the first and saving the second as R, third as NearIR
_, R, NearIR = cv2.split(im)

# Compute NDVI values for each pixel
NDVI = (NearIR - R) / (NearIR + R + 0.001)

Это приведет нас к тому, что вы напечатаете Done в своем коде. Обратите внимание, что, если вы не знали, что OpenCV использует упорядочение BGR, для 1-го и 3-го каналов потребуется замена, т. Е. имейте в виду, что ваш NDVI будет с плавающей точкой в ​​диапазоне [-1,1], поэтому вы можете умножить его на 10 и преобразовать в целое число, чтобы назначить один из ваших 9 цветов ...

Пожалуйста загрузите изображение, чтобы люди могли ответить вам лучше.

...