root / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / classification / ClassificationMaximumLikelihoodProcess.java @ 17820
History | View | Annotate | Download (12.6 KB)
1 | 13790 | dguerrero | /* 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 | 14322 | gsdiego | import java.util.ArrayList; |
44 | 13790 | dguerrero | |
45 | import org.gvsig.raster.buffer.RasterBuffer; |
||
46 | import org.gvsig.raster.dataset.IBuffer; |
||
47 | 14465 | amunoz | import org.gvsig.raster.dataset.IRasterDataSource; |
48 | 16598 | amunoz | import org.gvsig.raster.grid.GridException; |
49 | 14322 | gsdiego | import org.gvsig.raster.grid.roi.ROI; |
50 | 13790 | dguerrero | import org.gvsig.raster.process.RasterTaskQueue; |
51 | 16567 | amunoz | import org.gvsig.raster.util.RasterToolsUtil; |
52 | 13790 | dguerrero | |
53 | import Jama.Matrix; |
||
54 | |||
55 | import com.iver.andami.PluginServices; |
||
56 | 14465 | amunoz | import com.iver.cit.gvsig.project.documents.view.gui.View; |
57 | 13790 | dguerrero | |
58 | 14762 | amunoz | /** ClassificationMaximumLikelihoodProcess implementa el m?todo de clasificaci?n de
|
59 | * m?xima probabilidad.
|
||
60 | *
|
||
61 | * @see ClassificationGeneralProcess
|
||
62 | 14502 | amunoz | * @author Alejandro Mu?oz Sanchez (alejandro.munoz@uclm.es)
|
63 | 14762 | amunoz | * @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
|
64 | 14773 | amunoz | * @version 19/10/2007
|
65 | 14762 | amunoz | */
|
66 | 13790 | dguerrero | |
67 | 14483 | amunoz | public class ClassificationMaximumLikelihoodProcess extends ClassificationGeneralProcess{ |
68 | |||
69 | 14591 | gsdiego | private Matrix Y = null; |
70 | private Matrix result = null; |
||
71 | private Matrix inverseVarCovMatrix [] = null; |
||
72 | private double detS [] = null; |
||
73 | 14640 | gsdiego | private double means[][] = null; |
74 | private int bandCount = 0; |
||
75 | 14762 | amunoz | |
76 | /**
|
||
77 | 14773 | amunoz | * Class constructor.
|
78 | * @param raster raster a clasificar
|
||
79 | * @param rois lista de rois
|
||
80 | * @param bandList bandas habilitadas
|
||
81 | * @param view vista
|
||
82 | * @param fileNameOutput path de fichero de salida
|
||
83 | */
|
||
84 | 14762 | amunoz | public ClassificationMaximumLikelihoodProcess(IRasterDataSource raster, ArrayList rois, |
85 | int bandList[], View view, String fileNameOutput){ |
||
86 | 14465 | amunoz | this.raster= raster;
|
87 | 14322 | gsdiego | this.rois = rois;
|
88 | 14465 | amunoz | this.view=view;
|
89 | 13790 | dguerrero | this.fileNameOutput= fileNameOutput;
|
90 | 14506 | gsdiego | this.bandList = bandList;
|
91 | 14640 | gsdiego | numClases = rois.size(); |
92 | 13790 | dguerrero | } |
93 | |||
94 | 14783 | amunoz | /**
|
95 | * Lanzar el Thread del proceso de clasificaci?n por el metodo de m?xima probabilidad.
|
||
96 | */
|
||
97 | 13790 | dguerrero | public void start() { |
98 | blinker = new Thread(this); |
||
99 | blinker.start(); |
||
100 | } |
||
101 | |||
102 | 14783 | amunoz | /*
|
103 | * (non-Javadoc)
|
||
104 | * @see java.lang.Runnable#run()
|
||
105 | */
|
||
106 | 13790 | dguerrero | public void run() { |
107 | RasterTaskQueue.register(rasterTask); |
||
108 | 14465 | amunoz | setGrid(); |
109 | 14174 | amunoz | rasterResult= RasterBuffer.getBuffer(IBuffer.TYPE_DOUBLE, inputGrid.getRasterBuf().getWidth(), inputGrid.getRasterBuf().getHeight(), 1, true); |
110 | 13979 | amunoz | int c=0; |
111 | 14174 | amunoz | int iNY= inputGrid.getLayerNY();
|
112 | int iNX= inputGrid.getLayerNX();
|
||
113 | 14640 | gsdiego | bandCount = inputGrid.getBandCount(); |
114 | 14180 | amunoz | |
115 | 14640 | gsdiego | means = new double[numClases][bandCount]; |
116 | for (int clase=0; clase<numClases; clase++) |
||
117 | for (int i=0;i<bandCount;i++){ |
||
118 | ((ROI)rois.get(clase)).setBandToOperate(bandList[i]); |
||
119 | 16598 | amunoz | try{
|
120 | means[clase][i]=((ROI)rois.get(clase)).getMeanValue(); |
||
121 | }catch (GridException e) {
|
||
122 | RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e); |
||
123 | } |
||
124 | 14640 | gsdiego | } |
125 | |||
126 | 13956 | amunoz | try{
|
127 | 14640 | gsdiego | int inputGridNX = inputGrid.getNX();
|
128 | int datType = inputGrid.getRasterBuf().getDataType();
|
||
129 | |||
130 | 14174 | amunoz | // Se calculan las inversas de las matrices de Varianza-covarianza de todas las rois y se almacenan en inverseVarCovMAtrix
|
131 | 14591 | gsdiego | Matrix S = null;
|
132 | Matrix inverseS = null;
|
||
133 | 14181 | amunoz | inverseVarCovMatrix= new Matrix[numClases];
|
134 | 14591 | gsdiego | detS = new double [numClases]; |
135 | 14506 | gsdiego | double varCovarMatrix[][] = null; |
136 | double subMatrix[][] = null; |
||
137 | 13790 | dguerrero | |
138 | 14181 | amunoz | for (int i=0; i<numClases;i++){ |
139 | 16598 | amunoz | try{
|
140 | varCovarMatrix = ((ROI)rois.get(i)).getVarCovMatrix(); |
||
141 | }catch (GridException e) {
|
||
142 | RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e); |
||
143 | } |
||
144 | 14506 | gsdiego | if (bandList.length != raster.getBandCount()){
|
145 | /*
|
||
146 | * Extraer la submatiz correspondiente a las bandas que intervienen:
|
||
147 | */
|
||
148 | subMatrix = new double[bandList.length][bandList.length]; |
||
149 | for (int iBand = 0; iBand < bandList.length; iBand++) |
||
150 | for (int jBand = 0; jBand < bandList.length; jBand++) |
||
151 | subMatrix[iBand][jBand]=varCovarMatrix[bandList[iBand]][bandList[jBand]]; |
||
152 | 14591 | gsdiego | S = new Matrix(subMatrix);
|
153 | 14506 | gsdiego | }else
|
154 | 16598 | amunoz | try {
|
155 | S = new Matrix(((ROI)rois.get(i)).getVarCovMatrix());
|
||
156 | inverseS = S.inverse(); |
||
157 | detS[i] = S.det(); |
||
158 | 14506 | gsdiego | |
159 | 16598 | amunoz | } catch (RuntimeException e) { |
160 | incrementableTask.processFinalize(); |
||
161 | RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_clasificacion_roi") +((ROI)rois.get(i)).getName(),this); |
||
162 | return;
|
||
163 | } catch (GridException e) {
|
||
164 | RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e); |
||
165 | } |
||
166 | |||
167 | 14506 | gsdiego | inverseVarCovMatrix[i]= inverseS; |
168 | 14174 | amunoz | } |
169 | |||
170 | 14762 | amunoz | // Caso Buffer tipo Byte
|
171 | 14640 | gsdiego | if (datType == RasterBuffer.TYPE_BYTE){
|
172 | 14174 | amunoz | |
173 | byte data[]= new byte[inputGrid.getBandCount()]; |
||
174 | for(int i=0; i<iNY;i++){ |
||
175 | for(int j=0; j<iNX;j++){ |
||
176 | inputGrid.getRasterBuf().getElemByte(i, j, data); |
||
177 | c= getPixelClassForTypeByte(data); |
||
178 | rasterResult.setElem(i, j, 0,(double) c); |
||
179 | } |
||
180 | 14640 | gsdiego | percent = i*100/inputGridNX;
|
181 | 13790 | dguerrero | } |
182 | } |
||
183 | 13979 | amunoz | |
184 | 14174 | amunoz | // Caso Buffer tipo Short
|
185 | 14640 | gsdiego | if (datType == RasterBuffer.TYPE_SHORT){
|
186 | 14174 | amunoz | short data[]= new short[inputGrid.getBandCount()]; |
187 | for(int i=0; i<iNY;i++){ |
||
188 | for(int j=0; j<iNX;j++){ |
||
189 | inputGrid.getRasterBuf().getElemShort(i, j, data); |
||
190 | c= getPixelClassForTypeShort(data); |
||
191 | rasterResult.setElem(i, j, 0,(double)c); |
||
192 | } |
||
193 | 14640 | gsdiego | percent = i*100/inputGridNX;
|
194 | 14174 | amunoz | } |
195 | } |
||
196 | |||
197 | // Caso Buffer tipo Int
|
||
198 | 14640 | gsdiego | if (datType == RasterBuffer.TYPE_INT){
|
199 | 14174 | amunoz | int data[]= new int[inputGrid.getBandCount()]; |
200 | for(int i=0; i<iNY;i++){ |
||
201 | for(int j=0; j<iNX;j++){ |
||
202 | inputGrid.getRasterBuf().getElemInt(i, j, data); |
||
203 | c= getPixelClassForTypeInt(data); |
||
204 | rasterResult.setElem(i, j, 0,(double) c); |
||
205 | } |
||
206 | 14640 | gsdiego | percent = i*100/inputGridNX;
|
207 | 14174 | amunoz | } |
208 | } |
||
209 | 13790 | dguerrero | |
210 | 13979 | amunoz | |
211 | 14174 | amunoz | // Caso Buffer tipo Float
|
212 | 14640 | gsdiego | if (datType == RasterBuffer.TYPE_FLOAT){
|
213 | 14174 | amunoz | float data[]= new float[inputGrid.getBandCount()]; |
214 | for(int i=0; i<iNY;i++){ |
||
215 | for(int j=0; j<iNX;j++){ |
||
216 | inputGrid.getRasterBuf().getElemFloat(i, j, data); |
||
217 | c= getPixelClassForTypeFloat(data); |
||
218 | rasterResult.setElem(i, j, 0,(double) c); |
||
219 | } |
||
220 | 14640 | gsdiego | percent = i*100/inputGridNX;
|
221 | 14174 | amunoz | } |
222 | } |
||
223 | 13979 | amunoz | |
224 | 14174 | amunoz | |
225 | 14483 | amunoz | // Caso Buffer tipo Double
|
226 | 14640 | gsdiego | if (datType == RasterBuffer.TYPE_DOUBLE){
|
227 | 14174 | amunoz | double data[]= new double[inputGrid.getBandCount()]; |
228 | for(int i=0; i<iNY;i++){ |
||
229 | for(int j=0; j<iNX;j++){ |
||
230 | inputGrid.getRasterBuf().getElemDouble(i, j, data); |
||
231 | c= getPixelClassForTypeDouble(data); |
||
232 | rasterResult.setElem(i, j, 0,(double) c); |
||
233 | } |
||
234 | 14640 | gsdiego | percent = i*100/inputGridNX;
|
235 | 13979 | amunoz | } |
236 | } |
||
237 | 14174 | amunoz | |
238 | 14483 | amunoz | writeToFile(); |
239 | 14528 | amunoz | |
240 | 14465 | amunoz | }finally {
|
241 | 14174 | amunoz | RasterTaskQueue.remove(rasterTask); |
242 | 14465 | amunoz | } |
243 | 14174 | amunoz | } // Fin run()
|
244 | 14322 | gsdiego | |
245 | 14762 | amunoz | |
246 | 14174 | amunoz | /**
|
247 | 14762 | amunoz | * Metodo que implementa el clasificador de maxima probabilidad. Para cada
|
248 | * pixel, obtiene la clase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'*inverse(Si)*Y
|
||
249 | *
|
||
250 | * @param array de tipo byte con valores del pixel en cada una de las bandas
|
||
251 | * @return clase a la que pertenece el pixel
|
||
252 | */
|
||
253 | 14174 | amunoz | public int getPixelClassForTypeByte(byte pixelBandsValues[]){ |
254 | 14508 | amunoz | double probability=0.0, finalProbability=0.0; |
255 | int claseFinal=0; |
||
256 | 14180 | amunoz | for (int clase=0; clase<numClases;clase++) |
257 | 14174 | amunoz | { |
258 | 14640 | gsdiego | double[][] y = new double[bandCount][1]; |
259 | for (int i=0;i<bandCount;i++){ |
||
260 | y[i][0]=pixelBandsValues[i]-means[clase][i];
|
||
261 | 14174 | amunoz | } |
262 | 14591 | gsdiego | Y = new Matrix(y);
|
263 | result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y); |
||
264 | 14174 | amunoz | // Obtencion probabilidad de pertenencia del pixel a la clase clase
|
265 | 15999 | gsdiego | probability= Math.log(detS[clase])+ result.get(0, 0); |
266 | 14508 | amunoz | if(clase==0) |
267 | finalProbability=probability; |
||
268 | 14640 | gsdiego | else if(probability<finalProbability){ |
269 | 14508 | amunoz | finalProbability=probability; |
270 | claseFinal=clase; |
||
271 | } |
||
272 | 14174 | amunoz | } |
273 | 14508 | amunoz | return claseFinal;
|
274 | 14174 | amunoz | } |
275 | 13956 | amunoz | |
276 | |||
277 | 14174 | amunoz | /**
|
278 | * Metodo que implementa el clasificador de maxima probabilidad.
|
||
279 | * Para cada pixel, obtiene la calase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'* inverse(Si)*Y
|
||
280 | *
|
||
281 | 14762 | amunoz | * @param array de tipo short con valores del pixel en cada una de las bandas
|
282 | 14174 | amunoz | * @return clase a la que pertenece el pixel (por el metodo de maxima probabilidad)
|
283 | 14762 | amunoz | */
|
284 | 14174 | amunoz | public int getPixelClassForTypeShort(short pixelBandsValues[]){ |
285 | 14508 | amunoz | double probability=0.0, finalProbability=0.0; |
286 | int claseFinal=0; |
||
287 | 14180 | amunoz | for (int clase=0; clase<numClases;clase++) |
288 | 14174 | amunoz | { |
289 | 14640 | gsdiego | double[][] y = new double[bandCount][1]; |
290 | for (int i=0;i<bandCount;i++){ |
||
291 | y[i][0]=pixelBandsValues[i]-means[clase][i];
|
||
292 | 14174 | amunoz | } |
293 | 14640 | gsdiego | Y = new Matrix(y);
|
294 | result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y); |
||
295 | 14174 | amunoz | // Obtencion probabilidad de pertenencia del pixel a la clase clase
|
296 | 14591 | gsdiego | probability= Math.log(detS[clase])+ result.get(0, 0); |
297 | 14508 | amunoz | if(clase==0) |
298 | finalProbability=probability; |
||
299 | 14640 | gsdiego | else if(probability<finalProbability){ |
300 | 14508 | amunoz | finalProbability=probability; |
301 | claseFinal=clase; |
||
302 | } |
||
303 | 14174 | amunoz | } |
304 | 14508 | amunoz | return claseFinal;
|
305 | 13790 | dguerrero | } |
306 | |||
307 | 14174 | amunoz | |
308 | 13790 | dguerrero | /**
|
309 | 14762 | amunoz | * Metodo que implementa el clasificador de maxima probabilidad.
|
310 | * Para cada pixel, obtiene la calase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'* inverse(Si)*Y
|
||
311 | *
|
||
312 | * @param array de tipo int con valores del pixel en cada una de las bandas
|
||
313 | * @return clase a la que pertenece el pixel (por el metodo de maxima probabilidad)
|
||
314 | */
|
||
315 | 14174 | amunoz | public int getPixelClassForTypeInt(int pixelBandsValues[]){ |
316 | 14508 | amunoz | double probability=0.0, finalProbability=0.0; |
317 | int claseFinal=0; |
||
318 | 14180 | amunoz | for (int clase=0; clase<numClases;clase++) |
319 | 13790 | dguerrero | { |
320 | 14640 | gsdiego | double[][] y = new double[bandCount][1]; |
321 | for (int i=0;i<bandCount;i++){ |
||
322 | y[i][0]=pixelBandsValues[i]-means[clase][i];
|
||
323 | 13790 | dguerrero | } |
324 | 14640 | gsdiego | Y = new Matrix(y);
|
325 | result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y); |
||
326 | 13790 | dguerrero | // Obtencion probabilidad de pertenencia del pixel a la clase clase
|
327 | 15999 | gsdiego | probability= Math.log(detS[clase])+ result.get(0, 0); |
328 | 14508 | amunoz | if(clase==0) |
329 | finalProbability=probability; |
||
330 | 14640 | gsdiego | else if(probability<finalProbability){ |
331 | 14508 | amunoz | finalProbability=probability; |
332 | claseFinal=clase; |
||
333 | } |
||
334 | 13790 | dguerrero | } |
335 | 14508 | amunoz | return claseFinal;
|
336 | 13790 | dguerrero | } |
337 | |||
338 | |||
339 | 14174 | amunoz | /**
|
340 | 14762 | amunoz | * Metodo que implementa el clasificador de maxima probabilidad.
|
341 | * Para cada pixel, obtiene la calase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'* inverse(Si)*Y
|
||
342 | *
|
||
343 | * @param array de tipo float con valores del pixel en cada una de las bandas
|
||
344 | * @return clase a la que pertenece el pixel (por el metodo de maxima probabilidad)
|
||
345 | */
|
||
346 | 14174 | amunoz | public int getPixelClassForTypeFloat(float pixelBandsValues[]){ |
347 | 14508 | amunoz | double probability=0.0, finalProbability=0.0; |
348 | int claseFinal=0; |
||
349 | for (int clase=0; clase<numClases;clase++) |
||
350 | 14174 | amunoz | { |
351 | 14640 | gsdiego | double[][] y = new double[bandCount][1]; |
352 | for (int i=0;i<bandCount;i++){ |
||
353 | y[i][0]=pixelBandsValues[i]-means[clase][i];
|
||
354 | 14174 | amunoz | } |
355 | 14640 | gsdiego | Y = new Matrix(y);
|
356 | result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y); |
||
357 | 14174 | amunoz | // Obtencion probabilidad de pertenencia del pixel a la clase clase
|
358 | 15999 | gsdiego | probability= Math.log(detS[clase])+ result.get(0, 0); |
359 | 14508 | amunoz | if(clase==0) |
360 | finalProbability=probability; |
||
361 | 14640 | gsdiego | else if(probability<finalProbability){ |
362 | 14508 | amunoz | finalProbability=probability; |
363 | claseFinal=clase; |
||
364 | } |
||
365 | 14174 | amunoz | } |
366 | 14508 | amunoz | return claseFinal;
|
367 | 14174 | amunoz | } |
368 | 13790 | dguerrero | |
369 | 14322 | gsdiego | |
370 | 14174 | amunoz | /**
|
371 | 14762 | amunoz | * Metodo que implementa el clasificador de maxima probabilidad.
|
372 | * Para cada pixel, obtiene la calase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'* inverse(Si)*Y
|
||
373 | *
|
||
374 | * @param array de tipo double con valores del pixel en cada una de las bandas
|
||
375 | * @return clase a la que pertenece el pixel (por el metodo de maxima probabilidad)
|
||
376 | */
|
||
377 | 14174 | amunoz | public int getPixelClassForTypeDouble(double pixelBandsValues[]){ |
378 | 14508 | amunoz | double probability=0.0, finalProbability=0.0; |
379 | int claseFinal=0; |
||
380 | 14180 | amunoz | for (int clase=0; clase<numClases;clase++) |
381 | 13979 | amunoz | { |
382 | 14640 | gsdiego | double[][] y = new double[bandCount][1]; |
383 | for (int i=0;i<bandCount;i++){ |
||
384 | y[i][0]=pixelBandsValues[i]-means[clase][i];
|
||
385 | 13979 | amunoz | } |
386 | 14640 | gsdiego | Y = new Matrix(y);
|
387 | result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y); |
||
388 | 13979 | amunoz | // Obtencion probabilidad de pertenencia del pixel a la clase clase
|
389 | 15999 | gsdiego | probability= Math.log(detS[clase])+ result.get(0, 0); |
390 | 14508 | amunoz | if(clase==0) |
391 | finalProbability=probability; |
||
392 | 14640 | gsdiego | else if(probability<finalProbability){ |
393 | 14508 | amunoz | finalProbability=probability; |
394 | claseFinal=clase; |
||
395 | } |
||
396 | 13979 | amunoz | } |
397 | 14508 | amunoz | return claseFinal;
|
398 | 13790 | dguerrero | } |
399 | } |