Statistics
| Revision:

root / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / principalcomponents / PCStatisticsProcess.java @ 22761

History | View | Annotate | Download (12.4 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.principalcomponents;
42

    
43
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
44
import org.gvsig.raster.RasterProcess;
45
import org.gvsig.raster.buffer.BufferFactory;
46
import org.gvsig.raster.buffer.RasterBuffer;
47
import org.gvsig.raster.buffer.RasterBufferInvalidException;
48
import org.gvsig.raster.dataset.IRasterDataSource;
49
import org.gvsig.raster.grid.Grid;
50
import org.gvsig.raster.grid.GridException;
51
import org.gvsig.raster.util.RasterToolsUtil;
52

    
53
import Jama.EigenvalueDecomposition;
54
import Jama.Matrix;
55

    
56
import com.iver.andami.PluginServices;
57

    
58
/**
59
 *        PCStatisticsProcess es la clase que implementa el proceso c?lculo de estad?sticas avanzado
60
 *        para el an?lisis de componentes principales. Para la imagen y las bandas de entrada se calcula 
61
 *        la matriz de varianza-covarianza y los atovalores y autovectrores asociados .
62
 *
63
 *        @author Alejandro Mu?oz Sanchez (alejandro.munoz@uclm.es)
64
 *        @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
65
 *        @version 19/10/2007 
66
 */
67

    
68
public class PCStatisticsProcess extends RasterProcess{
69
        
70
        private Grid                                                                 inputGrid                         = null;
71
        private double                                                                autovalors[]                = null;
72
        private Matrix                                                                 coVarMatrix                        = null;
73
        private Matrix                                                                 autoVectorMatrix        = null;
74
        private int                                                                 percent                           = 0;
75
        private boolean                                                         cancel                                 = false;
76
        private        boolean                                                         selectedBands[]                 =null;
77
        private FLyrRasterSE                                                inputRasterLayer        = null;
78
        
79
        /**
80
         * Constructor
81
         */
82
        public PCStatisticsProcess() {
83
                
84
        }
85
        
86
        
87
        /**        
88
         *  C?lculo de la matriz de covarianza, autovalores y autovectores.
89
         */
90
        public void calculate() {
91
                 //Calculo de matriz de covarianza:
92
                double coVar[][]= covarianceOptimize();
93
                 // Calculo de autovectores:
94
                coVarMatrix = new Matrix(coVar);
95
                EigenvalueDecomposition eigenvalueDecomp = new EigenvalueDecomposition(coVarMatrix); 
96
                //Autovectores
97
                autoVectorMatrix= eigenvalueDecomp.getV();
98
                // Autovalores
99
                autovalors= eigenvalueDecomp.getRealEigenvalues();        
100
        }
101

    
102
                        
103
        /**
104
         * @return array con los autovalores
105
         */
106
        public Object getResult() {
107
                return autovalors;
108
        }
109
        
110
        /**
111
         * @return Matriz de autovectores
112
         */
113
        public Matrix getAutoVectorMatrix(){
114
                return autoVectorMatrix;
115
        }
116
        
117
        
118
        /**
119
         * @return Matriz varianza-covarianza
120
         */
121
        public Matrix getcoVarMatrix(){
122
                return coVarMatrix;
123
        }
124
        
125
        
126
        /**
127
         * C?lculo de la matriz varianza covarianza de las bandas de un Grid. 
128
         */
129
        private double[][] covarianceOptimize() {
130
                
131
                double dSum = 0;
132
                int iValues = 0;
133
                buildGrid();
134
                double[][] coV=new double[inputGrid.getRasterBuf().getBandCount()][inputGrid.getRasterBuf().getBandCount()];
135
                
136
                double cancelMatrix[][]=  new double[][]{{0}};
137
                double valorBandai=0, valorBandaj=0;
138
                int bandCount = inputGrid.getRasterBuf().getBandCount();
139
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_BYTE){
140
                        // Se recorre el grid obener la matriz de cov
141
                        for (int i = 0; i < bandCount; i++) {
142
                                for (int j = i; j < bandCount; j++) {
143
                                        // si  cancelado se devuelve  cancelMatrix
144
                                        if(cancel)
145
                                                return cancelMatrix;
146
                                        iValues=0;
147
                                        dSum = 0;
148
                                        // Calculo covarianza entre las bandas i,j
149
                                        for (int k=0; k<inputGrid.getNX(); k++){
150
                                                for (int l=0;l<inputGrid.getNY();l++){        
151
                                                                try{
152
                                                                        inputGrid.setBandToOperate(i);
153
                                                                        valorBandai=inputGrid.getCellValueAsByte(k,l) -inputGrid.getMeanValue();
154
                                                                        inputGrid.setBandToOperate(j);
155
                                                                        valorBandaj=inputGrid.getCellValueAsByte(k,l) -inputGrid.getMeanValue();
156
                                                                } catch (GridException e) {
157
                                                                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e);
158
                                                                }
159
                                                                dSum += valorBandai*valorBandaj;
160
                                                                iValues++;
161
                                                }
162
                                        }
163
                                        // Se asigna el valor a la matriz 
164
                                        if (iValues>1)
165
                                                coV[i][j]=dSum/(double)(iValues);        
166
                                        else
167
                                                coV[i][j]= inputGrid.getNoDataValue();
168
                                }
169
                
170
                        if (bandCount>1)
171
                                percent = (i+1)*100/(bandCount-1);
172
                        else
173
                                percent= (i+1)*100/(1);
174
                        }
175

    
176
                } // Fin tipo Byte
177
                
178
                
179
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_SHORT){
180
                        // Se recorre el grid obener la matriz de cov
181
                        for (int i = 0; i < bandCount; i++) {
182
                                for (int j = i; j < bandCount; j++) {
183
                                        if(cancel)
184
                                                return cancelMatrix;
185
                                        iValues=0;
186
                                        dSum = 0;
187
                                        // Calculo covarianza entre las bandas i,j
188
                                        for (int k=0; k<inputGrid.getNX(); k++){
189
                                                for (int l=0;l<inputGrid.getNY();l++){
190
                                                                try{
191
                                                                        inputGrid.setBandToOperate(i);
192
                                                                        valorBandai=inputGrid.getCellValueAsShort(k,l) -inputGrid.getMeanValue();
193
                                                                        inputGrid.setBandToOperate(j);
194
                                                                        valorBandaj=inputGrid.getCellValueAsShort(k,l) -inputGrid.getMeanValue();
195
                                                                } catch (GridException e) {
196
                                                                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e);
197
                                                                }
198
                                                                dSum += valorBandai*valorBandaj;
199
                                                                iValues++;
200
                                                }
201
                                        }
202
                                        // Se asigna el valor a la matriz 
203
                                        if (iValues>1)
204
                                                coV[i][j]=dSum/(double)(iValues);        
205
                                        else
206
                                                coV[i][j]= inputGrid.getNoDataValue();
207
        
208
                                }
209
                
210
                        if (bandCount>1)
211
                                percent = (i+1)*100/(bandCount-1);
212
                        else
213
                                percent= (i+1)*100/(1);
214
                        }
