From 551538b709efe236eb65a83a6d3a5ff006742684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Atkinson?= Date: Mon, 26 Aug 2019 13:36:04 -0300 Subject: [PATCH 1/6] add the index calculation at difital_image_processing file --- digital_image_processing/IndexCalculation.py | 651 +++++++++++++++++++ 1 file changed, 651 insertions(+) create mode 100644 digital_image_processing/IndexCalculation.py diff --git a/digital_image_processing/IndexCalculation.py b/digital_image_processing/IndexCalculation.py new file mode 100644 index 000000000000..36e33ca2a0c7 --- /dev/null +++ b/digital_image_processing/IndexCalculation.py @@ -0,0 +1,651 @@ +# Author: João Gustavo A. Amorim +# Author email: joaogustavoamorim@gmail.com +# Coding date: jan 2019 +# python/black: True + +# Imports +import numpy as np + +# Class implemented to calculus the index +class IndexCalculation: + """ + # Class Summary + This algorithm consists in calculating vegetation indices, these indices can be used for precision agriculture for example (or remote sensing). There are functions to define the data and to calculate the implemented indices. + + # Vegetation index + https://en.wikipedia.org/wiki/Vegetation_Index + A Vegetation Index (VI) is a spectral transformation of two or more bands designed to enhance the contribution of vegetation properties and allow reliable spatial and temporal inter-comparisons of terrestrial photosynthetic activity and canopy structural variations + + # Information about channels (Wavelength range for each) + * nir - near-infrared + https://www.malvernpanalytical.com/br/products/technology/near-infrared-spectroscopy + Wavelength Range 700 nm to 2500 nm + * Red Edge + https://en.wikipedia.org/wiki/Red_edge + Wavelength Range 680 nm to 730 nm + * red + https://en.wikipedia.org/wiki/Color + Wavelength Range 635 nm to 700 nm + * blue + https://en.wikipedia.org/wiki/Color + Wavelength Range 450 nm to 490 nm + * green + https://en.wikipedia.org/wiki/Color + Wavelength Range 520 nm to 560 nm + + + # Implemented index list + #"abbreviationOfIndexName" -- list of channels used + + #"ARVI2" -- red, nir + #"CCCI" -- red, redEdge, nir + #"CVI" -- red, green, nir + #"GLI" -- red, green, blue + #"NDVI" -- red, nir + #"BNDVI" -- blue, nir + #"redEdgeNDVI" -- red, redEdge + #"GNDVI" -- green, nir + #"GBNDVI" -- green, blue, nir + #"GRNDVI" -- red, green, nir + #"RBNDVI" -- red, blue, nir + #"PNDVI" -- red, green, blue, nir + #"ATSAVI" -- red, nir + #"BWDRVI" -- blue, nir + #"CIgreen" -- green, nir + #"CIrededge" -- redEdge, nir + #"CI" -- red, blue + #"CTVI" -- red, nir + #"GDVI" -- green, nir + #"EVI" -- red, blue, nir + #"GEMI" -- red, nir + #"GOSAVI" -- green, nir + #"GSAVI" -- green, nir + #"Hue" -- red, green, blue + #"IVI" -- red, nir + #"IPVI" -- red, nir + #"I" -- red, green, blue + #"RVI" -- red, nir + #"MRVI" -- red, nir + #"MSAVI" -- red, nir + #"NormG" -- red, green, nir + #"NormNIR" -- red, green, nir + #"NormR" -- red, green, nir + #"NGRDI" -- red, green + #"RI" -- red, green + #"S" -- red, green, blue + #"IF" -- red, green, blue + #"DVI" -- red, nir + #"TVI" -- red, nir + #"NDRE" -- redEdge, nir + + #list of all index implemented + #allIndex = ["ARVI2", "CCCI", "CVI", "GLI", "NDVI", "BNDVI", "redEdgeNDVI", "GNDVI", "GBNDVI", "GRNDVI", "RBNDVI", "PNDVI", "ATSAVI", "BWDRVI", "CIgreen", "CIrededge", "CI", "CTVI", "GDVI", "EVI", "GEMI", "GOSAVI", "GSAVI", "Hue", "IVI", "IPVI", "I", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", "NormR", "NGRDI", "RI", "S", "IF", "DVI", "TVI", "NDRE"] + #list of index with not blue channel + #notBlueIndex = ["ARVI2", "CCCI", "CVI", "NDVI", "redEdgeNDVI", "GNDVI", "GRNDVI", "ATSAVI", "CIgreen", "CIrededge", "CTVI", "GDVI", "GEMI", "GOSAVI", "GSAVI", "IVI", "IPVI", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", "NormR", "NGRDI", "RI", "DVI", "TVI", "NDRE"] + #list of index just with RGB channels + #RGBIndex = ["GLI", "CI", "Hue", "I", "NGRDI", "RI", "S", "IF"] + """ + + def __init__(self, red=None, green=None, blue=None, redEdge=None, nir=None): + print("Numpy version: " + np.__version__) + self.red = red + self.green = green + self.blue = blue + self.redEdge = redEdge + self.nir = nir + + def setMatrices(self, red=None, green=None, blue=None, redEdge=None, nir=None): + self.red = red + self.green = green + self.blue = blue + self.redEdge = redEdge + self.nir = nir + return True + + def calculation(self, index=""): + """ + performs the calculation of the index with the values instantiated in the class + :str index: sigla do indice a ser calculado + """ + if index == "": + print("Not determined index!") + elif index == "ARVI2": + return self.ARVI2(red=self.red, nir=self.nir) + elif index == "CCCI": + return self.CCCI(red=self.red, redEdge=self.redEdge, nir=self.nir) + elif index == "CVI": + return self.CVI(red=self.red, green=self.green, nir=self.nir) + elif index == "GLI": + return self.GLI(red=self.red, green=self.green, blue=self.blue) + elif index == "NDVI": + return self.NDVI(red=self.red, nir=self.nir) + elif index == "BNDVI": + return self.BNDVI(blue=self.blue, nir=self.nir) + elif index == "redEdgeNDVI": + return self.redEdgeNDVI(red=self.red, redEdge=self.redEdge) + elif index == "GNDVI": + return self.GNDVI(green=self.green, nir=self.nir) + elif index == "GBNDVI": + return self.GBNDVI(green=self.green, blue=self.blue, nir=self.nir) + elif index == "GRNDVI": + return self.GRNDVI(red=self.red, green=self.green, nir=self.nir) + elif index == "RBNDVI": + return self.RBNDVI(red=self.red, blue=self.blue, nir=self.nir) + elif index == "PNDVI": + return self.PNDVI( + red=self.red, green=self.green, blue=self.blue, nir=self.nir + ) + elif index == "ATSAVI": + return self.ATSAVI(red=self.red, nir=self.nir, X=0.08, a=1.22, b=0.03) + elif index == "BWDRVI": + return self.BWDRVI(blue=self.blue, nir=self.nir) + elif index == "CIgreen": + return self.CIgreen(green=self.green, nir=self.nir) + elif index == "CIrededge": + return self.CIrededge(redEdge=self.redEdge, nir=self.nir) + elif index == "CI": + return self.CI(red=self.red, blue=self.blue) + elif index == "CTVI": + return self.CTVI(red=self.red, nir=self.nir) + elif index == "GDVI": + return self.GDVI(green=self.green, nir=self.nir) + elif index == "EVI": + return self.EVI(red=self.red, blue=self.blue, nir=self.nir) + elif index == "GEMI": + return self.GEMI(red=self.red, nir=self.nir) + elif index == "GOSAVI": + return self.GOSAVI(green=self.green, nir=self.nir, Y=0.16) + elif index == "GSAVI": + return self.GSAVI(green=self.green, nir=self.nir, L=0.5) + elif index == "Hue": + return self.Hue(red=self.red, green=self.green, blue=self.blue) + elif index == "IVI": + return self.IVI(red=self.red, nir=self.nir, a=1, b=1) + elif index == "IPVI": + return self.IPVI(red=self.red, nir=self.nir) + elif index == "I": + return self.I(red=self.red, green=self.green, blue=self.blue) + elif index == "RVI": + return self.RVI(red=self.red, nir=self.nir) + elif index == "MRVI": + return self.MRVI(red=self.red, nir=self.nir) + elif index == "MSAVI": + return self.MSAVI(red=self.red, nir=self.nir) + elif index == "NormG": + return self.NormG(red=self.red, green=self.green, nir=self.nir) + elif index == "NormNIR": + return self.NormNIR(red=self.red, green=self.green, nir=self.nir) + elif index == "NormR": + return self.NormR(red=self.red, green=self.green, nir=self.nir) + elif index == "NGRDI": + return self.NGRDI(red=self.red, green=self.green) + elif index == "RI": + return self.RI(red=self.red, green=self.green) + elif index == "S": + return self.S(red=self.red, green=self.green, blue=self.blue) + elif index == "IF": + return self.IF(red=self.red, green=self.green, blue=self.blue) + elif index == "DVI": + return self.DVI(red=self.red, nir=self.nir) + elif index == "TVI": + return self.TVI(red=self.red, nir=self.nir) + elif index == "NDRE": + return self.NDRE(redEdge=self.redEdge, nir=self.nir) + else: + print("Index not list!") + + return False + + def directCalculation( + self, index="", red=None, green=None, blue=None, redEdge=None, nir=None + ): + """ + performs the calculation of the index with the values passed by parameter + 39 indices cadastrados + :str index: sigla do indice a ser calculado + """ + if index == "": + print("Not determined index!") + elif index == "ARVI2": + return self.ARVI2(red=red, nir=nir) + elif index == "CCCI": + return self.CCCI(red=red, redEdge=redEdge, nir=nir) + elif index == "CVI": + return self.CVI(red=red, green=green, nir=nir) + elif index == "GLI": + return self.GLI(red=red, green=green, blue=blue) + elif index == "NDVI": + return self.NDVI(red=red, nir=nir) + elif index == "BNDVI": + return self.BNDVI(blue=blue, nir=nir) + elif index == "redEdgeNDVI": + return self.redEdgeNDVI(red=red, redEdge=redEdge) + elif index == "GNDVI": + return self.GNDVI(green=green, nir=nir) + elif index == "GBNDVI": + return self.GBNDVI(green=green, blue=blue, nir=nir) + elif index == "GRNDVI": + return self.GRNDVI(red=red, green=green, nir=nir) + elif index == "RBNDVI": + return self.RBNDVI(red=red, blue=blue, nir=nir) + elif index == "PNDVI": + return self.PNDVI(red=red, green=green, blue=blue, nir=nir) + elif index == "ATSAVI": + return self.ATSAVI(red=red, nir=nir, X=0.08, a=1.22, b=0.03) + elif index == "BWDRVI": + return self.BWDRVI(blue=blue, nir=nir) + elif index == "CIgreen": + return self.CIgreen(green=green, nir=nir) + elif index == "CIrededge": + return self.CIrededge(redEdge=redEdge, nir=nir) + elif index == "CI": + return self.CI(red=red, blue=blue) + elif index == "CTVI": + return self.CTVI(red=red, nir=nir) + elif index == "GDVI": + return self.GDVI(green=green, nir=nir) + elif index == "EVI": + return self.EVI(red=red, blue=blue, nir=nir) + elif index == "GEMI": + return self.GEMI(red=red, nir=nir) + elif index == "GOSAVI": + return self.GOSAVI(green=green, nir=nir, Y=0.16) + elif index == "GSAVI": + return self.GSAVI(green=green, nir=nir, L=0.5) + elif index == "Hue": + return self.Hue(red=red, green=green, blue=blue) + elif index == "IVI": + return self.IVI(red=red, nir=nir, a=1, b=1) + elif index == "IPVI": + return self.IPVI(red=red, nir=nir) + elif index == "I": + return self.I(red=red, green=green, blue=blue) + elif index == "RVI": + return self.RVI(red=red, nir=nir) + elif index == "MRVI": + return self.MRVI(red=red, nir=nir) + elif index == "MSAVI": + return self.MSAVI(red=red, nir=nir) + elif index == "NormG": + return self.NormG(red=red, green=green, nir=nir) + elif index == "NormNIR": + return self.NormNIR(red=red, green=green, nir=nir) + elif index == "NormR": + return self.NormR(red=red, green=green, nir=nir) + elif index == "NGRDI": + return self.NGRDI(red=red, green=green) + elif index == "RI": + return self.RI(red=red, green=green) + elif index == "S": + return self.S(red=red, green=green, blue=blue) + elif index == "IF": + return self.IF(red=red, green=green, blue=blue) + elif index == "DVI": + return self.DVI(red=red, nir=nir) + elif index == "TVI": + return self.TVI(red=red, nir=nir) + elif index == "NDRE": + return self.NDRE(redEdge=redEdge, nir=nir) + else: + print("Index not list!") + + return False + + def ARVI2(self, red=None, nir=None): + """ + Atmospherically Resistant Vegetation Index 2 + https://www.indexdatabase.de/db/i-single.php?id=396 + :return: index + −0.18+1.17*(NIR−RED)/(NIR+RED) + """ + return -0.18 + (1.17 * ((nir - red) / (nir + red))) + + def CCCI(self, red=None, redEdge=None, nir=None): + """ + Canopy Chlorophyll Content Index + https://www.indexdatabase.de/db/i-single.php?id=224 + :return: index + """ + return ((nir - redEdge) / (nir + redEdge)) / ((nir - red) / (nir + red)) + + def CVI(self, red=None, green=None, nir=None): + """ + Chlorophyll vegetation index + https://www.indexdatabase.de/db/i-single.php?id=391 + :return: index + """ + return nir * (red / (green ** 2)) + + def GLI(self, red=None, green=None, blue=None): + """ + Green leaf index + https://www.indexdatabase.de/db/i-single.php?id=375 + :return: index + """ + return (2 * green - red - blue) / (2 * green + red + blue) + + def NDVI(self, red=None, nir=None): + """ + Normalized Difference NIR/Red Normalized Difference Vegetation Index, Calibrated NDVI - CDVI + https://www.indexdatabase.de/db/i-single.php?id=58 + :return: index + """ + return (nir - red) / (nir + red) + + def BNDVI(self, blue=None, nir=None): + """ + Normalized Difference NIR/Blue Blue-normalized difference vegetation index + https://www.indexdatabase.de/db/i-single.php?id=135 + :return: index + """ + return (nir - blue) / (nir + blue) + + def redEdgeNDVI(self, red=None, redEdge=None): + """ + Normalized Difference Rededge/Red + https://www.indexdatabase.de/db/i-single.php?id=235 + :return: index + """ + return (redEdge - red) / (redEdge + red) + + def GNDVI(self, green=None, nir=None): + """ + Normalized Difference NIR/Green Green NDVI + https://www.indexdatabase.de/db/i-single.php?id=401 + :return: index + """ + return (nir - green) / (nir + green) + + def GBNDVI(self, green=None, blue=None, nir=None): + """ + Green-Blue NDVI + https://www.indexdatabase.de/db/i-single.php?id=186 + :return: index + """ + return (nir - (green + blue)) / (nir + (green + blue)) + + def GRNDVI(self, red=None, green=None, nir=None): + """ + Green-Red NDVI + https://www.indexdatabase.de/db/i-single.php?id=185 + :return: index + """ + return (nir - (green + red)) / (nir + (green + red)) + + def RBNDVI(self, red=None, blue=None, nir=None): + """ + Red-Blue NDVI + https://www.indexdatabase.de/db/i-single.php?id=187 + :return: index + """ + return (nir - (blue + red)) / (nir + (blue + red)) + + def PNDVI(self, red=None, green=None, blue=None, nir=None): + """ + Pan NDVI + https://www.indexdatabase.de/db/i-single.php?id=188 + :return: index + """ + return (nir - (green + red + blue)) / (nir + (green + red + blue)) + + def ATSAVI(self, red=None, nir=None, X=0.08, a=1.22, b=0.03): + """ + Adjusted transformed soil-adjusted VI + https://www.indexdatabase.de/db/i-single.php?id=209 + :return: index + """ + return a * ((nir - a * red - b) / (a * nir + red - a * b + X * (1 + a ** 2))) + + def BWDRVI(self, blue=None, nir=None): + """ + Blue-wide dynamic range vegetation index + https://www.indexdatabase.de/db/i-single.php?id=136 + :return: index + """ + return (0.1 * nir - blue) / (0.1 * nir + blue) + + def CIgreen(self, green=None, nir=None): + """ + Chlorophyll Index Green + https://www.indexdatabase.de/db/i-single.php?id=128 + :return: index + """ + return (nir / green) - 1 + + def CIrededge(self, redEdge=None, nir=None): + """ + Chlorophyll Index RedEdge + https://www.indexdatabase.de/db/i-single.php?id=131 + :return: index + """ + return (nir / redEdge) - 1 + + def CI(self, red=None, blue=None): + """ + Coloration Index + https://www.indexdatabase.de/db/i-single.php?id=11 + :return: index + """ + return (red - blue) / red + + def CTVI(self, red=None, nir=None): + """ + Corrected Transformed Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=244 + :return: index + """ + ndvi = self.NDVI(red=red, nir=nir) + return ((ndvi + 0.5) / (abs(ndvi + 0.5))) * (abs(ndvi + 0.5) ** (1 / 2)) + + def GDVI(self, green=None, nir=None): + """ + Difference NIR/Green Green Difference Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=27 + :return: index + """ + return nir - green + + def EVI(self, red=None, blue=None, nir=None): + """ + Enhanced Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=16 + :return: index + """ + return 2.5 * ((nir - red) / (nir + 6 * red - 7.5 * blue + 1)) + + def GEMI(self, red=None, nir=None): + """ + Global Environment Monitoring Index + https://www.indexdatabase.de/db/i-single.php?id=25 + :return: index + """ + n = (2 * (nir ** 2 - red ** 2) + 1.5 * nir + 0.5 * red) / (nir + red + 0.5) + return n * (1 - 0.25 * n) - (red - 0.125) / (1 - red) + + def GOSAVI(self, green=None, nir=None, Y=0.16): + """ + Green Optimized Soil Adjusted Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=29 + mit Y = 0,16 + :return: index + """ + return (nir - green) / (nir + green + Y) + + def GSAVI(self, green=None, nir=None, L=0.5): + """ + Green Soil Adjusted Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=31 + mit L = 0,5 + :return: index + """ + return ((nir - green) / (nir + green + L)) * (1 + L) + + def Hue(self, red=None, green=None, blue=None): + """ + Hue + https://www.indexdatabase.de/db/i-single.php?id=34 + :return: index + """ + return np.arctan((((2 * red - green - blue) / 30.5) * (green - blue))) + + def IVI(self, red=None, nir=None, a=None, b=None): + """ + Ideal vegetation index + https://www.indexdatabase.de/db/i-single.php?id=276 + b=intercept of vegetation line + a=soil line slope + :return: index + """ + return (nir - b) / (a * red) + + def IPVI(self, red=None, nir=None): + """ + Infrared percentage vegetation index + https://www.indexdatabase.de/db/i-single.php?id=35 + :return: index + """ + return (nir / ((nir + red) / 2)) * (self.NDVI(red=red, nir=nir) + 1) + + def I(self, red=None, green=None, blue=None): + """ + Intensity + https://www.indexdatabase.de/db/i-single.php?id=36 + :return: index + """ + return (red + green + blue) / 30.5 + + def RVI(self, red=None, nir=None): + """ + Ratio-Vegetation-Index + http://www.seos-project.eu/modules/remotesensing/remotesensing-c03-s01-p01.html + :return: index + """ + return nir / red + + def MRVI(self, red=None, nir=None): + """ + Modified Normalized Difference Vegetation Index RVI + https://www.indexdatabase.de/db/i-single.php?id=275 + :return: index + """ + return (self.RVI(red=red, nir=nir) - 1) / (self.RVI(red=red, nir=nir) + 1) + + def MSAVI(self, red=None, nir=None): + """ + Modified Soil Adjusted Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=44 + :return: index + """ + return ((2 * nir + 1) - ((2 * nir + 1) ** 2 - 8 * (nir - red)) ** (1 / 2)) / 2 + + def NormG(self, red=None, green=None, nir=None): + """ + Norm G + https://www.indexdatabase.de/db/i-single.php?id=50 + :return: index + """ + return green / (nir + red + green) + + def NormNIR(self, red=None, green=None, nir=None): + """ + Norm NIR + https://www.indexdatabase.de/db/i-single.php?id=51 + :return: index + """ + return nir / (nir + red + green) + + def NormR(self, red=None, green=None, nir=None): + """ + Norm R + https://www.indexdatabase.de/db/i-single.php?id=52 + :return: index + """ + return red / (nir + red + green) + + def NGRDI(self, red=None, green=None): + """ + Normalized Difference Green/Red Normalized green red difference index, Visible Atmospherically Resistant Indices Green (VIgreen) + https://www.indexdatabase.de/db/i-single.php?id=390 + :return: index + """ + return (green - red) / (green + red) + + def RI(self, red=None, green=None): + """ + Normalized Difference Red/Green Redness Index + https://www.indexdatabase.de/db/i-single.php?id=74 + :return: index + """ + return (red - green) / (red + green) + + def S(self, red=None, green=None, blue=None): + """ + Saturation + https://www.indexdatabase.de/db/i-single.php?id=77 + :return: index + """ + max = np.max([np.max(red), np.max(green), np.max(blue)]) + min = np.min([np.min(red), np.min(green), np.min(blue)]) + return (max - min) / max + + def IF(self, red=None, green=None, blue=None): + """ + Shape Index + https://www.indexdatabase.de/db/i-single.php?id=79 + :return: index + """ + return (2 * red - green - blue) / (green - blue) + + def DVI(self, red=None, nir=None): + """ + Simple Ratio NIR/RED Difference Vegetation Index, Vegetation Index Number (VIN) + https://www.indexdatabase.de/db/i-single.php?id=12 + :return: index + """ + return nir / red + + def TVI(self, red=None, nir=None): + """ + Transformed Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=98 + :return: index + """ + return (self.NDVI(red=red, nir=nir) + 0.5) ** (1 / 2) + + def NDRE(self, redEdge=None, nir=None): + return (nir - redEdge) / (nir + redEdge) + + +""" +# genering a random matrices to test this class +red = np.ones((1000,1000, 1),dtype="float64") * 46787 +green = np.ones((1000,1000, 1),dtype="float64") * 23487 +blue = np.ones((1000,1000, 1),dtype="float64") * 14578 +redEdge = np.ones((1000,1000, 1),dtype="float64") * 51045 +nir = np.ones((1000,1000, 1),dtype="float64") * 52200 + +# Examples of how to use the class + +# instantiating the class +cl = IndexCalculation() + +# instantiating the class with the values +#cl = indexCalculation(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) + +# how set the values after instantiate the class cl, (for update the data or when dont instantiating the class with the values) +cl.setMatrices(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) + +# calculating the indices for the instantiated values in the class +indexValue = cl.calculation("CCCI").astype(np.float64) + +# calculating the index with the values directly +#indexValue = cl.directCalculation("CCCI",red=red, green=green, blue=blue, redEdge=redEdge, nir=nir).astype(np.float64) + + +print(np.array2string(indexValue, precision=20, separator=', ', floatmode='maxprec_equal')) +# A list of examples results for different type of data at 'calculation' or 'directCalculation' +# float16 -> 0.31567383 #NDVI (red = 50, nir = 100) +# float32 -> 0.31578946 #NDVI (red = 50, nir = 100) +# float64 -> 0.3157894736842105 #NDVI (red = 50, nir = 100) +# longdouble -> 0.3157894736842105 #NDVI (red = 50, nir = 100) +""" From 0ad760fc52c4c12bdbef94ebd90d6011b1aeb13a Mon Sep 17 00:00:00 2001 From: yakuza-uergsNOTE Date: Tue, 27 Aug 2019 12:52:08 -0300 Subject: [PATCH 2/6] make changes at index_calculation --- ...dexCalculation.py => index_calculation.py} | 1176 ++++++++--------- 1 file changed, 525 insertions(+), 651 deletions(-) rename digital_image_processing/{IndexCalculation.py => index_calculation.py} (56%) diff --git a/digital_image_processing/IndexCalculation.py b/digital_image_processing/index_calculation.py similarity index 56% rename from digital_image_processing/IndexCalculation.py rename to digital_image_processing/index_calculation.py index 36e33ca2a0c7..8edc41ebe19d 100644 --- a/digital_image_processing/IndexCalculation.py +++ b/digital_image_processing/index_calculation.py @@ -1,651 +1,525 @@ -# Author: João Gustavo A. Amorim -# Author email: joaogustavoamorim@gmail.com -# Coding date: jan 2019 -# python/black: True - -# Imports -import numpy as np - -# Class implemented to calculus the index -class IndexCalculation: - """ - # Class Summary - This algorithm consists in calculating vegetation indices, these indices can be used for precision agriculture for example (or remote sensing). There are functions to define the data and to calculate the implemented indices. - - # Vegetation index - https://en.wikipedia.org/wiki/Vegetation_Index - A Vegetation Index (VI) is a spectral transformation of two or more bands designed to enhance the contribution of vegetation properties and allow reliable spatial and temporal inter-comparisons of terrestrial photosynthetic activity and canopy structural variations - - # Information about channels (Wavelength range for each) - * nir - near-infrared - https://www.malvernpanalytical.com/br/products/technology/near-infrared-spectroscopy - Wavelength Range 700 nm to 2500 nm - * Red Edge - https://en.wikipedia.org/wiki/Red_edge - Wavelength Range 680 nm to 730 nm - * red - https://en.wikipedia.org/wiki/Color - Wavelength Range 635 nm to 700 nm - * blue - https://en.wikipedia.org/wiki/Color - Wavelength Range 450 nm to 490 nm - * green - https://en.wikipedia.org/wiki/Color - Wavelength Range 520 nm to 560 nm - - - # Implemented index list - #"abbreviationOfIndexName" -- list of channels used - - #"ARVI2" -- red, nir - #"CCCI" -- red, redEdge, nir - #"CVI" -- red, green, nir - #"GLI" -- red, green, blue - #"NDVI" -- red, nir - #"BNDVI" -- blue, nir - #"redEdgeNDVI" -- red, redEdge - #"GNDVI" -- green, nir - #"GBNDVI" -- green, blue, nir - #"GRNDVI" -- red, green, nir - #"RBNDVI" -- red, blue, nir - #"PNDVI" -- red, green, blue, nir - #"ATSAVI" -- red, nir - #"BWDRVI" -- blue, nir - #"CIgreen" -- green, nir - #"CIrededge" -- redEdge, nir - #"CI" -- red, blue - #"CTVI" -- red, nir - #"GDVI" -- green, nir - #"EVI" -- red, blue, nir - #"GEMI" -- red, nir - #"GOSAVI" -- green, nir - #"GSAVI" -- green, nir - #"Hue" -- red, green, blue - #"IVI" -- red, nir - #"IPVI" -- red, nir - #"I" -- red, green, blue - #"RVI" -- red, nir - #"MRVI" -- red, nir - #"MSAVI" -- red, nir - #"NormG" -- red, green, nir - #"NormNIR" -- red, green, nir - #"NormR" -- red, green, nir - #"NGRDI" -- red, green - #"RI" -- red, green - #"S" -- red, green, blue - #"IF" -- red, green, blue - #"DVI" -- red, nir - #"TVI" -- red, nir - #"NDRE" -- redEdge, nir - - #list of all index implemented - #allIndex = ["ARVI2", "CCCI", "CVI", "GLI", "NDVI", "BNDVI", "redEdgeNDVI", "GNDVI", "GBNDVI", "GRNDVI", "RBNDVI", "PNDVI", "ATSAVI", "BWDRVI", "CIgreen", "CIrededge", "CI", "CTVI", "GDVI", "EVI", "GEMI", "GOSAVI", "GSAVI", "Hue", "IVI", "IPVI", "I", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", "NormR", "NGRDI", "RI", "S", "IF", "DVI", "TVI", "NDRE"] - #list of index with not blue channel - #notBlueIndex = ["ARVI2", "CCCI", "CVI", "NDVI", "redEdgeNDVI", "GNDVI", "GRNDVI", "ATSAVI", "CIgreen", "CIrededge", "CTVI", "GDVI", "GEMI", "GOSAVI", "GSAVI", "IVI", "IPVI", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", "NormR", "NGRDI", "RI", "DVI", "TVI", "NDRE"] - #list of index just with RGB channels - #RGBIndex = ["GLI", "CI", "Hue", "I", "NGRDI", "RI", "S", "IF"] - """ - - def __init__(self, red=None, green=None, blue=None, redEdge=None, nir=None): - print("Numpy version: " + np.__version__) - self.red = red - self.green = green - self.blue = blue - self.redEdge = redEdge - self.nir = nir - - def setMatrices(self, red=None, green=None, blue=None, redEdge=None, nir=None): - self.red = red - self.green = green - self.blue = blue - self.redEdge = redEdge - self.nir = nir - return True - - def calculation(self, index=""): - """ - performs the calculation of the index with the values instantiated in the class - :str index: sigla do indice a ser calculado - """ - if index == "": - print("Not determined index!") - elif index == "ARVI2": - return self.ARVI2(red=self.red, nir=self.nir) - elif index == "CCCI": - return self.CCCI(red=self.red, redEdge=self.redEdge, nir=self.nir) - elif index == "CVI": - return self.CVI(red=self.red, green=self.green, nir=self.nir) - elif index == "GLI": - return self.GLI(red=self.red, green=self.green, blue=self.blue) - elif index == "NDVI": - return self.NDVI(red=self.red, nir=self.nir) - elif index == "BNDVI": - return self.BNDVI(blue=self.blue, nir=self.nir) - elif index == "redEdgeNDVI": - return self.redEdgeNDVI(red=self.red, redEdge=self.redEdge) - elif index == "GNDVI": - return self.GNDVI(green=self.green, nir=self.nir) - elif index == "GBNDVI": - return self.GBNDVI(green=self.green, blue=self.blue, nir=self.nir) - elif index == "GRNDVI": - return self.GRNDVI(red=self.red, green=self.green, nir=self.nir) - elif index == "RBNDVI": - return self.RBNDVI(red=self.red, blue=self.blue, nir=self.nir) - elif index == "PNDVI": - return self.PNDVI( - red=self.red, green=self.green, blue=self.blue, nir=self.nir - ) - elif index == "ATSAVI": - return self.ATSAVI(red=self.red, nir=self.nir, X=0.08, a=1.22, b=0.03) - elif index == "BWDRVI": - return self.BWDRVI(blue=self.blue, nir=self.nir) - elif index == "CIgreen": - return self.CIgreen(green=self.green, nir=self.nir) - elif index == "CIrededge": - return self.CIrededge(redEdge=self.redEdge, nir=self.nir) - elif index == "CI": - return self.CI(red=self.red, blue=self.blue) - elif index == "CTVI": - return self.CTVI(red=self.red, nir=self.nir) - elif index == "GDVI": - return self.GDVI(green=self.green, nir=self.nir) - elif index == "EVI": - return self.EVI(red=self.red, blue=self.blue, nir=self.nir) - elif index == "GEMI": - return self.GEMI(red=self.red, nir=self.nir) - elif index == "GOSAVI": - return self.GOSAVI(green=self.green, nir=self.nir, Y=0.16) - elif index == "GSAVI": - return self.GSAVI(green=self.green, nir=self.nir, L=0.5) - elif index == "Hue": - return self.Hue(red=self.red, green=self.green, blue=self.blue) - elif index == "IVI": - return self.IVI(red=self.red, nir=self.nir, a=1, b=1) - elif index == "IPVI": - return self.IPVI(red=self.red, nir=self.nir) - elif index == "I": - return self.I(red=self.red, green=self.green, blue=self.blue) - elif index == "RVI": - return self.RVI(red=self.red, nir=self.nir) - elif index == "MRVI": - return self.MRVI(red=self.red, nir=self.nir) - elif index == "MSAVI": - return self.MSAVI(red=self.red, nir=self.nir) - elif index == "NormG": - return self.NormG(red=self.red, green=self.green, nir=self.nir) - elif index == "NormNIR": - return self.NormNIR(red=self.red, green=self.green, nir=self.nir) - elif index == "NormR": - return self.NormR(red=self.red, green=self.green, nir=self.nir) - elif index == "NGRDI": - return self.NGRDI(red=self.red, green=self.green) - elif index == "RI": - return self.RI(red=self.red, green=self.green) - elif index == "S": - return self.S(red=self.red, green=self.green, blue=self.blue) - elif index == "IF": - return self.IF(red=self.red, green=self.green, blue=self.blue) - elif index == "DVI": - return self.DVI(red=self.red, nir=self.nir) - elif index == "TVI": - return self.TVI(red=self.red, nir=self.nir) - elif index == "NDRE": - return self.NDRE(redEdge=self.redEdge, nir=self.nir) - else: - print("Index not list!") - - return False - - def directCalculation( - self, index="", red=None, green=None, blue=None, redEdge=None, nir=None - ): - """ - performs the calculation of the index with the values passed by parameter - 39 indices cadastrados - :str index: sigla do indice a ser calculado - """ - if index == "": - print("Not determined index!") - elif index == "ARVI2": - return self.ARVI2(red=red, nir=nir) - elif index == "CCCI": - return self.CCCI(red=red, redEdge=redEdge, nir=nir) - elif index == "CVI": - return self.CVI(red=red, green=green, nir=nir) - elif index == "GLI": - return self.GLI(red=red, green=green, blue=blue) - elif index == "NDVI": - return self.NDVI(red=red, nir=nir) - elif index == "BNDVI": - return self.BNDVI(blue=blue, nir=nir) - elif index == "redEdgeNDVI": - return self.redEdgeNDVI(red=red, redEdge=redEdge) - elif index == "GNDVI": - return self.GNDVI(green=green, nir=nir) - elif index == "GBNDVI": - return self.GBNDVI(green=green, blue=blue, nir=nir) - elif index == "GRNDVI": - return self.GRNDVI(red=red, green=green, nir=nir) - elif index == "RBNDVI": - return self.RBNDVI(red=red, blue=blue, nir=nir) - elif index == "PNDVI": - return self.PNDVI(red=red, green=green, blue=blue, nir=nir) - elif index == "ATSAVI": - return self.ATSAVI(red=red, nir=nir, X=0.08, a=1.22, b=0.03) - elif index == "BWDRVI": - return self.BWDRVI(blue=blue, nir=nir) - elif index == "CIgreen": - return self.CIgreen(green=green, nir=nir) - elif index == "CIrededge": - return self.CIrededge(redEdge=redEdge, nir=nir) - elif index == "CI": - return self.CI(red=red, blue=blue) - elif index == "CTVI": - return self.CTVI(red=red, nir=nir) - elif index == "GDVI": - return self.GDVI(green=green, nir=nir) - elif index == "EVI": - return self.EVI(red=red, blue=blue, nir=nir) - elif index == "GEMI": - return self.GEMI(red=red, nir=nir) - elif index == "GOSAVI": - return self.GOSAVI(green=green, nir=nir, Y=0.16) - elif index == "GSAVI": - return self.GSAVI(green=green, nir=nir, L=0.5) - elif index == "Hue": - return self.Hue(red=red, green=green, blue=blue) - elif index == "IVI": - return self.IVI(red=red, nir=nir, a=1, b=1) - elif index == "IPVI": - return self.IPVI(red=red, nir=nir) - elif index == "I": - return self.I(red=red, green=green, blue=blue) - elif index == "RVI": - return self.RVI(red=red, nir=nir) - elif index == "MRVI": - return self.MRVI(red=red, nir=nir) - elif index == "MSAVI": - return self.MSAVI(red=red, nir=nir) - elif index == "NormG": - return self.NormG(red=red, green=green, nir=nir) - elif index == "NormNIR": - return self.NormNIR(red=red, green=green, nir=nir) - elif index == "NormR": - return self.NormR(red=red, green=green, nir=nir) - elif index == "NGRDI": - return self.NGRDI(red=red, green=green) - elif index == "RI": - return self.RI(red=red, green=green) - elif index == "S": - return self.S(red=red, green=green, blue=blue) - elif index == "IF": - return self.IF(red=red, green=green, blue=blue) - elif index == "DVI": - return self.DVI(red=red, nir=nir) - elif index == "TVI": - return self.TVI(red=red, nir=nir) - elif index == "NDRE": - return self.NDRE(redEdge=redEdge, nir=nir) - else: - print("Index not list!") - - return False - - def ARVI2(self, red=None, nir=None): - """ - Atmospherically Resistant Vegetation Index 2 - https://www.indexdatabase.de/db/i-single.php?id=396 - :return: index - −0.18+1.17*(NIR−RED)/(NIR+RED) - """ - return -0.18 + (1.17 * ((nir - red) / (nir + red))) - - def CCCI(self, red=None, redEdge=None, nir=None): - """ - Canopy Chlorophyll Content Index - https://www.indexdatabase.de/db/i-single.php?id=224 - :return: index - """ - return ((nir - redEdge) / (nir + redEdge)) / ((nir - red) / (nir + red)) - - def CVI(self, red=None, green=None, nir=None): - """ - Chlorophyll vegetation index - https://www.indexdatabase.de/db/i-single.php?id=391 - :return: index - """ - return nir * (red / (green ** 2)) - - def GLI(self, red=None, green=None, blue=None): - """ - Green leaf index - https://www.indexdatabase.de/db/i-single.php?id=375 - :return: index - """ - return (2 * green - red - blue) / (2 * green + red + blue) - - def NDVI(self, red=None, nir=None): - """ - Normalized Difference NIR/Red Normalized Difference Vegetation Index, Calibrated NDVI - CDVI - https://www.indexdatabase.de/db/i-single.php?id=58 - :return: index - """ - return (nir - red) / (nir + red) - - def BNDVI(self, blue=None, nir=None): - """ - Normalized Difference NIR/Blue Blue-normalized difference vegetation index - https://www.indexdatabase.de/db/i-single.php?id=135 - :return: index - """ - return (nir - blue) / (nir + blue) - - def redEdgeNDVI(self, red=None, redEdge=None): - """ - Normalized Difference Rededge/Red - https://www.indexdatabase.de/db/i-single.php?id=235 - :return: index - """ - return (redEdge - red) / (redEdge + red) - - def GNDVI(self, green=None, nir=None): - """ - Normalized Difference NIR/Green Green NDVI - https://www.indexdatabase.de/db/i-single.php?id=401 - :return: index - """ - return (nir - green) / (nir + green) - - def GBNDVI(self, green=None, blue=None, nir=None): - """ - Green-Blue NDVI - https://www.indexdatabase.de/db/i-single.php?id=186 - :return: index - """ - return (nir - (green + blue)) / (nir + (green + blue)) - - def GRNDVI(self, red=None, green=None, nir=None): - """ - Green-Red NDVI - https://www.indexdatabase.de/db/i-single.php?id=185 - :return: index - """ - return (nir - (green + red)) / (nir + (green + red)) - - def RBNDVI(self, red=None, blue=None, nir=None): - """ - Red-Blue NDVI - https://www.indexdatabase.de/db/i-single.php?id=187 - :return: index - """ - return (nir - (blue + red)) / (nir + (blue + red)) - - def PNDVI(self, red=None, green=None, blue=None, nir=None): - """ - Pan NDVI - https://www.indexdatabase.de/db/i-single.php?id=188 - :return: index - """ - return (nir - (green + red + blue)) / (nir + (green + red + blue)) - - def ATSAVI(self, red=None, nir=None, X=0.08, a=1.22, b=0.03): - """ - Adjusted transformed soil-adjusted VI - https://www.indexdatabase.de/db/i-single.php?id=209 - :return: index - """ - return a * ((nir - a * red - b) / (a * nir + red - a * b + X * (1 + a ** 2))) - - def BWDRVI(self, blue=None, nir=None): - """ - Blue-wide dynamic range vegetation index - https://www.indexdatabase.de/db/i-single.php?id=136 - :return: index - """ - return (0.1 * nir - blue) / (0.1 * nir + blue) - - def CIgreen(self, green=None, nir=None): - """ - Chlorophyll Index Green - https://www.indexdatabase.de/db/i-single.php?id=128 - :return: index - """ - return (nir / green) - 1 - - def CIrededge(self, redEdge=None, nir=None): - """ - Chlorophyll Index RedEdge - https://www.indexdatabase.de/db/i-single.php?id=131 - :return: index - """ - return (nir / redEdge) - 1 - - def CI(self, red=None, blue=None): - """ - Coloration Index - https://www.indexdatabase.de/db/i-single.php?id=11 - :return: index - """ - return (red - blue) / red - - def CTVI(self, red=None, nir=None): - """ - Corrected Transformed Vegetation Index - https://www.indexdatabase.de/db/i-single.php?id=244 - :return: index - """ - ndvi = self.NDVI(red=red, nir=nir) - return ((ndvi + 0.5) / (abs(ndvi + 0.5))) * (abs(ndvi + 0.5) ** (1 / 2)) - - def GDVI(self, green=None, nir=None): - """ - Difference NIR/Green Green Difference Vegetation Index - https://www.indexdatabase.de/db/i-single.php?id=27 - :return: index - """ - return nir - green - - def EVI(self, red=None, blue=None, nir=None): - """ - Enhanced Vegetation Index - https://www.indexdatabase.de/db/i-single.php?id=16 - :return: index - """ - return 2.5 * ((nir - red) / (nir + 6 * red - 7.5 * blue + 1)) - - def GEMI(self, red=None, nir=None): - """ - Global Environment Monitoring Index - https://www.indexdatabase.de/db/i-single.php?id=25 - :return: index - """ - n = (2 * (nir ** 2 - red ** 2) + 1.5 * nir + 0.5 * red) / (nir + red + 0.5) - return n * (1 - 0.25 * n) - (red - 0.125) / (1 - red) - - def GOSAVI(self, green=None, nir=None, Y=0.16): - """ - Green Optimized Soil Adjusted Vegetation Index - https://www.indexdatabase.de/db/i-single.php?id=29 - mit Y = 0,16 - :return: index - """ - return (nir - green) / (nir + green + Y) - - def GSAVI(self, green=None, nir=None, L=0.5): - """ - Green Soil Adjusted Vegetation Index - https://www.indexdatabase.de/db/i-single.php?id=31 - mit L = 0,5 - :return: index - """ - return ((nir - green) / (nir + green + L)) * (1 + L) - - def Hue(self, red=None, green=None, blue=None): - """ - Hue - https://www.indexdatabase.de/db/i-single.php?id=34 - :return: index - """ - return np.arctan((((2 * red - green - blue) / 30.5) * (green - blue))) - - def IVI(self, red=None, nir=None, a=None, b=None): - """ - Ideal vegetation index - https://www.indexdatabase.de/db/i-single.php?id=276 - b=intercept of vegetation line - a=soil line slope - :return: index - """ - return (nir - b) / (a * red) - - def IPVI(self, red=None, nir=None): - """ - Infrared percentage vegetation index - https://www.indexdatabase.de/db/i-single.php?id=35 - :return: index - """ - return (nir / ((nir + red) / 2)) * (self.NDVI(red=red, nir=nir) + 1) - - def I(self, red=None, green=None, blue=None): - """ - Intensity - https://www.indexdatabase.de/db/i-single.php?id=36 - :return: index - """ - return (red + green + blue) / 30.5 - - def RVI(self, red=None, nir=None): - """ - Ratio-Vegetation-Index - http://www.seos-project.eu/modules/remotesensing/remotesensing-c03-s01-p01.html - :return: index - """ - return nir / red - - def MRVI(self, red=None, nir=None): - """ - Modified Normalized Difference Vegetation Index RVI - https://www.indexdatabase.de/db/i-single.php?id=275 - :return: index - """ - return (self.RVI(red=red, nir=nir) - 1) / (self.RVI(red=red, nir=nir) + 1) - - def MSAVI(self, red=None, nir=None): - """ - Modified Soil Adjusted Vegetation Index - https://www.indexdatabase.de/db/i-single.php?id=44 - :return: index - """ - return ((2 * nir + 1) - ((2 * nir + 1) ** 2 - 8 * (nir - red)) ** (1 / 2)) / 2 - - def NormG(self, red=None, green=None, nir=None): - """ - Norm G - https://www.indexdatabase.de/db/i-single.php?id=50 - :return: index - """ - return green / (nir + red + green) - - def NormNIR(self, red=None, green=None, nir=None): - """ - Norm NIR - https://www.indexdatabase.de/db/i-single.php?id=51 - :return: index - """ - return nir / (nir + red + green) - - def NormR(self, red=None, green=None, nir=None): - """ - Norm R - https://www.indexdatabase.de/db/i-single.php?id=52 - :return: index - """ - return red / (nir + red + green) - - def NGRDI(self, red=None, green=None): - """ - Normalized Difference Green/Red Normalized green red difference index, Visible Atmospherically Resistant Indices Green (VIgreen) - https://www.indexdatabase.de/db/i-single.php?id=390 - :return: index - """ - return (green - red) / (green + red) - - def RI(self, red=None, green=None): - """ - Normalized Difference Red/Green Redness Index - https://www.indexdatabase.de/db/i-single.php?id=74 - :return: index - """ - return (red - green) / (red + green) - - def S(self, red=None, green=None, blue=None): - """ - Saturation - https://www.indexdatabase.de/db/i-single.php?id=77 - :return: index - """ - max = np.max([np.max(red), np.max(green), np.max(blue)]) - min = np.min([np.min(red), np.min(green), np.min(blue)]) - return (max - min) / max - - def IF(self, red=None, green=None, blue=None): - """ - Shape Index - https://www.indexdatabase.de/db/i-single.php?id=79 - :return: index - """ - return (2 * red - green - blue) / (green - blue) - - def DVI(self, red=None, nir=None): - """ - Simple Ratio NIR/RED Difference Vegetation Index, Vegetation Index Number (VIN) - https://www.indexdatabase.de/db/i-single.php?id=12 - :return: index - """ - return nir / red - - def TVI(self, red=None, nir=None): - """ - Transformed Vegetation Index - https://www.indexdatabase.de/db/i-single.php?id=98 - :return: index - """ - return (self.NDVI(red=red, nir=nir) + 0.5) ** (1 / 2) - - def NDRE(self, redEdge=None, nir=None): - return (nir - redEdge) / (nir + redEdge) - - -""" -# genering a random matrices to test this class -red = np.ones((1000,1000, 1),dtype="float64") * 46787 -green = np.ones((1000,1000, 1),dtype="float64") * 23487 -blue = np.ones((1000,1000, 1),dtype="float64") * 14578 -redEdge = np.ones((1000,1000, 1),dtype="float64") * 51045 -nir = np.ones((1000,1000, 1),dtype="float64") * 52200 - -# Examples of how to use the class - -# instantiating the class -cl = IndexCalculation() - -# instantiating the class with the values -#cl = indexCalculation(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) - -# how set the values after instantiate the class cl, (for update the data or when dont instantiating the class with the values) -cl.setMatrices(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) - -# calculating the indices for the instantiated values in the class -indexValue = cl.calculation("CCCI").astype(np.float64) - -# calculating the index with the values directly -#indexValue = cl.directCalculation("CCCI",red=red, green=green, blue=blue, redEdge=redEdge, nir=nir).astype(np.float64) - - -print(np.array2string(indexValue, precision=20, separator=', ', floatmode='maxprec_equal')) -# A list of examples results for different type of data at 'calculation' or 'directCalculation' -# float16 -> 0.31567383 #NDVI (red = 50, nir = 100) -# float32 -> 0.31578946 #NDVI (red = 50, nir = 100) -# float64 -> 0.3157894736842105 #NDVI (red = 50, nir = 100) -# longdouble -> 0.3157894736842105 #NDVI (red = 50, nir = 100) -""" +# Author: João Gustavo A. Amorim +# Author email: joaogustavoamorim@gmail.com +# Coding date: jan 2019 +# python/black: True + +# Imports +import numpy as np + +# Class implemented to calculus the index +class IndexCalculation: + """ + # Class Summary + This algorithm consists in calculating vegetation indices, these indices can be used for precision agriculture for example (or remote sensing). There are functions to define the data and to calculate the implemented indices. + + # Vegetation index + https://en.wikipedia.org/wiki/Vegetation_Index + A Vegetation Index (VI) is a spectral transformation of two or more bands designed to enhance the contribution of vegetation properties and allow reliable spatial and temporal inter-comparisons of terrestrial photosynthetic activity and canopy structural variations + + # Information about channels (Wavelength range for each) + * nir - near-infrared + https://www.malvernpanalytical.com/br/products/technology/near-infrared-spectroscopy + Wavelength Range 700 nm to 2500 nm + * Red Edge + https://en.wikipedia.org/wiki/Red_edge + Wavelength Range 680 nm to 730 nm + * red + https://en.wikipedia.org/wiki/Color + Wavelength Range 635 nm to 700 nm + * blue + https://en.wikipedia.org/wiki/Color + Wavelength Range 450 nm to 490 nm + * green + https://en.wikipedia.org/wiki/Color + Wavelength Range 520 nm to 560 nm + + + # Implemented index list + #"abbreviationOfIndexName" -- list of channels used + + #"ARVI2" -- red, nir + #"CCCI" -- red, redEdge, nir + #"CVI" -- red, green, nir + #"GLI" -- red, green, blue + #"NDVI" -- red, nir + #"BNDVI" -- blue, nir + #"redEdgeNDVI" -- red, redEdge + #"GNDVI" -- green, nir + #"GBNDVI" -- green, blue, nir + #"GRNDVI" -- red, green, nir + #"RBNDVI" -- red, blue, nir + #"PNDVI" -- red, green, blue, nir + #"ATSAVI" -- red, nir + #"BWDRVI" -- blue, nir + #"CIgreen" -- green, nir + #"CIrededge" -- redEdge, nir + #"CI" -- red, blue + #"CTVI" -- red, nir + #"GDVI" -- green, nir + #"EVI" -- red, blue, nir + #"GEMI" -- red, nir + #"GOSAVI" -- green, nir + #"GSAVI" -- green, nir + #"Hue" -- red, green, blue + #"IVI" -- red, nir + #"IPVI" -- red, nir + #"I" -- red, green, blue + #"RVI" -- red, nir + #"MRVI" -- red, nir + #"MSAVI" -- red, nir + #"NormG" -- red, green, nir + #"NormNIR" -- red, green, nir + #"NormR" -- red, green, nir + #"NGRDI" -- red, green + #"RI" -- red, green + #"S" -- red, green, blue + #"IF" -- red, green, blue + #"DVI" -- red, nir + #"TVI" -- red, nir + #"NDRE" -- redEdge, nir + + #list of all index implemented + #allIndex = ["ARVI2", "CCCI", "CVI", "GLI", "NDVI", "BNDVI", "redEdgeNDVI", "GNDVI", "GBNDVI", "GRNDVI", "RBNDVI", "PNDVI", "ATSAVI", "BWDRVI", "CIgreen", "CIrededge", "CI", "CTVI", "GDVI", "EVI", "GEMI", "GOSAVI", "GSAVI", "Hue", "IVI", "IPVI", "I", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", "NormR", "NGRDI", "RI", "S", "IF", "DVI", "TVI", "NDRE"] + #list of index with not blue channel + #notBlueIndex = ["ARVI2", "CCCI", "CVI", "NDVI", "redEdgeNDVI", "GNDVI", "GRNDVI", "ATSAVI", "CIgreen", "CIrededge", "CTVI", "GDVI", "GEMI", "GOSAVI", "GSAVI", "IVI", "IPVI", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", "NormR", "NGRDI", "RI", "DVI", "TVI", "NDRE"] + #list of index just with RGB channels + #RGBIndex = ["GLI", "CI", "Hue", "I", "NGRDI", "RI", "S", "IF"] + """ + + def __init__(self, red=None, green=None, blue=None, redEdge=None, nir=None): + # print("Numpy version: " + np.__version__) + self.setMatrices(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) + + def setMatrices(self, red=None, green=None, blue=None, redEdge=None, nir=None): + if red is None: + self.red = red + if green is None: + self.green = green + if blue is None: + self.blue = blue + if redEdge is None: + self.redEdge = redEdge + if nir is None: + self.nir = nir + return True + + def calculation( + self, index="", red=None, green=None, blue=None, redEdge=None, nir=None + ): + """ + performs the calculation of the index with the values instantiated in the class + :str index: abbreviation of index name to perform + """ + self.setMatrices(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) + funcs = { + "ARVI2": self.ARVI2, + "CCCI": self.CCCI, + "CVI": self.CVI, + "GLI": self.GLI, + "NDVI": self.NDVI, + "BNDVI": self.BNDVI, + "redEdgeNDVI": self.redEdgeNDVI, + "GNDVI": self.GNDVI, + "GBNDVI": self.GBNDVI, + "GRNDVI": self.GRNDVI, + "RBNDVI": self.RBNDVI, + "PNDVI": self.PNDVI, + "ATSAVI": self.ATSAVI, + "BWDRVI": self.BWDRVI, + "CIgreen": self.CIgreen, + "CIrededge": self.CIrededge, + "CI": self.CI, + "CTVI": self.CTVI, + "GDVI": self.GDVI, + "EVI": self.EVI, + "GEMI": self.GEMI, + "GOSAVI": self.GOSAVI, + "GSAVI": self.GSAVI, + "Hue": self.Hue, + "IVI": self.IVI, + "IPVI": self.IPVI, + "I": self.I, + "RVI": self.RVI, + "MRVI": self.MRVI, + "MSAVI": self.MSAVI, + "NormG": self.NormG, + "NormNIR": self.NormNIR, + "NormR": self.NormR, + "NGRDI": self.NGRDI, + "RI": self.RI, + "S": self.S, + "IF": self.IF, + "DVI": self.DVI, + "TVI": self.TVI, + "NDRE": self.NDRE, + } + + try: + return funcs[index]() + except KeyError: + print("Index not in the list!") + return False + + def ARVI2(self): + """ + Atmospherically Resistant Vegetation Index 2 + https://www.indexdatabase.de/db/i-single.php?id=396 + :return: index + −0.18+1.17*(NIR−RED)/(NIR+RED) + """ + return -0.18 + (1.17 * ((nir - red) / (nir + red))) + + def CCCI(self): + """ + Canopy Chlorophyll Content Index + https://www.indexdatabase.de/db/i-single.php?id=224 + :return: index + """ + return ((nir - redEdge) / (nir + redEdge)) / ((nir - red) / (nir + red)) + + def CVI(self): + """ + Chlorophyll vegetation index + https://www.indexdatabase.de/db/i-single.php?id=391 + :return: index + """ + return nir * (red / (green ** 2)) + + def GLI(self): + """ + Green leaf index + https://www.indexdatabase.de/db/i-single.php?id=375 + :return: index + """ + return (2 * green - red - blue) / (2 * green + red + blue) + + def NDVI(self): + """ + Normalized Difference NIR/Red Normalized Difference Vegetation Index, Calibrated NDVI - CDVI + https://www.indexdatabase.de/db/i-single.php?id=58 + :return: index + """ + return (nir - red) / (nir + red) + + def BNDVI(self): + """ + Normalized Difference NIR/Blue Blue-normalized difference vegetation index + https://www.indexdatabase.de/db/i-single.php?id=135 + :return: index + """ + return (nir - blue) / (nir + blue) + + def redEdgeNDVI(self): + """ + Normalized Difference Rededge/Red + https://www.indexdatabase.de/db/i-single.php?id=235 + :return: index + """ + return (redEdge - red) / (redEdge + red) + + def GNDVI(self): + """ + Normalized Difference NIR/Green Green NDVI + https://www.indexdatabase.de/db/i-single.php?id=401 + :return: index + """ + return (nir - green) / (nir + green) + + def GBNDVI(self): + """ + Green-Blue NDVI + https://www.indexdatabase.de/db/i-single.php?id=186 + :return: index + """ + return (nir - (green + blue)) / (nir + (green + blue)) + + def GRNDVI(self): + """ + Green-Red NDVI + https://www.indexdatabase.de/db/i-single.php?id=185 + :return: index + """ + return (nir - (green + red)) / (nir + (green + red)) + + def RBNDVI(self): + """ + Red-Blue NDVI + https://www.indexdatabase.de/db/i-single.php?id=187 + :return: index + """ + return (nir - (blue + red)) / (nir + (blue + red)) + + def PNDVI(self): + """ + Pan NDVI + https://www.indexdatabase.de/db/i-single.php?id=188 + :return: index + """ + return (nir - (green + red + blue)) / (nir + (green + red + blue)) + + def ATSAVI(self, X=0.08, a=1.22, b=0.03): + """ + Adjusted transformed soil-adjusted VI + https://www.indexdatabase.de/db/i-single.php?id=209 + :return: index + """ + return a * ((nir - a * red - b) / (a * nir + red - a * b + X * (1 + a ** 2))) + + def BWDRVI(self): + """ + Blue-wide dynamic range vegetation index + https://www.indexdatabase.de/db/i-single.php?id=136 + :return: index + """ + return (0.1 * nir - blue) / (0.1 * nir + blue) + + def CIgreen(self): + """ + Chlorophyll Index Green + https://www.indexdatabase.de/db/i-single.php?id=128 + :return: index + """ + return (nir / green) - 1 + + def CIrededge(self): + """ + Chlorophyll Index RedEdge + https://www.indexdatabase.de/db/i-single.php?id=131 + :return: index + """ + return (nir / redEdge) - 1 + + def CI(self): + """ + Coloration Index + https://www.indexdatabase.de/db/i-single.php?id=11 + :return: index + """ + return (red - blue) / red + + def CTVI(self): + """ + Corrected Transformed Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=244 + :return: index + """ + ndvi = self.NDVI() + return ((ndvi + 0.5) / (abs(ndvi + 0.5))) * (abs(ndvi + 0.5) ** (1 / 2)) + + def GDVI(self): + """ + Difference NIR/Green Green Difference Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=27 + :return: index + """ + return nir - green + + def EVI(self): + """ + Enhanced Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=16 + :return: index + """ + return 2.5 * ((nir - red) / (nir + 6 * red - 7.5 * blue + 1)) + + def GEMI(self): + """ + Global Environment Monitoring Index + https://www.indexdatabase.de/db/i-single.php?id=25 + :return: index + """ + n = (2 * (nir ** 2 - red ** 2) + 1.5 * nir + 0.5 * red) / (nir + red + 0.5) + return n * (1 - 0.25 * n) - (red - 0.125) / (1 - red) + + def GOSAVI(self, Y=0.16): + """ + Green Optimized Soil Adjusted Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=29 + mit Y = 0,16 + :return: index + """ + return (nir - green) / (nir + green + Y) + + def GSAVI(self, L=0.5): + """ + Green Soil Adjusted Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=31 + mit L = 0,5 + :return: index + """ + return ((nir - green) / (nir + green + L)) * (1 + L) + + def Hue(self): + """ + Hue + https://www.indexdatabase.de/db/i-single.php?id=34 + :return: index + """ + return np.arctan((((2 * red - green - blue) / 30.5) * (green - blue))) + + def IVI(self, a=None, b=None): + """ + Ideal vegetation index + https://www.indexdatabase.de/db/i-single.php?id=276 + b=intercept of vegetation line + a=soil line slope + :return: index + """ + return (nir - b) / (a * red) + + def IPVI(self): + """ + Infrared percentage vegetation index + https://www.indexdatabase.de/db/i-single.php?id=35 + :return: index + """ + return (nir / ((nir + red) / 2)) * (self.NDVI() + 1) + + def I(self): + """ + Intensity + https://www.indexdatabase.de/db/i-single.php?id=36 + :return: index + """ + return (red + green + blue) / 30.5 + + def RVI(self): + """ + Ratio-Vegetation-Index + http://www.seos-project.eu/modules/remotesensing/remotesensing-c03-s01-p01.html + :return: index + """ + return nir / red + + def MRVI(self): + """ + Modified Normalized Difference Vegetation Index RVI + https://www.indexdatabase.de/db/i-single.php?id=275 + :return: index + """ + return (self.RVI() - 1) / (self.RVI() + 1) + + def MSAVI(self): + """ + Modified Soil Adjusted Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=44 + :return: index + """ + return ((2 * nir + 1) - ((2 * nir + 1) ** 2 - 8 * (nir - red)) ** (1 / 2)) / 2 + + def NormG(self): + """ + Norm G + https://www.indexdatabase.de/db/i-single.php?id=50 + :return: index + """ + return green / (nir + red + green) + + def NormNIR(self): + """ + Norm NIR + https://www.indexdatabase.de/db/i-single.php?id=51 + :return: index + """ + return nir / (nir + red + green) + + def NormR(self): + """ + Norm R + https://www.indexdatabase.de/db/i-single.php?id=52 + :return: index + """ + return red / (nir + red + green) + + def NGRDI(self): + """ + Normalized Difference Green/Red Normalized green red difference index, Visible Atmospherically Resistant Indices Green (VIgreen) + https://www.indexdatabase.de/db/i-single.php?id=390 + :return: index + """ + return (green - red) / (green + red) + + def RI(self): + """ + Normalized Difference Red/Green Redness Index + https://www.indexdatabase.de/db/i-single.php?id=74 + :return: index + """ + return (red - green) / (red + green) + + def S(self): + """ + Saturation + https://www.indexdatabase.de/db/i-single.php?id=77 + :return: index + """ + max = np.max([np.max(red), np.max(green), np.max(blue)]) + min = np.min([np.min(red), np.min(green), np.min(blue)]) + return (max - min) / max + + def IF(self): + """ + Shape Index + https://www.indexdatabase.de/db/i-single.php?id=79 + :return: index + """ + return (2 * red - green - blue) / (green - blue) + + def DVI(self): + """ + Simple Ratio NIR/RED Difference Vegetation Index, Vegetation Index Number (VIN) + https://www.indexdatabase.de/db/i-single.php?id=12 + :return: index + """ + return nir / red + + def TVI(self): + """ + Transformed Vegetation Index + https://www.indexdatabase.de/db/i-single.php?id=98 + :return: index + """ + return (self.NDVI() + 0.5) ** (1 / 2) + + def NDRE(self): + return (nir - redEdge) / (nir + redEdge) + + +""" +# genering a random matrices to test this class +red = np.ones((1000,1000, 1),dtype="float64") * 46787 +green = np.ones((1000,1000, 1),dtype="float64") * 23487 +blue = np.ones((1000,1000, 1),dtype="float64") * 14578 +redEdge = np.ones((1000,1000, 1),dtype="float64") * 51045 +nir = np.ones((1000,1000, 1),dtype="float64") * 52200 + +# Examples of how to use the class + +# instantiating the class +cl = IndexCalculation() + +# instantiating the class with the values +#cl = indexCalculation(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) + +# how set the values after instantiate the class cl, (for update the data or when dont instantiating the class with the values) +cl.setMatrices(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) + +# calculating the indices for the instantiated values in the class + # Note: the CCCI index can be changed to any index implemented in the class. +indexValue_form1 = cl.calculation("CCCI").astype(np.float64) +indexValue_form2 = cl.CCCI() + +# calculating the index with the values directly -- you can set just the values preferred -- note: the *calculation* fuction performs the function *setMatrices* +indexValue_form3 = cl.calculation("CCCI", red=red, green=green, blue=blue, redEdge=redEdge, nir=nir).astype(np.float64) + + +print("Form 1: "+np.array2string(indexValue_form1, precision=20, separator=', ', floatmode='maxprec_equal')) +print("Form 2: "+np.array2string(indexValue_form2, precision=20, separator=', ', floatmode='maxprec_equal')) +print("Form 3: "+np.array2string(indexValue_form3, precision=20, separator=', ', floatmode='maxprec_equal')) + +# A list of examples results for different type of data at NDVI +# float16 -> 0.31567383 #NDVI (red = 50, nir = 100) +# float32 -> 0.31578946 #NDVI (red = 50, nir = 100) +# float64 -> 0.3157894736842105 #NDVI (red = 50, nir = 100) +# longdouble -> 0.3157894736842105 #NDVI (red = 50, nir = 100) +""" From c3b7210b7bf7a68781b6282a53120cc8d0cdd07d Mon Sep 17 00:00:00 2001 From: yakuza-uergsNOTE Date: Tue, 27 Aug 2019 13:59:09 -0300 Subject: [PATCH 3/6] update the variables to self variables at functions --- digital_image_processing/index_calculation.py | 155 ++++++++++-------- 1 file changed, 90 insertions(+), 65 deletions(-) diff --git a/digital_image_processing/index_calculation.py b/digital_image_processing/index_calculation.py index 8edc41ebe19d..e1e1d5f7e6b4 100644 --- a/digital_image_processing/index_calculation.py +++ b/digital_image_processing/index_calculation.py @@ -91,15 +91,15 @@ def __init__(self, red=None, green=None, blue=None, redEdge=None, nir=None): self.setMatrices(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) def setMatrices(self, red=None, green=None, blue=None, redEdge=None, nir=None): - if red is None: + if red is not None: self.red = red - if green is None: + if green is not None: self.green = green - if blue is None: + if blue is not None: self.blue = blue - if redEdge is None: + if redEdge is not None: self.redEdge = redEdge - if nir is None: + if nir is not None: self.nir = nir return True @@ -165,9 +165,9 @@ def ARVI2(self): Atmospherically Resistant Vegetation Index 2 https://www.indexdatabase.de/db/i-single.php?id=396 :return: index - −0.18+1.17*(NIR−RED)/(NIR+RED) + −0.18+1.17*(self.nir−self.red)/(self.nir+self.red) """ - return -0.18 + (1.17 * ((nir - red) / (nir + red))) + return -0.18 + (1.17 * ((self.nir - self.red) / (self.nir + self.red))) def CCCI(self): """ @@ -175,7 +175,9 @@ def CCCI(self): https://www.indexdatabase.de/db/i-single.php?id=224 :return: index """ - return ((nir - redEdge) / (nir + redEdge)) / ((nir - red) / (nir + red)) + return ((self.nir - self.redEdge) / (self.nir + self.redEdge)) / ( + (self.nir - self.red) / (self.nir + self.red) + ) def CVI(self): """ @@ -183,71 +185,77 @@ def CVI(self): https://www.indexdatabase.de/db/i-single.php?id=391 :return: index """ - return nir * (red / (green ** 2)) + return self.nir * (self.red / (self.green ** 2)) def GLI(self): """ - Green leaf index + self.green leaf index https://www.indexdatabase.de/db/i-single.php?id=375 :return: index """ - return (2 * green - red - blue) / (2 * green + red + blue) + return (2 * self.green - self.red - self.blue) / ( + 2 * self.green + self.red + self.blue + ) def NDVI(self): """ - Normalized Difference NIR/Red Normalized Difference Vegetation Index, Calibrated NDVI - CDVI + Normalized Difference self.nir/self.red Normalized Difference Vegetation Index, Calibrated NDVI - CDVI https://www.indexdatabase.de/db/i-single.php?id=58 :return: index """ - return (nir - red) / (nir + red) + return (self.nir - self.red) / (self.nir + self.red) def BNDVI(self): """ - Normalized Difference NIR/Blue Blue-normalized difference vegetation index + Normalized Difference self.nir/self.blue self.blue-normalized difference vegetation index https://www.indexdatabase.de/db/i-single.php?id=135 :return: index """ - return (nir - blue) / (nir + blue) + return (self.nir - self.blue) / (self.nir + self.blue) def redEdgeNDVI(self): """ - Normalized Difference Rededge/Red + Normalized Difference self.rededge/self.red https://www.indexdatabase.de/db/i-single.php?id=235 :return: index """ - return (redEdge - red) / (redEdge + red) + return (self.redEdge - self.red) / (self.redEdge + self.red) def GNDVI(self): """ - Normalized Difference NIR/Green Green NDVI + Normalized Difference self.nir/self.green self.green NDVI https://www.indexdatabase.de/db/i-single.php?id=401 :return: index """ - return (nir - green) / (nir + green) + return (self.nir - self.green) / (self.nir + self.green) def GBNDVI(self): """ - Green-Blue NDVI + self.green-self.blue NDVI https://www.indexdatabase.de/db/i-single.php?id=186 :return: index """ - return (nir - (green + blue)) / (nir + (green + blue)) + return (self.nir - (self.green + self.blue)) / ( + self.nir + (self.green + self.blue) + ) def GRNDVI(self): """ - Green-Red NDVI + self.green-self.red NDVI https://www.indexdatabase.de/db/i-single.php?id=185 :return: index """ - return (nir - (green + red)) / (nir + (green + red)) + return (self.nir - (self.green + self.red)) / ( + self.nir + (self.green + self.red) + ) def RBNDVI(self): """ - Red-Blue NDVI + self.red-self.blue NDVI https://www.indexdatabase.de/db/i-single.php?id=187 :return: index """ - return (nir - (blue + red)) / (nir + (blue + red)) + return (self.nir - (self.blue + self.red)) / (self.nir + (self.blue + self.red)) def PNDVI(self): """ @@ -255,7 +263,9 @@ def PNDVI(self): https://www.indexdatabase.de/db/i-single.php?id=188 :return: index """ - return (nir - (green + red + blue)) / (nir + (green + red + blue)) + return (self.nir - (self.green + self.red + self.blue)) / ( + self.nir + (self.green + self.red + self.blue) + ) def ATSAVI(self, X=0.08, a=1.22, b=0.03): """ @@ -263,31 +273,34 @@ def ATSAVI(self, X=0.08, a=1.22, b=0.03): https://www.indexdatabase.de/db/i-single.php?id=209 :return: index """ - return a * ((nir - a * red - b) / (a * nir + red - a * b + X * (1 + a ** 2))) + return a * ( + (self.nir - a * self.red - b) + / (a * self.nir + self.red - a * b + X * (1 + a ** 2)) + ) def BWDRVI(self): """ - Blue-wide dynamic range vegetation index + self.blue-wide dynamic range vegetation index https://www.indexdatabase.de/db/i-single.php?id=136 :return: index """ - return (0.1 * nir - blue) / (0.1 * nir + blue) + return (0.1 * self.nir - self.blue) / (0.1 * self.nir + self.blue) def CIgreen(self): """ - Chlorophyll Index Green + Chlorophyll Index self.green https://www.indexdatabase.de/db/i-single.php?id=128 :return: index """ - return (nir / green) - 1 + return (self.nir / self.green) - 1 def CIrededge(self): """ - Chlorophyll Index RedEdge + Chlorophyll Index self.redEdge https://www.indexdatabase.de/db/i-single.php?id=131 :return: index """ - return (nir / redEdge) - 1 + return (self.nir / self.redEdge) - 1 def CI(self): """ @@ -295,7 +308,7 @@ def CI(self): https://www.indexdatabase.de/db/i-single.php?id=11 :return: index """ - return (red - blue) / red + return (self.red - self.blue) / self.red def CTVI(self): """ @@ -308,11 +321,11 @@ def CTVI(self): def GDVI(self): """ - Difference NIR/Green Green Difference Vegetation Index + Difference self.nir/self.green self.green Difference Vegetation Index https://www.indexdatabase.de/db/i-single.php?id=27 :return: index """ - return nir - green + return self.nir - self.green def EVI(self): """ @@ -320,7 +333,9 @@ def EVI(self): https://www.indexdatabase.de/db/i-single.php?id=16 :return: index """ - return 2.5 * ((nir - red) / (nir + 6 * red - 7.5 * blue + 1)) + return 2.5 * ( + (self.nir - self.red) / (self.nir + 6 * self.red - 7.5 * self.blue + 1) + ) def GEMI(self): """ @@ -328,26 +343,28 @@ def GEMI(self): https://www.indexdatabase.de/db/i-single.php?id=25 :return: index """ - n = (2 * (nir ** 2 - red ** 2) + 1.5 * nir + 0.5 * red) / (nir + red + 0.5) - return n * (1 - 0.25 * n) - (red - 0.125) / (1 - red) + n = (2 * (self.nir ** 2 - self.red ** 2) + 1.5 * self.nir + 0.5 * self.red) / ( + self.nir + self.red + 0.5 + ) + return n * (1 - 0.25 * n) - (self.red - 0.125) / (1 - self.red) def GOSAVI(self, Y=0.16): """ - Green Optimized Soil Adjusted Vegetation Index + self.green Optimized Soil Adjusted Vegetation Index https://www.indexdatabase.de/db/i-single.php?id=29 mit Y = 0,16 :return: index """ - return (nir - green) / (nir + green + Y) + return (self.nir - self.green) / (self.nir + self.green + Y) def GSAVI(self, L=0.5): """ - Green Soil Adjusted Vegetation Index + self.green Soil Adjusted Vegetation Index https://www.indexdatabase.de/db/i-single.php?id=31 mit L = 0,5 :return: index """ - return ((nir - green) / (nir + green + L)) * (1 + L) + return ((self.nir - self.green) / (self.nir + self.green + L)) * (1 + L) def Hue(self): """ @@ -355,7 +372,12 @@ def Hue(self): https://www.indexdatabase.de/db/i-single.php?id=34 :return: index """ - return np.arctan((((2 * red - green - blue) / 30.5) * (green - blue))) + return np.arctan( + ( + ((2 * self.red - self.green - self.blue) / 30.5) + * (self.green - self.blue) + ) + ) def IVI(self, a=None, b=None): """ @@ -365,15 +387,15 @@ def IVI(self, a=None, b=None): a=soil line slope :return: index """ - return (nir - b) / (a * red) + return (self.nir - b) / (a * self.red) def IPVI(self): """ - Infrared percentage vegetation index + Infraself.red percentage vegetation index https://www.indexdatabase.de/db/i-single.php?id=35 :return: index """ - return (nir / ((nir + red) / 2)) * (self.NDVI() + 1) + return (self.nir / ((self.nir + self.red) / 2)) * (self.NDVI() + 1) def I(self): """ @@ -381,7 +403,7 @@ def I(self): https://www.indexdatabase.de/db/i-single.php?id=36 :return: index """ - return (red + green + blue) / 30.5 + return (self.red + self.green + self.blue) / 30.5 def RVI(self): """ @@ -389,7 +411,7 @@ def RVI(self): http://www.seos-project.eu/modules/remotesensing/remotesensing-c03-s01-p01.html :return: index """ - return nir / red + return self.nir / self.red def MRVI(self): """ @@ -405,7 +427,10 @@ def MSAVI(self): https://www.indexdatabase.de/db/i-single.php?id=44 :return: index """ - return ((2 * nir + 1) - ((2 * nir + 1) ** 2 - 8 * (nir - red)) ** (1 / 2)) / 2 + return ( + (2 * self.nir + 1) + - ((2 * self.nir + 1) ** 2 - 8 * (self.nir - self.red)) ** (1 / 2) + ) / 2 def NormG(self): """ @@ -413,15 +438,15 @@ def NormG(self): https://www.indexdatabase.de/db/i-single.php?id=50 :return: index """ - return green / (nir + red + green) + return self.green / (self.nir + self.red + self.green) def NormNIR(self): """ - Norm NIR + Norm self.nir https://www.indexdatabase.de/db/i-single.php?id=51 :return: index """ - return nir / (nir + red + green) + return self.nir / (self.nir + self.red + self.green) def NormR(self): """ @@ -429,23 +454,23 @@ def NormR(self): https://www.indexdatabase.de/db/i-single.php?id=52 :return: index """ - return red / (nir + red + green) + return self.red / (self.nir + self.red + self.green) def NGRDI(self): """ - Normalized Difference Green/Red Normalized green red difference index, Visible Atmospherically Resistant Indices Green (VIgreen) + Normalized Difference self.green/self.red Normalized self.green self.red difference index, Visible Atmospherically Resistant Indices self.green (VIself.green) https://www.indexdatabase.de/db/i-single.php?id=390 :return: index """ - return (green - red) / (green + red) + return (self.green - self.red) / (self.green + self.red) def RI(self): """ - Normalized Difference Red/Green Redness Index + Normalized Difference self.red/self.green self.redness Index https://www.indexdatabase.de/db/i-single.php?id=74 :return: index """ - return (red - green) / (red + green) + return (self.red - self.green) / (self.red + self.green) def S(self): """ @@ -453,8 +478,8 @@ def S(self): https://www.indexdatabase.de/db/i-single.php?id=77 :return: index """ - max = np.max([np.max(red), np.max(green), np.max(blue)]) - min = np.min([np.min(red), np.min(green), np.min(blue)]) + max = np.max([np.max(self.red), np.max(self.green), np.max(self.blue)]) + min = np.min([np.min(self.red), np.min(self.green), np.min(self.blue)]) return (max - min) / max def IF(self): @@ -463,15 +488,15 @@ def IF(self): https://www.indexdatabase.de/db/i-single.php?id=79 :return: index """ - return (2 * red - green - blue) / (green - blue) + return (2 * self.red - self.green - self.blue) / (self.green - self.blue) def DVI(self): """ - Simple Ratio NIR/RED Difference Vegetation Index, Vegetation Index Number (VIN) + Simple Ratio self.nir/self.red Difference Vegetation Index, Vegetation Index Number (VIN) https://www.indexdatabase.de/db/i-single.php?id=12 :return: index """ - return nir / red + return self.nir / self.red def TVI(self): """ @@ -482,7 +507,7 @@ def TVI(self): return (self.NDVI() + 0.5) ** (1 / 2) def NDRE(self): - return (nir - redEdge) / (nir + redEdge) + return (self.nir - self.redEdge) / (self.nir + self.redEdge) """ @@ -506,7 +531,7 @@ def NDRE(self): # calculating the indices for the instantiated values in the class # Note: the CCCI index can be changed to any index implemented in the class. -indexValue_form1 = cl.calculation("CCCI").astype(np.float64) +indexValue_form1 = cl.calculation("CCCI", red=red, green=green, blue=blue, redEdge=redEdge, nir=nir).astype(np.float64) indexValue_form2 = cl.CCCI() # calculating the index with the values directly -- you can set just the values preferred -- note: the *calculation* fuction performs the function *setMatrices* From 5e34683ad9f50d1c9cd980edd70d30ef1c3ea39d Mon Sep 17 00:00:00 2001 From: yakuza-uergsNOTE Date: Tue, 27 Aug 2019 14:19:40 -0300 Subject: [PATCH 4/6] update the word wrap in comments at index_calculation --- digital_image_processing/index_calculation.py | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/digital_image_processing/index_calculation.py b/digital_image_processing/index_calculation.py index e1e1d5f7e6b4..33be382634d5 100644 --- a/digital_image_processing/index_calculation.py +++ b/digital_image_processing/index_calculation.py @@ -10,11 +10,16 @@ class IndexCalculation: """ # Class Summary - This algorithm consists in calculating vegetation indices, these indices can be used for precision agriculture for example (or remote sensing). There are functions to define the data and to calculate the implemented indices. + This algorithm consists in calculating vegetation indices, these indices + can be used for precision agriculture for example (or remote sensing). There are + functions to define the data and to calculate the implemented indices. # Vegetation index https://en.wikipedia.org/wiki/Vegetation_Index - A Vegetation Index (VI) is a spectral transformation of two or more bands designed to enhance the contribution of vegetation properties and allow reliable spatial and temporal inter-comparisons of terrestrial photosynthetic activity and canopy structural variations + A Vegetation Index (VI) is a spectral transformation of two or more bands designed + to enhance the contribution of vegetation properties and allow reliable spatial and + temporal inter-comparisons of terrestrial photosynthetic activity and canopy + structural variations # Information about channels (Wavelength range for each) * nir - near-infrared @@ -79,9 +84,18 @@ class IndexCalculation: #"NDRE" -- redEdge, nir #list of all index implemented - #allIndex = ["ARVI2", "CCCI", "CVI", "GLI", "NDVI", "BNDVI", "redEdgeNDVI", "GNDVI", "GBNDVI", "GRNDVI", "RBNDVI", "PNDVI", "ATSAVI", "BWDRVI", "CIgreen", "CIrededge", "CI", "CTVI", "GDVI", "EVI", "GEMI", "GOSAVI", "GSAVI", "Hue", "IVI", "IPVI", "I", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", "NormR", "NGRDI", "RI", "S", "IF", "DVI", "TVI", "NDRE"] + #allIndex = ["ARVI2", "CCCI", "CVI", "GLI", "NDVI", "BNDVI", "redEdgeNDVI", "GNDVI", + "GBNDVI", "GRNDVI", "RBNDVI", "PNDVI", "ATSAVI", "BWDRVI", "CIgreen", + "CIrededge", "CI", "CTVI", "GDVI", "EVI", "GEMI", "GOSAVI", "GSAVI", + "Hue", "IVI", "IPVI", "I", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", + "NormR", "NGRDI", "RI", "S", "IF", "DVI", "TVI", "NDRE"] + #list of index with not blue channel - #notBlueIndex = ["ARVI2", "CCCI", "CVI", "NDVI", "redEdgeNDVI", "GNDVI", "GRNDVI", "ATSAVI", "CIgreen", "CIrededge", "CTVI", "GDVI", "GEMI", "GOSAVI", "GSAVI", "IVI", "IPVI", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", "NormR", "NGRDI", "RI", "DVI", "TVI", "NDRE"] + #notBlueIndex = ["ARVI2", "CCCI", "CVI", "NDVI", "redEdgeNDVI", "GNDVI", "GRNDVI", + "ATSAVI", "CIgreen", "CIrededge", "CTVI", "GDVI", "GEMI", "GOSAVI", + "GSAVI", "IVI", "IPVI", "RVI", "MRVI", "MSAVI", "NormG", "NormNIR", + "NormR", "NGRDI", "RI", "DVI", "TVI", "NDRE"] + #list of index just with RGB channels #RGBIndex = ["GLI", "CI", "Hue", "I", "NGRDI", "RI", "S", "IF"] """ @@ -199,7 +213,8 @@ def GLI(self): def NDVI(self): """ - Normalized Difference self.nir/self.red Normalized Difference Vegetation Index, Calibrated NDVI - CDVI + Normalized Difference self.nir/self.red Normalized Difference Vegetation Index, + Calibrated NDVI - CDVI https://www.indexdatabase.de/db/i-single.php?id=58 :return: index """ @@ -207,7 +222,8 @@ def NDVI(self): def BNDVI(self): """ - Normalized Difference self.nir/self.blue self.blue-normalized difference vegetation index + Normalized Difference self.nir/self.blue self.blue-normalized difference + vegetation index https://www.indexdatabase.de/db/i-single.php?id=135 :return: index """ @@ -458,7 +474,8 @@ def NormR(self): def NGRDI(self): """ - Normalized Difference self.green/self.red Normalized self.green self.red difference index, Visible Atmospherically Resistant Indices self.green (VIself.green) + Normalized Difference self.green/self.red Normalized self.green self.red + difference index, Visible Atmospherically Resistant Indices self.green (VIself.green) https://www.indexdatabase.de/db/i-single.php?id=390 :return: index """ @@ -492,7 +509,8 @@ def IF(self): def DVI(self): """ - Simple Ratio self.nir/self.red Difference Vegetation Index, Vegetation Index Number (VIN) + Simple Ratio self.nir/self.red Difference Vegetation Index, Vegetation Index + Number (VIN) https://www.indexdatabase.de/db/i-single.php?id=12 :return: index """ @@ -526,7 +544,8 @@ def NDRE(self): # instantiating the class with the values #cl = indexCalculation(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) -# how set the values after instantiate the class cl, (for update the data or when dont instantiating the class with the values) +# how set the values after instantiate the class cl, (for update the data or when dont +# instantiating the class with the values) cl.setMatrices(red=red, green=green, blue=blue, redEdge=redEdge, nir=nir) # calculating the indices for the instantiated values in the class @@ -534,7 +553,8 @@ def NDRE(self): indexValue_form1 = cl.calculation("CCCI", red=red, green=green, blue=blue, redEdge=redEdge, nir=nir).astype(np.float64) indexValue_form2 = cl.CCCI() -# calculating the index with the values directly -- you can set just the values preferred -- note: the *calculation* fuction performs the function *setMatrices* +# calculating the index with the values directly -- you can set just the values preferred -- +# note: the *calculation* fuction performs the function *setMatrices* indexValue_form3 = cl.calculation("CCCI", red=red, green=green, blue=blue, redEdge=redEdge, nir=nir).astype(np.float64) From e8a4d80414ebeda216163e0f014baf23a2d3a64a Mon Sep 17 00:00:00 2001 From: yakuza-uergsNOTE Date: Fri, 30 Aug 2019 14:10:04 -0300 Subject: [PATCH 5/6] add the hamming code algorithm --- hashes/hamming_code.py | 315 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 hashes/hamming_code.py diff --git a/hashes/hamming_code.py b/hashes/hamming_code.py new file mode 100644 index 000000000000..155c1b10a38d --- /dev/null +++ b/hashes/hamming_code.py @@ -0,0 +1,315 @@ +# -*- coding: utf-8 -*- +# Author: João Gustavo A. Amorim & Gabriel Kunz +# Author email: joaogustavoamorim@gmail.com and gabriel-kunz@uergs.edu.br +# Coding date: apr 2019 +# Black: True + +""" + * This code implement the Hamming code: + https://en.wikipedia.org/wiki/Hamming_code - In telecommunication, + Hamming codes are a family of linear error-correcting codes. Hamming + codes can detect up to two-bit errors or correct one-bit errors + without detection of uncorrected errors. By contrast, the simple + parity code cannot correct errors, and can detect only an odd number + of bits in error. Hamming codes are perfect codes, that is, they + achieve the highest possible rate for codes with their block length + and minimum distance of three. + + * the implemented code consists of: + * a function responsible for encoding the message (emitterConverter) + * return the encoded message + * a function responsible for decoding the message (receptorConverter) + * return the decoded message and a ack of data integrity + + * how to use: + to be used you must declare how many parity bits (sizePari) + you want to include in the message. + it is desired (for test purposes) to select a bit to be set + as an error. This serves to check whether the code is working correctly. + Lastly, the variable of the message/word that must be desired to be + encoded (text). + + * how this work: + declaration of variables (sizePari, be, text) + + converts the message/word (text) to binary using the + text_to_bits function + encodes the message using the rules of hamming encoding + decodes the message using the rules of hamming encoding + print the original message, the encoded message and the + decoded message + + forces an error in the coded text variable + decodes the message that was forced the error + print the original message, the encoded message, the bit changed + message and the decoded message +""" + +# Imports +import numpy as np + +# Functions of binary conversion-------------------------------------- +def text_to_bits(text, encoding="utf-8", errors="surrogatepass"): + """ + >>> text_to_bits("msg") + '011011010111001101100111' + """ + bits = bin(int.from_bytes(text.encode(encoding, errors), "big"))[2:] + return bits.zfill(8 * ((len(bits) + 7) // 8)) + + +def text_from_bits(bits, encoding="utf-8", errors="surrogatepass"): + """ + >>> text_from_bits('011011010111001101100111') + 'msg' + """ + n = int(bits, 2) + return n.to_bytes((n.bit_length() + 7) // 8, "big").decode(encoding, errors) or "\0" + + +# Functions of hamming code------------------------------------------- +def emitterConverter(sizePar, data): + """ + :param sizePar: how many parity bits the message must have + :param data: information bits + :return: message to be transmitted by unreliable medium + - bits of information merged with parity bits + + >>> emitterConverter(4, "101010111111") + ['1', '1', '1', '1', '0', '1', '0', '0', '1', '0', '1', '1', '1', '1', '1', '1'] + """ + if sizePar + len(data) <= 2 ** sizePar - (len(data) - 1): + print("ERROR - size of parity don't match with size of data") + exit(0) + + dataOut = [] + parity = [] + binPos = [bin(x)[2:] for x in range(1, sizePar + len(data) + 1)] + pos = [x for x in range(1, sizePar + len(data) + 1)] + + # sorted information data for the size of the output data + dataOrd = [] + # data position template + parity + dataOutGab = [] + # parity bit counter + qtdBP = 0 + # counter position of data bits + contData = 0 + + for x in range(1, sizePar + len(data) + 1): + # Performs a template of bit positions - who should be given, + # and who should be parity + if qtdBP < sizePar: + if ((np.log(x) / np.log(2))).is_integer(): + dataOutGab.append("P") + qtdBP = qtdBP + 1 + else: + dataOutGab.append("D") + else: + dataOutGab.append("D") + + # Sorts the data to the new output size + if dataOutGab[-1] == "D": + dataOrd.append(data[contData]) + contData += 1 + else: + dataOrd.append(None) + + # Calculates parity + qtdBP = 0 # parity bit counter + for bp in range(1, sizePar + 1): + # Bit counter one for a given parity + contBO = 0 + # counter to control the loop reading + contLoop = 0 + for x in dataOrd: + if x != None: + try: + aux = (binPos[contLoop])[-1 * (bp)] + except: + aux = "0" + if aux == "1": + if x == "1": + contBO += 1 + contLoop += 1 + if contBO % 2 == 0: + parity.append(0) + else: + parity.append(1) + + qtdBP += 1 + + # Mount the message + ContBP = 0 # parity bit counter + for x in range(0, sizePar + len(data)): + if dataOrd[x] == None: + dataOut.append(str(parity[ContBP])) + ContBP += 1 + else: + dataOut.append(dataOrd[x]) + + return dataOut + + +def receptorConverter(sizePar, data): + """ + >>> receptorConverter(4, "1111010010111111") + (['1', '0', '1', '0', '1', '0', '1', '1', '1', '1', '1', '1'], True) + """ + # data position template + parity + dataOutGab = [] + # Parity bit counter + qtdBP = 0 + # Counter p data bit reading + contData = 0 + # list of parity received + parityReceived = [] + dataOutput = [] + + for x in range(1, len(data) + 1): + # Performs a template of bit positions - who should be given, + # and who should be parity + if qtdBP < sizePar: + if ((np.log(x) / np.log(2))).is_integer(): + dataOutGab.append("P") + qtdBP = qtdBP + 1 + else: + dataOutGab.append("D") + else: + dataOutGab.append("D") + + # Sorts the data to the new output size + if dataOutGab[-1] == "D": + dataOutput.append(data[contData]) + else: + parityReceived.append(data[contData]) + contData += 1 + + # -----------calculates the parity with the data + dataOut = [] + parity = [] + binPos = [bin(x)[2:] for x in range(1, sizePar + len(dataOutput) + 1)] + pos = [x for x in range(1, sizePar + len(dataOutput) + 1)] + + # sorted information data for the size of the output data + dataOrd = [] + # Data position feedback + parity + dataOutGab = [] + # Parity bit counter + qtdBP = 0 + # Counter p data bit reading + contData = 0 + + for x in range(1, sizePar + len(dataOutput) + 1): + # Performs a template position of bits - who should be given, + # and who should be parity + if qtdBP < sizePar: + if ((np.log(x) / np.log(2))).is_integer(): + dataOutGab.append("P") + qtdBP = qtdBP + 1 + else: + dataOutGab.append("D") + else: + dataOutGab.append("D") + + # Sorts the data to the new output size + if dataOutGab[-1] == "D": + dataOrd.append(dataOutput[contData]) + contData += 1 + else: + dataOrd.append(None) + + # Calculates parity + qtdBP = 0 # parity bit counter + for bp in range(1, sizePar + 1): + # Bit counter one for a certain parity + contBO = 0 + # Counter to control loop reading + contLoop = 0 + for x in dataOrd: + if x != None: + try: + aux = (binPos[contLoop])[-1 * (bp)] + except: + aux = "0" + if aux == "1": + if x == "1": + contBO += 1 + contLoop += 1 + if contBO % 2 == 0: + parity.append("0") + else: + parity.append("1") + + qtdBP += 1 + + # Mount the message + ContBP = 0 # Parity bit counter + for x in range(0, sizePar + len(dataOutput)): + if dataOrd[x] == None: + dataOut.append(str(parity[ContBP])) + ContBP += 1 + else: + dataOut.append(dataOrd[x]) + + if parityReceived == parity: + ack = True + else: + ack = False + + return dataOutput, ack + + +# --------------------------------------------------------------------- +""" +# Example how to use + +# number of parity bits +sizePari = 4 + +# location of the bit that will be forced an error +be = 2 + +# Message/word to be encoded and decoded with hamming +# text = input("Enter the word to be read: ") +text = "Message01" + +# Convert the message to binary +binaryText = text_to_bits(text) + +# Prints the binary of the string +print("Text input in binary is '" + binaryText + "'") + +# total transmitted bits +totalBits = len(binaryText) + sizePari +print("Size of data is " + str(totalBits)) + +print("\n --Message exchange--") +print("Data to send ------------> " + binaryText) +dataOut = emitterConverter(sizePari, binaryText) +print("Data converted ----------> " + "".join(dataOut)) +dataReceiv, ack = receptorConverter(sizePari, dataOut) +print( + "Data receive ------------> " + + "".join(dataReceiv) + + "\t\t -- Data integrity: " + + str(ack) +) + + +print("\n --Force error--") +print("Data to send ------------> " + binaryText) +dataOut = emitterConverter(sizePari, binaryText) +print("Data converted ----------> " + "".join(dataOut)) + +# forces error +dataOut[-be] = "1" * (dataOut[-be] == "0") + "0" * (dataOut[-be] == "1") +print("Data after transmission -> " + "".join(dataOut)) +dataReceiv, ack = receptorConverter(sizePari, dataOut) +print( + "Data receive ------------> " + + "".join(dataReceiv) + + "\t\t -- Data integrity: " + + str(ack) +) +""" From d9f62153fcce5db40594d92b6e5c741b72e9d21c Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Fri, 6 Dec 2019 07:12:54 +0100 Subject: [PATCH 6/6] Wrap long lines --- digital_image_processing/index_calculation.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/digital_image_processing/index_calculation.py b/digital_image_processing/index_calculation.py index 33be382634d5..f4f8759ad010 100644 --- a/digital_image_processing/index_calculation.py +++ b/digital_image_processing/index_calculation.py @@ -550,13 +550,14 @@ def NDRE(self): # calculating the indices for the instantiated values in the class # Note: the CCCI index can be changed to any index implemented in the class. -indexValue_form1 = cl.calculation("CCCI", red=red, green=green, blue=blue, redEdge=redEdge, nir=nir).astype(np.float64) +indexValue_form1 = cl.calculation("CCCI", red=red, green=green, blue=blue, + redEdge=redEdge, nir=nir).astype(np.float64) indexValue_form2 = cl.CCCI() # calculating the index with the values directly -- you can set just the values preferred -- # note: the *calculation* fuction performs the function *setMatrices* -indexValue_form3 = cl.calculation("CCCI", red=red, green=green, blue=blue, redEdge=redEdge, nir=nir).astype(np.float64) - +indexValue_form3 = cl.calculation("CCCI", red=red, green=green, blue=blue, + redEdge=redEdge, nir=nir).astype(np.float64) print("Form 1: "+np.array2string(indexValue_form1, precision=20, separator=', ', floatmode='maxprec_equal')) print("Form 2: "+np.array2string(indexValue_form2, precision=20, separator=', ', floatmode='maxprec_equal'))