1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Tool Library //
9 // imagery_tools //
10 // //
11 //-------------------------------------------------------//
12 // //
13 // local_statistical_measures.cpp //
14 // //
15 // Copyright (C) 2016 by //
16 // Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. SAGA is free software; you //
22 // can redistribute it and/or modify it under the terms //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the //
25 // License, or (at your option) any later version. //
26 // //
27 // SAGA is distributed in the hope that it will be //
28 // useful, but WITHOUT ANY WARRANTY; without even the //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
30 // PARTICULAR PURPOSE. See the GNU General Public //
31 // License for more details. //
32 // //
33 // You should have received a copy of the GNU General //
34 // Public License along with this program; if not, see //
35 // <http://www.gnu.org/licenses/>. //
36 // //
37 //-------------------------------------------------------//
38 // //
39 // e-mail: oconrad@saga-gis.org //
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Hamburg //
44 // Germany //
45 // //
46 ///////////////////////////////////////////////////////////
47
48 //---------------------------------------------------------
49 #include "local_statistical_measures.h"
50
51
52 ///////////////////////////////////////////////////////////
53 // //
54 // //
55 // //
56 ///////////////////////////////////////////////////////////
57
58 //---------------------------------------------------------
CLocal_Statistical_Measures(void)59 CLocal_Statistical_Measures::CLocal_Statistical_Measures(void)
60 {
61 Set_Name (_TL("Local Statistical Measures"));
62
63 Set_Author ("O.Conrad (c) 2016");
64
65 Set_Description (_TW(
66 "<hr><h4>References</h4><ul>"
67 "<li><b>Zhang, Y. (2001):</b> Texture-integrated classification of urban treed areas in high-resolution color-infrared imagery."
68 " Photogrammetric Engineering and Remote Sensing 67(12), 1359-1365."
69 " <a href=\"http://web.pdx.edu/~nauna/2001_dec_1359-1365.pdf\">online</a>.</li>"
70 "</ul>"
71 ));
72
73 Parameters.Add_Grid("", "GRID" , _TL("Grid" ), _TL(""), PARAMETER_INPUT);
74
75 Parameters.Add_Grid("", "CONTRAST", _TL("Contrast"), _TL(""), PARAMETER_OUTPUT);
76 Parameters.Add_Grid("", "ENERGY" , _TL("Energy" ), _TL(""), PARAMETER_OUTPUT);
77 Parameters.Add_Grid("", "ENTROPY" , _TL("Entropy" ), _TL(""), PARAMETER_OUTPUT);
78 Parameters.Add_Grid("", "VARIANCE", _TL("Variance"), _TL(""), PARAMETER_OUTPUT);
79
80 Parameters.Add_Choice("",
81 "TYPE" , _TL("Kernel"),
82 _TL("kernel radius in cells"),
83 CSG_String::Format("%s|%s|",
84 _TL("square"),
85 _TL("circle")
86 ), 1
87 );
88
89 Parameters.Add_Int("",
90 "RADIUS" , _TL("Radius"),
91 _TL("kernel radius in cells"),
92 1, 1, true
93 );
94
95 Parameters.Add_Choice("",
96 "NORMALIZE" , _TL("Normalization"),
97 _TL(""),
98 CSG_String::Format("%s|%s|",
99 _TL("no"),
100 _TL("scale to range")
101 ), 1
102 );
103
104 Parameters.Add_Double("NORMALIZE",
105 "NORM_MIN" , _TL("Minimum"),
106 _TL(""),
107 1.0
108 );
109
110 Parameters.Add_Double("NORMALIZE",
111 "NORM_MAX" , _TL("Maximum"),
112 _TL(""),
113 255.0
114 );
115 }
116
117
118 ///////////////////////////////////////////////////////////
119 // //
120 ///////////////////////////////////////////////////////////
121
122 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)123 int CLocal_Statistical_Measures::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
124 {
125 if( pParameter->Cmp_Identifier("NORMALIZE") )
126 {
127 pParameters->Set_Enabled("NORM_MIN", pParameter->asInt() == 1);
128 pParameters->Set_Enabled("NORM_MAX", pParameter->asInt() == 1);
129 }
130
131 return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
132 }
133
134
135 ///////////////////////////////////////////////////////////
136 // //
137 ///////////////////////////////////////////////////////////
138
139 //---------------------------------------------------------
On_Execute(void)140 bool CLocal_Statistical_Measures::On_Execute(void)
141 {
142 //-----------------------------------------------------
143 m_pGrid = Parameters("GRID")->asGrid();
144
145 if( m_pGrid->Get_Range() <= 0.0 )
146 {
147 Error_Set(_TL("nothing to do, input data has no variation."));
148
149 return( false );
150 }
151
152 //-----------------------------------------------------
153 m_pContrast = Parameters("CONTRAST" )->asGrid();
154 m_pEnergy = Parameters("ENERGY" )->asGrid();
155 m_pEntropy = Parameters("ENTROPY" )->asGrid();
156 m_pVariance = Parameters("VARIANCE" )->asGrid();
157
158 DataObject_Set_Colors(m_pContrast , 11, SG_COLORS_RAINBOW);
159 DataObject_Set_Colors(m_pEnergy , 11, SG_COLORS_RAINBOW);
160 DataObject_Set_Colors(m_pEntropy , 11, SG_COLORS_RAINBOW);
161 DataObject_Set_Colors(m_pVariance , 11, SG_COLORS_RAINBOW);
162
163 //-----------------------------------------------------
164 m_Kernel.Get_Weighting().Set_Parameters(Parameters);
165 m_Kernel.Set_Radius(m_Radius = Parameters("RADIUS")->asInt(), Parameters("TYPE")->asInt() == 0);
166
167 //-----------------------------------------------------
168 m_Normalize = Parameters("NORMALIZE")->asInt();
169 m_Minimum = Parameters("NORM_MIN" )->asDouble();
170 m_Scale = (Parameters("NORM_MAX" )->asDouble() - m_Minimum) / m_pGrid->Get_Range();
171
172 //-----------------------------------------------------
173 for(int y=0; y<Get_NY() && Set_Progress(y); y++)
174 {
175 #pragma omp parallel for
176 for(int x=0; x<Get_NX(); x++)
177 {
178 Get_Measure(x, y);
179 }
180 }
181
182 //-----------------------------------------------------
183 m_Kernel.Destroy();
184
185 return( true );
186 }
187
188
189 ///////////////////////////////////////////////////////////
190 // //
191 ///////////////////////////////////////////////////////////
192
193 //---------------------------------------------------------
Get_Value(int x,int y,double & z)194 inline bool CLocal_Statistical_Measures::Get_Value(int x, int y, double &z)
195 {
196 if( m_pGrid->is_InGrid(x, y) )
197 {
198 switch( m_Normalize )
199 {
200 default:
201 z = m_pGrid->asDouble(x, y);
202 break;
203
204 case 1:
205 z = m_Minimum + m_Scale * (m_pGrid->asDouble(x, y) - m_pGrid->Get_Min());
206 break;
207 }
208
209 return( true );
210 }
211
212 return( false );
213 }
214
215
216 ///////////////////////////////////////////////////////////
217 // //
218 ///////////////////////////////////////////////////////////
219
220 //---------------------------------------------------------
Get_Measure(int x,int y)221 bool CLocal_Statistical_Measures::Get_Measure(int x, int y)
222 {
223 //-----------------------------------------------------
224 CSG_Simple_Statistics s;
225
226 double Energy = 0.0;
227 double Entropy = 0.0;
228
229 double z;
230
231 //-----------------------------------------------------
232 for(int i=0; i<m_Kernel.Get_Count(); i++)
233 {
234 int ix = m_Kernel.Get_X(i);
235 int iy = m_Kernel.Get_Y(i);
236
237 if( Get_Value(x + ix, y + iy, z) )
238 {
239 s += z;
240 Energy += z*z;
241 Entropy += z * log(z > 0.0 ? z : M_ALMOST_ZERO);
242 }
243 }
244
245 //-----------------------------------------------------
246 if( s.Get_Count() > 0 )
247 {
248 Get_Value(x, y, z);
249
250 m_pContrast ->Set_Value(x, y, s.Get_Mean() ? (z - s.Get_Mean()) / s.Get_Mean() : 0.0); // Weber
251 // m_pContrast ->Set_Value(x, y, s.Get_Range() ? s.Get_Range() / (s.Get_Minimum() + s.Get_Maximum()) : 0.0); // Michelson
252 m_pEnergy ->Set_Value(x, y, Energy );
253 m_pEntropy ->Set_Value(x, y, Entropy );
254 m_pVariance ->Set_Value(x, y, s.Get_Variance());
255
256 return( true );
257 }
258
259 m_pContrast ->Set_NoData(x, y);
260 m_pEnergy ->Set_NoData(x, y);
261 m_pEntropy ->Set_NoData(x, y);
262 m_pVariance ->Set_NoData(x, y);
263
264 return( false );
265 }
266
267
268 ///////////////////////////////////////////////////////////
269 // //
270 // //
271 // //
272 ///////////////////////////////////////////////////////////
273
274 //---------------------------------------------------------
275