215

    
216
                } // Fin tipo Short
217
                
218
                
219
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_INT){
220
                        // Se recorre el grid obener la matriz de cov
221
                        for (int i = 0; i < bandCount; i++) {
222
                                for (int j = i; j < bandCount; j++) {
223
                                        if(cancel)
224
                                                return cancelMatrix;
225
                                        iValues=0;
226
                                        dSum = 0;
227
                                        // Calculo covarianza entre las bandas i,j
228
                                        for (int k=0; k<inputGrid.getNX(); k++){
229
                                                for (int l=0;l<inputGrid.getNY();l++){
230
                                                                try{
231
                                                                        inputGrid.setBandToOperate(i);
232
                                                                        valorBandai=inputGrid.getCellValueAsInt(k,l) -inputGrid.getMeanValue();
233
                                                                        inputGrid.setBandToOperate(j);
234
                                                                        valorBandaj=inputGrid.getCellValueAsInt(k,l) -inputGrid.getMeanValue();
235
                                                                } catch (GridException e) {
236
                                                                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e);
237
                                                                }
238
                                                                dSum += valorBandai*valorBandaj;
239
                                                                iValues++;
240
                                                }
241
                                        }
242
                                        // Se asigna el valor a la matriz 
243
                                        if (iValues>1)
244
                                                coV[i][j]=dSum/(double)(iValues);        
245
                                        else
246
                                                coV[i][j]= inputGrid.getNoDataValue();
247
                                }
248
                
249
                        if (bandCount>1)
250
                                percent = (i+1)*100/(bandCount-1);
251
                        else
252
                                percent= (i+1)*100/(1);
253
                        }
