svn-gvsig-desktop / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / classification / ClassificationMinimumDistanceProcess.java @ 16598
History | View | Annotate | Download (11.3 KB)
1 |
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2006 Instituto de Desarrollo Regional and Generalitat Valenciana.
|
4 |
*
|
5 |
* This program is free software; you can redistribute it and/or
|
6 |
* modify it under the terms of the GNU General Public License
|
7 |
* as published by the Free Software Foundation; either version 2
|
8 |
* of the License, or (at your option) any later version.
|
9 |
*
|
10 |
* This program is distributed in the hope that it will be useful,
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13 |
* GNU General Public License for more details.
|
14 |
*
|
15 |
* You should have received a copy of the GNU General Public License
|
16 |
* along with this program; if not, write to the Free Software
|
17 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
18 |
*
|
19 |
* For more information, contact:
|
20 |
*
|
21 |
* Generalitat Valenciana
|
22 |
* Conselleria d'Infraestructures i Transport
|
23 |
* Av. Blasco Iba?ez, 50
|
24 |
* 46010 VALENCIA
|
25 |
* SPAIN
|
26 |
*
|
27 |
* +34 963862235
|
28 |
* gvsig@gva.es
|
29 |
* www.gvsig.gva.es
|
30 |
*
|
31 |
* or
|
32 |
*
|
33 |
* Instituto de Desarrollo Regional (Universidad de Castilla La-Mancha)
|
34 |
* Campus Universitario s/n
|
35 |
* 02071 Alabacete
|
36 |
* Spain
|
37 |
*
|
38 |
* +34 967 599 200
|
39 |
*/
|
40 |
|
41 |
package org.gvsig.remotesensing.classification; |
42 |
|
43 |
import java.util.ArrayList; |
44 |
import org.gvsig.raster.buffer.RasterBuffer; |
45 |
import org.gvsig.raster.dataset.IBuffer; |
46 |
import org.gvsig.raster.dataset.IRasterDataSource; |
47 |
import org.gvsig.raster.grid.GridException; |
48 |
import org.gvsig.raster.grid.roi.ROI; |
49 |
import org.gvsig.raster.process.RasterTaskQueue; |
50 |
import org.gvsig.raster.util.RasterToolsUtil; |
51 |
|
52 |
import com.iver.andami.PluginServices; |
53 |
import com.iver.cit.gvsig.project.documents.view.gui.View; |
54 |
|
55 |
/** ClassificationMinimumDistanceProcess implementa el m?todo de clasificaci?n de
|
56 |
* m?nima distancia.
|
57 |
*
|
58 |
* @see ClassificationGeneralProcess
|
59 |
* @author Alejandro Mu?oz Sanchez (alejandro.munoz@uclm.es)
|
60 |
* @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
|
61 |
* @version 19/10/2007
|
62 |
*/
|
63 |
public class ClassificationMinimumDistanceProcess extends ClassificationGeneralProcess { |
64 |
|
65 |
private double means[][] = null; |
66 |
private int bandCount = 0; |
67 |
|
68 |
/**
|
69 |
* Class constructor.
|
70 |
* @param raster raster a clasificar
|
71 |
* @param rois lista de rois
|
72 |
* @param bandList bandas habilitadas
|
73 |
* @param view vista
|
74 |
* @param fileNameOutput path de fichero de salida
|
75 |
*/
|
76 |
public ClassificationMinimumDistanceProcess(IRasterDataSource raster, ArrayList rois, int bandList[], View view, String fileNameOutput){ |
77 |
this.raster= raster;
|
78 |
this.rois = rois;
|
79 |
this.view=view;
|
80 |
this.fileNameOutput= fileNameOutput;
|
81 |
this.bandList = bandList;
|
82 |
numClases = rois.size(); |
83 |
} |
84 |
|
85 |
/**
|
86 |
* Lanzar el Thread del proceso de clasificaci?n por el m?todo de m?nima distancia.
|
87 |
*/
|
88 |
public void start() { |
89 |
blinker = new Thread(this); |
90 |
blinker.start(); |
91 |
} |
92 |
|
93 |
|
94 |
/*
|
95 |
* (non-Javadoc)
|
96 |
* @see java.lang.Runnable#run()
|
97 |
*/
|
98 |
public void run() { |
99 |
RasterTaskQueue.register(rasterTask); |
100 |
setGrid(); |
101 |
rasterResult= RasterBuffer.getBuffer(IBuffer.TYPE_DOUBLE, inputGrid.getRasterBuf().getWidth(), inputGrid.getRasterBuf().getHeight(), 1, true); |
102 |
int c=0; |
103 |
int iNY= inputGrid.getLayerNY();
|
104 |
int iNX= inputGrid.getLayerNX();
|
105 |
|
106 |
bandCount = inputGrid.getBandCount(); |
107 |
|
108 |
|
109 |
try{
|
110 |
|
111 |
means = new double[numClases][bandCount]; |
112 |
for (int clase=0; clase<numClases; clase++) |
113 |
for (int i=0;i<bandCount;i++){ |
114 |
((ROI)rois.get(clase)).setBandToOperate(bandList[i]); |
115 |
means[clase][i]=((ROI)rois.get(clase)).getMeanValue(); |
116 |
} |
117 |
|
118 |
|
119 |
|
120 |
int inputGridNX = inputGrid.getNX();
|
121 |
int datType = inputGrid.getRasterBuf().getDataType();
|
122 |
|
123 |
// Caso Buffer tipo Byte
|
124 |
if (datType == RasterBuffer.TYPE_BYTE){
|
125 |
byte data[]= new byte[bandCount]; |
126 |
for(int i=0; i<iNY;i++){ |
127 |
for(int j=0; j<iNX;j++){ |
128 |
inputGrid.getRasterBuf().getElemByte(i, j, data); |
129 |
c= getPixelClassForTypeByte(data); |
130 |
rasterResult.setElem(i, j, 0,(double) c); |
131 |
} |
132 |
percent = i*100/inputGridNX;
|
133 |
} |
134 |
} |
135 |
|
136 |
// Caso Buffer tipo Short
|
137 |
else if (datType == RasterBuffer.TYPE_SHORT){ |
138 |
short data[]= new short[bandCount]; |
139 |
for(int i=0; i<iNY;i++){ |
140 |
for(int j=0; j<iNX;j++){ |
141 |
inputGrid.getRasterBuf().getElemShort(i, j, data); |
142 |
c= getPixelClassForTypeShort(data); |
143 |
rasterResult.setElem(i, j, 0,(double)c); |
144 |
} |
145 |
percent = i*100/inputGridNX;
|
146 |
} |
147 |
} |
148 |
|
149 |
// Caso Buffer tipo Int
|
150 |
else if (datType == RasterBuffer.TYPE_INT){ |
151 |
int data[]= new int[bandCount]; |
152 |
for(int i=0; i<iNY;i++){ |
153 |
for(int j=0; j<iNX;j++){ |
154 |
inputGrid.getRasterBuf().getElemInt(i, j, data); |
155 |
c= getPixelClassForTypeInt(data); |
156 |
rasterResult.setElem(i, j, 0,(double) c); |
157 |
} |
158 |
percent = i*100/inputGridNX;
|
159 |
} |
160 |
} |
161 |
|
162 |
|
163 |
// Caso Buffer tipo Float
|
164 |
else if (datType == RasterBuffer.TYPE_FLOAT){ |
165 |
float data[]= new float[bandCount]; |
166 |
for(int i=0; i<iNY;i++){ |
167 |
for(int j=0; j<iNX;j++){ |
168 |
inputGrid.getRasterBuf().getElemFloat(i, j, data); |
169 |
c= getPixelClassForTypeFloat(data); |
170 |
rasterResult.setElem(i, j, 0,(double) c); |
171 |
} |
172 |
percent = i*100/inputGridNX;
|
173 |
} |
174 |
} |
175 |
|
176 |
|
177 |
// Caso Buffer tipo Float
|
178 |
else if (datType == RasterBuffer.TYPE_DOUBLE){ |
179 |
double data[]= new double[bandCount]; |
180 |
for(int i=0; i<iNY;i++){ |
181 |
for(int j=0; j<iNX;j++){ |
182 |
inputGrid.getRasterBuf().getElemDouble(i, j, data); |
183 |
c= getPixelClassForTypeDouble(data); |
184 |
rasterResult.setElem(i, j, 0,(double) c); |
185 |
} |
186 |
percent = i*100/inputGridNX;
|
187 |
} |
188 |
} |
189 |
|
190 |
writeToFile(); |
191 |
|
192 |
|
193 |
}catch (GridException e) {
|
194 |
RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e); |
195 |
}finally {
|
196 |
RasterTaskQueue.remove(rasterTask); |
197 |
} |
198 |
} |
199 |
|
200 |
|
201 |
/**
|
202 |
* M?todo que implementa el clasificador de m?nima distancia.
|
203 |
* Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al
|
204 |
* vector de medias es m?nima
|
205 |
*
|
206 |
* @param array de tipo byte con los valores del pixel en cada una de las bandas
|
207 |
* @return clase a la que pertenece el pixel
|
208 |
*/
|
209 |
public int getPixelClassForTypeByte(byte[] pixelBandsValues) { |
210 |
int clasefinal=0; double distanciaFinal=0.0; |
211 |
for (int clase=0; clase<numClases; clase++) |
212 |
{ |
213 |
double[] y = new double[bandCount]; |
214 |
double distancia=0; |
215 |
for (int i=0;i<bandCount;i++){ |
216 |
y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]); |
217 |
//y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
|
218 |
distancia+=y[i]; |
219 |
} |
220 |
//distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
|
221 |
if (clase==0) |
222 |
distanciaFinal=distancia; |
223 |
|
224 |
else if (distancia<distanciaFinal){ |
225 |
distanciaFinal = distancia; |
226 |
clasefinal = clase; |
227 |
} |
228 |
} |
229 |
return clasefinal;
|
230 |
} |
231 |
|
232 |
|
233 |
/**
|
234 |
* M?todo que implementa el clasificador de m?nima distancia.
|
235 |
* Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al
|
236 |
* vector de medias es m?nima
|
237 |
*
|
238 |
* @param array de tipo short con los valores del pixel en cada una de las bandas
|
239 |
* @return clase a la que pertenece el pixel
|
240 |
*/
|
241 |
public int getPixelClassForTypeShort(short[] pixelBandsValues) { |
242 |
int clasefinal=0; double distanciaFinal=0.0; |
243 |
for (int clase=0; clase<numClases; clase++) |
244 |
{ |
245 |
double[] y = new double[bandCount]; |
246 |
double distancia=0; |
247 |
for (int i=0;i<bandCount;i++){ |
248 |
y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]); |
249 |
//y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
|
250 |
distancia+=y[i]; |
251 |
} |
252 |
//distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
|
253 |
if (clase==0) |
254 |
distanciaFinal=distancia; |
255 |
else if (distancia<distanciaFinal){ |
256 |
distanciaFinal= distancia; |
257 |
clasefinal=clase; |
258 |
} |
259 |
} |
260 |
return clasefinal;
|
261 |
} |
262 |
|
263 |
|
264 |
/**
|
265 |
* M?todo que implementa el clasificador de m?nima distancia.
|
266 |
* Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al
|
267 |
* vector de medias es m?nima
|
268 |
*
|
269 |
* @param array de tipo int con los valores del pixel en cada una de las bandas
|
270 |
* @return clase a la que pertenece el pixel
|
271 |
*/
|
272 |
public int getPixelClassForTypeInt(int[] pixelBandsValues) { |
273 |
|
274 |
int clasefinal=0; double distanciaFinal=0.0; |
275 |
for (int clase=0; clase<numClases; clase++) |
276 |
{ |
277 |
double[] y = new double[bandCount]; |
278 |
double distancia=0; |
279 |
for (int i=0;i<bandCount;i++){ |
280 |
y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]); |
281 |
//y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
|
282 |
distancia+=y[i]; |
283 |
} |
284 |
//distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
|
285 |
if (clase==0) |
286 |
distanciaFinal=distancia; |
287 |
else if (distancia<distanciaFinal){ |
288 |
distanciaFinal= distancia; |
289 |
clasefinal=clase; |
290 |
} |
291 |
} |
292 |
return clasefinal;
|
293 |
} |
294 |
|
295 |
|
296 |
/**
|
297 |
* M?todo que implementa el clasificador de m?nima distancia.
|
298 |
* Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al
|
299 |
* vector de medias es m?nima
|
300 |
*
|
301 |
* @param array de tipo float con los valores del pixel en cada una de las bandas
|
302 |
* @return clase a la que pertenece el pixel
|
303 |
*/
|
304 |
public int getPixelClassForTypeFloat(float[] pixelBandsValues) { |
305 |
int clasefinal=0; double distanciaFinal=0.0; |
306 |
for (int clase=0; clase<numClases; clase++) |
307 |
{ |
308 |
double[] y = new double[bandCount]; |
309 |
double distancia=0; |
310 |
for (int i=0;i<bandCount;i++){ |
311 |
y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]); |
312 |
//y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
|
313 |
distancia+=y[i]; |
314 |
} |
315 |
//distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
|
316 |
if (clase==0) |
317 |
distanciaFinal=distancia; |
318 |
else if (distancia<distanciaFinal){ |
319 |
distanciaFinal= distancia; |
320 |
clasefinal=clase; |
321 |
} |
322 |
} |
323 |
return clasefinal;
|
324 |
} |
325 |
|
326 |
|
327 |
/**
|
328 |
* M?todo que implementa el clasificador de m?nima distancia.
|
329 |
* Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al
|
330 |
* vector de medias es m?nima
|
331 |
*
|
332 |
* @param array de tipo double con los valores del pixel en cada una de las bandas
|
333 |
* @return clase a la que pertenece el pixel
|
334 |
*/
|
335 |
public int getPixelClassForTypeDouble(double[] pixelBandsValues) { |
336 |
int clasefinal=0; double distanciaFinal=0.0; |
337 |
for (int clase=0; clase<numClases; clase++) |
338 |
{ |
339 |
double[] y = new double[bandCount]; |
340 |
double distancia=0; |
341 |
for (int i=0;i<bandCount;i++){ |
342 |
y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]); |
343 |
//y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
|
344 |
distancia+=y[i]; |
345 |
} |
346 |
//distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
|
347 |
if (clase==0) |
348 |
distanciaFinal=distancia; |
349 |
else if (distancia<distanciaFinal){ |
350 |
distanciaFinal= distancia; |
351 |
clasefinal=clase; |
352 |
} |
353 |
} |
354 |
return clasefinal;
|
355 |
} |
356 |
} |