Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extRemoteSensing / src / org / gvsig / remotesensing / classification / ClassificationMaximumLikelihoodProcess.java @ 31496

History | View | Annotate | Download (12.5 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

    
45
import org.gvsig.andami.PluginServices;
46
import org.gvsig.app.project.documents.view.gui.DefaultViewPanel;
47
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
48
import org.gvsig.raster.buffer.RasterBuffer;
49
import org.gvsig.raster.dataset.IBuffer;
50
import org.gvsig.raster.grid.GridException;
51
import org.gvsig.raster.grid.roi.ROI;
52
import org.gvsig.raster.util.RasterToolsUtil;
53

    
54
import Jama.Matrix;
55

    
56

    
57
/** ClassificationMaximumLikelihoodProcess implementa el m?todo de clasificaci?n de 
58
 * m?xima probabilidad.
59
 * 
60
 * @see ClassificationGeneralProcess
61
 * @author Alejandro Mu?oz Sanchez (alejandro.munoz@uclm.es)
62
 * @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
63
 * @version 19/10/2007 
64
*/
65

    
66
public class ClassificationMaximumLikelihoodProcess extends ClassificationGeneralProcess{
67
        
68
        private Matrix                                         Y                                                = null;
69
        private Matrix                                         result                                        = null;
70
        private Matrix                                         inverseVarCovMatrix []        = null;
71
        private double                                        detS []                                        = null;
72
        private double                                         means[][]                                 = null;
73
        private int                                         bandCount                                 = 0;
74

    
75
        /** 
76
        * Class constructor.
77
        */
78
        public  ClassificationMaximumLikelihoodProcess(){
79
        
80
        }
81
        
82
        
83
        /**
84
        * Metodo que implementa el clasificador de maxima probabilidad. Para cada 
85
        * pixel, obtiene la clase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'*inverse(Si)*Y
86
        * 
87
        * @param  array de tipo byte con valores del pixel en cada una de las bandas 
88
        * @return clase a la que pertenece el pixel
89
        */
90
        public int getPixelClassForTypeByte(byte pixelBandsValues[]){
91
                double probability=0.0, finalProbability=0.0; 
92
                int claseFinal=0;
93
                for (int clase=0; clase<numClases;clase++)
94
                {
95
                        double[][] y = new double[bandCount][1];
96
                        for (int i=0;i<bandCount;i++){
97
                                y[i][0]=pixelBandsValues[i]-means[clase][i];
98
                        }
99
                        Y = new Matrix(y);
100
                        result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y);
101
                        // Obtencion probabilidad de pertenencia del pixel a la clase clase
102
                        probability= Math.log(detS[clase])+ result.get(0, 0);
103
                        if(clase==0)
104
                                finalProbability=probability;
105
                        else if(probability<finalProbability){
106
                                finalProbability=probability;
107
                                claseFinal=clase;
108
                                }
109
                }        
110
                return claseFinal;
111
        }
112
        
113
        
114
        /**
115
         * Metodo que implementa el clasificador de maxima probabilidad. 
116
         * Para cada pixel, obtiene la calase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'* inverse(Si)*Y
117
         * 
118
         * @param array de tipo short con valores del pixel en cada una de las bandas
119
         * @return clase a la que pertenece el pixel (por el metodo de maxima probabilidad)
120
         */
121
        public int getPixelClassForTypeShort(short pixelBandsValues[]){
122
                double probability=0.0, finalProbability=0.0; 
123
                int claseFinal=0;
124
                for (int clase=0; clase<numClases;clase++)
125
                {
126
                        double[][] y = new double[bandCount][1];
127
                        for (int i=0;i<bandCount;i++){
128
                                y[i][0]=pixelBandsValues[i]-means[clase][i];
129
                        }
130
                        Y = new Matrix(y);
131
                        result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y);
132
                        // Obtencion probabilidad de pertenencia del pixel a la clase clase
133
                        probability= Math.log(detS[clase])+ result.get(0, 0);
134
                        if(clase==0)
135
                                finalProbability=probability;
136
                        else if(probability<finalProbability){
137
                                finalProbability=probability;
138
                                claseFinal=clase;
139
                                }
140
                }        
141
                return claseFinal;
142
        }
143
        
144
        
145
        /**
146
        * Metodo que implementa el clasificador de maxima probabilidad. 
147
        * Para cada pixel, obtiene la calase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'* inverse(Si)*Y
148
        * 
149
        * @param array de tipo int con valores del pixel en cada una de las bandas
150
        * @return clase a la que pertenece el pixel (por el metodo de maxima probabilidad)
151
        */
152
        public int getPixelClassForTypeInt(int pixelBandsValues[]){
153
                double probability=0.0, finalProbability=0.0; 
154
                int claseFinal=0;
155
                for (int clase=0; clase<numClases;clase++)
156
                {
157
                        double[][] y = new double[bandCount][1];
158
                        for (int i=0;i<bandCount;i++){
159
                                y[i][0]=pixelBandsValues[i]-means[clase][i];
160
                        }
161
                        Y = new Matrix(y);
162
                        result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y);
163
                        // Obtencion probabilidad de pertenencia del pixel a la clase clase
164
                        probability= Math.log(detS[clase])+ result.get(0, 0);
165
                        if(clase==0)
166
                                finalProbability=probability;
167
                        else if(probability<finalProbability){
168
                                finalProbability=probability;
169
                                claseFinal=clase;
170
                                }
171
                }        