254

    
255
                } // Fin tipo Int
256
                
257
                
258
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_FLOAT){
259
                        // Se recorre el grid obener la matriz de cov
260
                        for (int i = 0; i < bandCount; i++) {
261
                                for (int j = i; j < bandCount; j++) {
262
                                        if(cancel)
263
                                                return  cancelMatrix;
264
                                        iValues=0;
265
                                        dSum = 0;
266
                                        // Calculo la covarianza entre las bandas i,j
267
                                        for (int k=0; k<inputGrid.getNX(); k++){
268
                                                for (int l=0;l<inputGrid.getNY();l++){                                                
269
                                                                try{
270
                                                                        inputGrid.setBandToOperate(i);
271
                                                                        valorBandai=inputGrid.getCellValueAsFloat(k,l) -inputGrid.getMeanValue();
272
                                                                        inputGrid.setBandToOperate(j);
273
                                                                        valorBandaj=inputGrid.getCellValueAsFloat(k,l) -inputGrid.getMeanValue();
274
                                                                } catch (GridException e) {
275
                                                                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e);
276
                                                                }
277
                                                                dSum += valorBandai*valorBandaj;
278
                                                                iValues++;
279
                                                }
280
                                        }
281
                                        // Se asigna el valor a la matriz 
282
                                        if (iValues>1)
283
                                                coV[i][j]=dSum/(double)(iValues);        
284
                                        else
285
                                                coV[i][j]= inputGrid.getNoDataValue();
286
                                }
287
                
288
                        if (bandCount>1)
289
                                percent = (i+1)*100/(bandCount-1);
290
                        else
291
                                percent= (i+1)*100/(1);
292
                        }
293

    
294
                } // Fin tipo Float
295
                
296
        
297
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_DOUBLE){
298
                        // Se recorre el grid obener la matriz de cov
299
                        for (int i = 0; i < bandCount; i++) {
300
                                for (int j = i; j < bandCount; j++) {
301
                                        if(cancel)
302
                                                return cancelMatrix;
303
                                        iValues=0;
304
                                        dSum = 0;
305
                                        // Calculo la covarianza entre las bandas i,j
306
                                        for (int k=0; k<inputGrid.getNX(); k++){
307
                                                for (int l=0;l<inputGrid.getNY();l++){
308
                                                                try{
309
                                                                        inputGrid.setBandToOperate(i);
310
                                                                        valorBandai=inputGrid.getCellValueAsDouble(k,l) -inputGrid.getMeanValue();
311
                                                                        inputGrid.setBandToOperate(j);
312
                                                                        valorBandaj=inputGrid.getCellValueAsDouble(k,l) -inputGrid.getMeanValue();
313
                                                                } catch (GridException e) {
314
                                                                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e);
315
                                                                }
316
                                                                dSum += valorBandai*valorBandaj;
317
                                                                iValues++;
318
                                                }
319
                                        }
320
                                        // Asigno el valor a la matriz 
321
                                        if (iValues>1)
322
                                                coV[i][j]=dSum/(double)(iValues);        
323
                                        else
324
                                                coV[i][j]= inputGrid.getNoDataValue();
325
                                }
326
                
327
                        if (bandCount>1)
328
                                percent = (i+1)*100/(bandCount-1);
329
                        else
330
                                percent= (i+1)*100/(1);
331
                        }
