/
Water_Classifier.py
177 lines (124 loc) · 4.36 KB
/
Water_Classifier.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import numpy as np
import gc
import warnings
import datacube
from datacube.storage import masking
import xarray as xr
def water_classifier(dataset_in):
def _band_ratio(a, b):
"""
Calculates a normalized ratio index
"""
return (a - b) / (a + b)
def _run_regression(band1, band2, band3, band4, band5, band7):
"""
Water classifier. Regression analysis based on Australia training data.
"""
# Compute normalized ratio indices
ndi_52 = _band_ratio(band5, band2)
ndi_43 = _band_ratio(band4, band3)
ndi_72 = _band_ratio(band7, band2)
#classified = np.ones(shape, dtype='uint8')
classified = np.full(shape, no_data, dtype='uint8')
# Start with the tree's left branch, finishing nodes as needed
# Left branch
r1 = ndi_52 <= -0.01
r2 = band1 <= 2083.5
classified[r1 & ~r2] = 0 #Node 3
r3 = band7 <= 323.5
_tmp = r1 & r2
_tmp2 = _tmp & r3
_tmp &= ~r3
r4 = ndi_43 <= 0.61
classified[_tmp2 & r4] = 1 #Node 6
classified[_tmp2 & ~r4] = 0 #Node 7
r5 = band1 <= 1400.5
_tmp2 = _tmp & ~r5
r6 = ndi_43 <= -0.01
classified[_tmp2 & r6] = 1 #Node 10
classified[_tmp2 & ~r6] = 0 #Node 11
_tmp &= r5
r7 = ndi_72 <= -0.23
_tmp2 = _tmp & ~r7
r8 = band1 <= 379
classified[_tmp2 & r8] = 1 #Node 14
classified[_tmp2 & ~r8] = 0 #Node 15
_tmp &= r7
r9 = ndi_43 <= 0.22
classified[_tmp & r9] = 1 #Node 17
_tmp &= ~r9
r10 = band1 <= 473
classified[_tmp & r10] = 1 #Node 19
classified[_tmp & ~r10] = 0 #Node 20
# Left branch complete; cleanup
del r2, r3, r4, r5, r6, r7, r8, r9, r10
gc.collect()
# Right branch of regression tree
r1 = ~r1
r11 = ndi_52 <= 0.23
_tmp = r1 & r11
r12 = band1 <= 334.5
_tmp2 = _tmp & ~r12
classified[_tmp2] = 0 #Node 23
_tmp &= r12
r13 = ndi_43 <= 0.54
_tmp2 = _tmp & ~r13
classified[_tmp2] = 0 #Node 25
_tmp &= r13
r14 = ndi_52 <= 0.12
_tmp2 = _tmp & r14
classified[_tmp2] = 1 #Node 27
_tmp &= ~r14
r15 = band3 <= 364.5
_tmp2 = _tmp & r15
r16 = band1 <= 129.5
classified[_tmp2 & r16] = 1 #Node 31
classified[_tmp2 & ~r16] = 0 #Node 32
_tmp &= ~r15
r17 = band1 <= 300.5
_tmp2 = _tmp & ~r17
_tmp &= r17
classified[_tmp] = 1 #Node 33
classified[_tmp2] = 0 #Node 34
_tmp = r1 & ~r11
r18 = ndi_52 <= 0.34
classified[_tmp & ~r18] = 0 #Node 36
_tmp &= r18
r19 = band1 <= 249.5
classified[_tmp & ~r19] = 0 #Node 38
_tmp &= r19
r20 = ndi_43 <= 0.45
classified[_tmp & ~r20] = 0 #Node 40
_tmp &= r20
r21 = band3 <= 364.5
classified[_tmp & ~r21] = 0 #Node 42
_tmp &= r21
r22 = band1 <= 129.5
classified[_tmp & r22] = 1 #Node 44
classified[_tmp & ~r22] = 0 #Node 45
# Completed regression tree
return classified
blue = dataset_in.blue
green = dataset_in.green
red = dataset_in.red
nir = dataset_in.nir
swir1 = dataset_in.swir1
swir2 = dataset_in.swir2
dtype = blue.values.dtype
shape = blue.values.shape
no_data =-9999
classified = _run_regression(blue.values, green.values, red.values, nir.values, swir1.values, swir2.values)
classified_clean=classified.astype('float64')
y = dataset_in.y
x = dataset_in.x
time = None
coords = None
dims = None
time = dataset_in.time
coords = [time, y, x]
dims = ['time', 'y', 'x']
data_array = xr.DataArray(classified_clean, coords=coords, dims=dims)
dataset_out = xr.Dataset({'wofs': data_array}, coords={'time': time, 'y': y,'x': x})
desc = """The water classifier is based on Mueller, et al. (2015) "Water observations from space: Mapping surface water from 25 years of Landsat imagery across Australia." Remote Sensing of Environment. https://github.com/GeoscienceAustralia/eo-tools/blob/stable/eotools/water_classifier.py https://www.sciencedirect.com/science/article/pii/S0034425715301929
"""
return (dataset_out, desc)