172
                return claseFinal;
173
        }
174
        
175
        
176
        /**
177
        * Metodo que implementa el clasificador de maxima probabilidad. 
178
        * Para cada pixel, obtiene la calase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'* inverse(Si)*Y
179
        * 
180
        * @param array de tipo float con valores del pixel en cada una de las bandas
181
        * @return clase a la que pertenece el pixel (por el metodo de maxima probabilidad)
182
        */
183
        public int getPixelClassForTypeFloat(float pixelBandsValues[]){
184
                double probability=0.0, finalProbability=0.0; 
185
                int claseFinal=0;
186
                for (int clase=0; clase<numClases;clase++)
187
                {
188
                        double[][] y = new double[bandCount][1];
189
                        for (int i=0;i<bandCount;i++){
190
                                y[i][0]=pixelBandsValues[i]-means[clase][i];
191
                        }
192
                        Y = new Matrix(y);
193
                        result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y);
194
                        // Obtencion probabilidad de pertenencia del pixel a la clase clase
195
                        probability= Math.log(detS[clase])+ result.get(0, 0);
196
                        if(clase==0)
197
                                finalProbability=probability;
198
                        else if(probability<finalProbability){
199
                                finalProbability=probability;
200
                                claseFinal=clase;
201
                                }
202
                }        
203
                return claseFinal;
204
        }
205
        
206

    
207
        /**
208
        * Metodo que implementa el clasificador de maxima probabilidad. 
209
        * Para cada pixel, obtiene la calase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'* inverse(Si)*Y
210
        * 
211
        * @param array de tipo double con valores del pixel en cada una de las bandas
212
        * @return clase a la que pertenece el pixel (por el metodo de maxima probabilidad)
213
        */
214
        public int getPixelClassForTypeDouble(double pixelBandsValues[]){
215
                double probability=0.0, finalProbability=0.0; 
216
                int claseFinal=0;
217
                for (int clase=0; clase<numClases;clase++)
218
                {
219
                        double[][] y = new double[bandCount][1];
220
                        for (int i=0;i<bandCount;i++){
221
                                y[i][0]=pixelBandsValues[i]-means[clase][i];
222
                        }
223
                        Y = new Matrix(y);
224
                        result= (Y.transpose().times(inverseVarCovMatrix[clase])).times(Y);
225
                        // Obtencion probabilidad de pertenencia del pixel a la clase clase
226
                        probability= Math.log(detS[clase])+ result.get(0, 0);
227
                        if(clase==0)
228
                                finalProbability=probability;
229
                        else if(probability<finalProbability){
230
                                finalProbability=probability;
231
                                claseFinal=clase;
232
                                }
233
                }        
234
                return claseFinal;
235
        }
236

    
237
        /** Metodo que recoge los parametros del proceso de clasificacion de 
238
        * m?xima probabilidad 
239
        * <LI>rasterSE: Capa de entrada para la clasificaci?n</LI>
240
        * <LI> rois: lista de rois</LI> 
241
        * <LI> bandList:bandas habilitadas </LI> 
242
        * <LI>view: vista sobre la que se carga la capa al acabar el proceso</LI>
243
        * <LI>filename: path con el fichero de salida</LI>
244
        */
245
        public void init() {
246
                rasterSE= (FLyrRasterSE)getParam("layer");
247
                rois = (ArrayList)getParam("rois");
248
                view=(DefaultViewPanel)getParam("view");
249
                filename= getStringParam("filename");
250
                bandList = (int[])getParam("bandList");
251
                numClases = rois.size();
252
        }
253

    
254

    
255
        /** Proceso de clasificaci?n de m?xima probabilidad */
256
        public void process() throws InterruptedException {
257
                
258
                setGrid();
259
                rasterResult= RasterBuffer.getBuffer(IBuffer.TYPE_BYTE, inputGrid.getRasterBuf().getWidth(), inputGrid.getRasterBuf().getHeight(), 1, true);
260
                int c=0;
261
                int iNY= inputGrid.getLayerNY();
262
                int iNX= inputGrid.getLayerNX();
263
                bandCount  = inputGrid.getBandCount();
264
                
265
                means = new double[numClases][bandCount];
266
                for (int clase=0; clase<numClases; clase++)
267
                        for (int i=0;i<bandCount;i++){
268
                        ((ROI)rois.get(clase)).setBandToOperate(bandList[i]);
269
                        try{
270
                                means[clase][i]=((ROI)rois.get(clase)).getMeanValue();
271
                        }catch (GridException e) {
272
                                RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e);
273
                        }
274
                }
275
                
276
        
277
                        
278
                int inputGridNX = inputGrid.getNX();
279
                int datType = inputGrid.getRasterBuf().getDataType();