332

    
333
                } // Fin tipo Double
334

    
335
                for (int i = 0; i < bandCount; i++) {
336
                        for (int j = 0; j < bandCount; j++) {
337
                                if(j<i)
338
                                        coV[i][j]=coV[j][i];
339
                        }
340
                }
341
        
342
                return coV;
343
        }
344
        
345

    
346
        
347
        /**
348
         * Construye el grid con las bandas seleccionadas
349
         */
350
        private void buildGrid(){
351
        
352
                IRasterDataSource dsetCopy = null; 
353
                dsetCopy = inputRasterLayer.getDataSource().newDataset();
354
                BufferFactory bufferFactory = new BufferFactory(dsetCopy);
355
                if (!RasterBuffer.loadInMemory(dsetCopy))
356
                        bufferFactory.setReadOnly(true);
357
                
358
                int longitud=0;
359
                for (int i=0; i<selectedBands.length;i++)
360
                                if (selectedBands[i]) longitud++;
361
                        
362
                int bands[]= new int[longitud];
363
                int j=0;
364
                for (int i=0; i<selectedBands.length; i++)
365
                        if (selectedBands[i])
366
                                { bands[j]=i;
367
                                                 j++;
368
                                }
369
                try {
370
                                inputGrid = new Grid(bufferFactory, bands);        
371
                } catch (RasterBufferInvalidException e) {
372
                                        e.printStackTrace();                        
373
                }
374
        }
375
        
376
        
377
        /*
378
         * (non-Javadoc)
379
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getLabel()
380
         */
381
        public String getLabel() {
382
                return  PluginServices.getText(this,"procesando");
383
        }
384

    
385
        /*
386
         * (non-Javadoc)
387
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getLog()
388
         */
389
        public String getLog() {
390
                return PluginServices.getText(this,"calculando_estadisticas")+"...";
391
        }
392

    
393
        
394
        /*
395
         * (non-Javadoc)
396
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
397
         */
398
        public int getPercent() {
399
                return percent;
400
        }
401

    
402
        /*
403
         * (non-Javadoc)
404
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
405
         */
406
        public String getTitle() {
407
                return PluginServices.getText(this,"principal_components");
408
        }
409

    
410
        /**
411
         * @return grid 
412
         */
413
        public Grid getInputGrid() {
414
                return inputGrid;
415
        }
416
        
417
        /**
418
         * @return raster de entrada
419
         * */
420
        public FLyrRasterSE getRasterLayer(){
421
                return inputRasterLayer;
422
        }
423

    
424
        
425
        public void init() {
426
                // Se toman los parametros del proceso
427
                selectedBands = (boolean []) getParam("selectedBands");
428
                inputRasterLayer = getLayerParam("layer");
429
        }
430

    
431

    
432
        /**
433
         *  Proceso de calculo de estadisticas para Principal Component
434
         * */
435
        public void process() throws InterruptedException {
436

    
437
                        double coVar[][]= covarianceOptimize();
438
                         // Calculo de autovectores:
439
                        coVarMatrix = new Matrix(coVar);
440
                        EigenvalueDecomposition eigenvalueDecomp = new EigenvalueDecomposition(coVarMatrix); 
441
                        //Autovectores
442
                        autoVectorMatrix= eigenvalueDecomp.getV();
443
                        // Autovalores
444
                        autovalors= eigenvalueDecomp.getRealEigenvalues();        
445
                        
446
                        if(!cancel)
447
                                if(incrementableTask!=null)
448
                                        incrementableTask.processFinalize();
449
                                        
450
                        if (externalActions!=null)
451
                                externalActions.end(autovalors);
452
        }
453

    
454
        public void interrupted() {
455
                // TODO Auto-generated method stub
456
                
457
        }
458

    
459
}