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