280
                        
281
                // Se calculan las inversas de las matrices de Varianza-covarianza de todas las rois y se almacenan en inverseVarCovMAtrix
282
                Matrix S = null;
283
                Matrix inverseS = null;
284
                inverseVarCovMatrix= new Matrix[numClases];
285
                detS = new double [numClases];
286
                double varCovarMatrix[][] = null;
287
                double subMatrix[][] = null;
288
                        
289
                for (int i=0; i<numClases;i++){
290
                        try{
291
                                varCovarMatrix = ((ROI)rois.get(i)).getVarCovMatrix();
292
                        }catch (GridException e) {
293
                                RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e);
294
                        }
295
                        if (bandList.length != rasterSE.getBandCount()){
296
                                /*
297
                                 * Extraer la submatiz correspondiente a las bandas que intervienen:
298
                                 */
299
                                subMatrix = new double[bandList.length][bandList.length];
300
                                for (int iBand = 0; iBand < bandList.length; iBand++)
301
                                        for (int jBand = 0; jBand < bandList.length; jBand++)
302
                                                subMatrix[iBand][jBand]=varCovarMatrix[bandList[iBand]][bandList[jBand]];
303
                                S = new Matrix(subMatrix);
304
                                inverseS = S.inverse();
305
                                detS[i]=S.det();
306
                        }else
307
                                try {
308
                                        S = new Matrix(((ROI)rois.get(i)).getVarCovMatrix());
309
                                        inverseS = S.inverse();        
310
                                        detS[i] = S.det();
311
                        
312
                                } catch (RuntimeException e) {
313
                                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_clasificacion_roi") +((ROI)rois.get(i)).getName(),this);
314
                                        return;
315
                                } catch (GridException e) {
316
                                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e);
317
                                }
318
                        
319
                        inverseVarCovMatrix[i]= inverseS;        
320
                 }
321
                
322
//                         Caso Buffer tipo Byte
323
                if (datType == RasterBuffer.TYPE_BYTE){
324
                        
325
                                byte data[]= new byte[inputGrid.getBandCount()];
326
                                for(int i=0; i<iNY;i++){
327
                                        for(int j=0; j<iNX;j++){
328
                                                inputGrid.getRasterBuf().getElemByte(i, j, data);
329
                                                c= getPixelClassForTypeByte(data);
330
                                                rasterResult.setElem(i, j, 0,(byte) c);
331
                                        }
332
                                        percent = i*100/inputGridNX;
333
                                }
334
                }
335
                
336
//                        Caso Buffer tipo Short
337
                if (datType == RasterBuffer.TYPE_SHORT){
338
                                short data[]= new short[inputGrid.getBandCount()];
339
                                for(int i=0; i<iNY;i++){
340
                                        for(int j=0; j<iNX;j++){
341
                                                inputGrid.getRasterBuf().getElemShort(i, j, data);
342
                                                c= getPixelClassForTypeShort(data);
343
                                                rasterResult.setElem(i, j, 0,(byte)c);
344
                                        }
345
                                        percent = i*100/inputGridNX;
346
                                }
347
                }
348
                        
349
//                         Caso Buffer tipo Int
350
                if (datType == RasterBuffer.TYPE_INT){
351
                                int data[]= new int[inputGrid.getBandCount()];
352
                                for(int i=0; i<iNY;i++){
353
                                        for(int j=0; j<iNX;j++){
354
                                                inputGrid.getRasterBuf().getElemInt(i, j, data);
355
                                                c= getPixelClassForTypeInt(data);
356
                                                rasterResult.setElem(i, j, 0,(byte) c);
357
                                        }
358
                                        percent = i*100/inputGridNX;
359
                                }
360
                }
361
                
362
                
363
//                         Caso Buffer tipo Float
364
                if (datType == RasterBuffer.TYPE_FLOAT){
365
                                float data[]= new float[inputGrid.getBandCount()];
366
                                for(int i=0; i<iNY;i++){
367
                                        for(int j=0; j<iNX;j++){
368
                                                inputGrid.getRasterBuf().getElemFloat(i, j, data);
369
                                                c= getPixelClassForTypeFloat(data);
370
                                                rasterResult.setElem(i, j, 0,(byte) c);
371
                                        }
372
                                        percent = i*100/inputGridNX;
373
                                }
374
                }
375
                        
376
                        
377
//                         Caso Buffer tipo Double
378
                if (datType == RasterBuffer.TYPE_DOUBLE){
379
                                double data[]= new double[inputGrid.getBandCount()];
380
                                for(int i=0; i<iNY;i++){
381
                                        for(int j=0; j<iNX;j++){
382
                                                inputGrid.getRasterBuf().getElemDouble(i, j, data);
383
                                                c= getPixelClassForTypeDouble(data);
384
                                                rasterResult.setElem(i, j, 0,(byte) c);
385
                                        }
386
                                        percent = i*100/inputGridNX;
387
                                }
388
                }
389
                        
390
                writeToFile();        
391
        //        incrementableTask.processFinalize();
392
        }
393
}