-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspectral_indices.py
140 lines (105 loc) · 4.67 KB
/
spectral_indices.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
from skimage import io
from abc import ABC, abstractmethod
class ImageProcess:
def __init__(self, path):
self.__path = path
def read_image(self):
return io.imread(self.__path)
@staticmethod
def normalize_band(band):
return (band - np.min(band)) / (np.max(band) - np.min(band))
def display_band(title: str, band: np.ndarray, cmap: cm):
plt.figure(figsize=(15, 10))
plt.imshow(band, cmap=cmap)
plt.title(title)
plt.colorbar()
plt.axis('off')
plt.show()
class BandCalculate(ABC):
def __init__(self, band1: ImageProcess, nir_band: ImageProcess):
self.__result = None
self._band1 = ImageProcess.normalize_band(np.array(band1.read_image()).astype(float))
self._nir_band = ImageProcess.normalize_band(np.array(nir_band.read_image()).astype(float))
@abstractmethod
def calculate_band(self) -> np.ndarray:
pass
@abstractmethod
def show(self, title):
pass
class NDVI(BandCalculate):
def __init__(self, red_band: ImageProcess, nir_band: ImageProcess):
super().__init__(red_band, nir_band)
self.__ndvi = None
def calculate_band(self) -> np.ndarray:
self.__ndvi = (self._nir_band - self._band1) / (self._nir_band + self._band1)
return self.__ndvi
def show(self, title: str):
if self.__ndvi is None:
raise ValueError("NDVI not calculated. Please calculate NDVI using calculate_band() method before "
"displaying.")
display_band(title, self.__ndvi, cmap=cm.Grays)
class NDWI(BandCalculate):
def __init__(self, green_band: ImageProcess, nir_band: ImageProcess):
super().__init__(green_band, nir_band)
self.__ndwi = None
def calculate_band(self) -> np.ndarray:
self.__ndwi = (self._band1 - self._nir_band) / (self._band1 + self._nir_band)
return self.__ndwi
def show(self, title: str):
if self.__ndwi is None:
raise ValueError("NDWI not calculated. Please calculate NDWI using calculate_band() method before "
"displaying.")
display_band(title, self.__ndwi, cmap=cm.Grays)
class SAVI(BandCalculate):
def __init__(self, red_band: ImageProcess, nir_band: ImageProcess):
super().__init__(red_band, nir_band)
self.__savi = None
def calculate_band(self) -> np.ndarray:
self.__savi = ((self._nir_band - self._band1) / (self._nir_band + self._band1 + 0.5)) * (1 + 0.5)
return self.__savi
def show(self, title):
if self.__savi is None:
raise ValueError("SAVI not calculated. Please calculate SAVI using calculate_band() method before "
"displaying.")
display_band(title, self.__savi, cmap=cm.gray)
class AFVI(BandCalculate):
def __init__(self, swir1_band, nir_band):
super().__init__(swir1_band, nir_band)
self.__afvi = None
def calculate_band(self) -> np.ndarray:
self.__afvi = ((self._nir_band - 0.66) * (self._band1 / (self._nir_band + (0.66 * self._band1))))
return self.__afvi
def show(self, title):
if self.__afvi is None:
raise ValueError("AFVI not calculated. Please calculate AFVI using calculate_band() method before "
"displaying.")
display_band(title, self.__afvi, cmap=cm.gray)
class UI(BandCalculate):
def __init__(self, swir2_band, nir_band):
super().__init__(swir2_band, nir_band)
self.__ui = None
def calculate_band(self) -> np.ndarray:
self.__ui = (self._band1 - self._nir_band) / (self._band1 + self._nir_band)
return self.__ui
def show(self, title):
if self.__ui is None:
raise ValueError("UI not calculated. Please calculate UI using calculate_band() method before "
"displaying.")
display_band(title, self.__ui, cmap=cm.gray)
class BI(BandCalculate):
def __init__(self, green_band, red_band, nir_band):
super().__init__(green_band, nir_band)
self._red_band = ImageProcess.normalize_band(np.array(red_band.read_image()).astype(float))
self.__bi = None
def calculate_band(self) -> np.ndarray:
self.__bi = ((self._nir_band - self._band1) - self._red_band) / (
(self._nir_band + self._band1) + self._red_band)
return self.__bi
def show(self, title):
if self.__bi is None:
raise ValueError("BI not calculated. Please calculate BI using calculate_band() method before "
"displaying.")
display_band(title, self.__bi, cmap=cm.gray)