Statistics
| Revision:

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

History | View | Annotate | Download (14 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.gui.beans.incrementabletask.IIncrementable;
44
import org.gvsig.gui.beans.incrementabletask.IncrementableEvent;
45
import org.gvsig.gui.beans.incrementabletask.IncrementableListener;
46
import org.gvsig.gui.beans.incrementabletask.IncrementableTask;
47
import org.gvsig.raster.buffer.BufferFactory;
48
import org.gvsig.raster.buffer.RasterBuffer;
49
import org.gvsig.raster.buffer.RasterBufferInvalidAccessException;
50
import org.gvsig.raster.buffer.RasterBufferInvalidException;
51
import org.gvsig.raster.dataset.IRasterDataSource;
52
import org.gvsig.raster.grid.Grid;
53
import org.gvsig.raster.process.CancelEvent;
54
import org.gvsig.raster.process.RasterTask;
55
import org.gvsig.raster.process.RasterTaskQueue;
56
import org.gvsig.remotesensing.principalcomponents.gui.PrincipalComponentCalculusPanel;
57

    
58
import Jama.EigenvalueDecomposition;
59
import Jama.Matrix;
60

    
61
import com.iver.andami.PluginServices;
62
import com.iver.cit.gvsig.project.documents.view.gui.View;
63

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

    
74
public class PCStatisticsProcess implements Runnable, IIncrementable, IncrementableListener{
75
        
76
        private Grid                                                                 inputGrid                         = null;
77
        private double                                                                autovalors[]                        = null;
78
        private Matrix                                                                 coVarMatrix                        = null;
79
        private Matrix                                                                 autoVectorMatrix        = null;
80
        private IncrementableTask                                        incrementableTask         = null;
81
        private int                                                                 percent                           = 0;
82
        private boolean                                                         cancel                                 = false;
83
        private Thread                                                                 blinker                                = null;
84
        private View                                                                 view                                = null;
85
        private RasterTask                                                        rasterTask = new RasterTask(this);
86
        private IRasterDataSource                                        raster                                = null;
87
        private        boolean                                                         selectedBands[]                 =null;
88
        
89
        
90
        /**
91
         * Constructor
92
         * @param raster raster al que se aplica la transformacion de PC
93
         * @param view vista actual de la aplicacion
94
         * @param selectedBands bandas  de la imagen seleccionadas para el proceso
95
         */
96
        public PCStatisticsProcess(IRasterDataSource raster,View view,boolean selectedBands[]) {
97
                this.raster= raster;
98
                this.view = view;
99
                this.selectedBands= selectedBands;
100
        }
101
        
102
        
103
        /**        
104
         *  C?lculo de la matriz de covarianza, autovalores y autovectores.
105
         */
106
        public void calculate() {
107
                 //Calculo de matriz de covarianza:
108
                double coVar[][]= covarianceOptimize();
109
                
110
                 // Calculo de autovectores:
111
                coVarMatrix = new Matrix(coVar);
112
                EigenvalueDecomposition eigenvalueDecomp = new EigenvalueDecomposition(coVarMatrix); 
113
                
114
                //Autovectores
115
                autoVectorMatrix= eigenvalueDecomp.getV();
116
            
117
                // Autovalores
118
                autovalors= eigenvalueDecomp.getRealEigenvalues();        
119
        }
120

    
121
                        
122
        /**
123
         * @return array con los autovalores
124
         */
125
        public double[] getResult() {
126
                return autovalors;
127
        }
128
        
129
        /**
130
         * @return Matriz de autovectores
131
         */
132
        public Matrix getAutoVectorMatrix(){
133
                return autoVectorMatrix;
134
        }
135
        
136
        
137
        /**
138
         * @return Matriz varianza-covarianza
139
         */
140
        public Matrix getcoVarMatrix(){
141
                return coVarMatrix;
142
        }
143
        
144
        
145
        /**
146
         * C?lculo de la matriz varianza covarianza de las bandas de un Grid. 
147
         */
148
        private double[][] covarianceOptimize() {
149
                
150
                double dSum = 0;
151
                int iValues = 0;
152
                double[][] coV =new double[inputGrid.getRasterBuf().getBandCount()][inputGrid.getRasterBuf().getBandCount()];
153
                double cancelMatrix[][]=  new double[][]{{0}};
154
                double valorBandai=0, valorBandaj=0;
155
                int bandCount = inputGrid.getRasterBuf().getBandCount();
156
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_BYTE){
157
                        // Se recorre el grid obener la matriz de cov
158
                        for (int i = 0; i < bandCount; i++) {
159
                                for (int j = i; j < bandCount; j++) {
160
                                        // si  cancelado se devuelve  cancelMatrix
161
                                        if(cancel)
162
                                                return cancelMatrix;
163
                                        iValues=0;
164
                                        dSum = 0;
165
                                        // Calculo covarianza entre las bandas i,j
166
                                        for (int k=0; k<inputGrid.getNX(); k++){
167
                                                for (int l=0;l<inputGrid.getNY();l++){        
168
                                                                try{
169
                                                                        inputGrid.setBandToOperate(i);
170
                                                                        valorBandai=inputGrid.getCellValueAsByte(k,l) -inputGrid.getMeanValue();
171
                                                                        inputGrid.setBandToOperate(j);
172
                                                                        valorBandaj=inputGrid.getCellValueAsByte(k,l) -inputGrid.getMeanValue();
173
                                                                } catch (RasterBufferInvalidAccessException e) {e.printStackTrace();}
174
                                                                dSum += valorBandai*valorBandaj;
175
                                                                iValues++;
176
                                                }
177
                                        }
178
                                        // Se asigna el valor a la matriz 
179
                                        if (iValues>1)
180
                                                coV[i][j]=dSum/(double)(iValues);        
181
                                        else
182
                                                coV[i][j]= inputGrid.getNoDataValue();
183
                                }
184
                
185
                        if (bandCount>1)
186
                                percent = (i+1)*100/(bandCount-1);
187
                        else
188
                                percent= (i+1)*100/(1);
189
                        }
190

    
191
                } // Fin tipo Byte
192
                
193
                
194
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_SHORT){
195
                        // Se recorre el grid obener la matriz de cov
196
                        for (int i = 0; i < bandCount; i++) {
197
                                for (int j = i; j < bandCount; j++) {
198
                                        if(cancel)
199
                                                return cancelMatrix;
200
                                        iValues=0;
201
                                        dSum = 0;
202
                                        // Calculo covarianza entre las bandas i,j
203
                                        for (int k=0; k<inputGrid.getNX(); k++){
204
                                                for (int l=0;l<inputGrid.getNY();l++){
205
                                                                try{
206
                                                                        inputGrid.setBandToOperate(i);
207
                                                                        valorBandai=inputGrid.getCellValueAsShort(k,l) -inputGrid.getMeanValue();
208
                                                                        inputGrid.setBandToOperate(j);
209
                                                                        valorBandaj=inputGrid.getCellValueAsShort(k,l) -inputGrid.getMeanValue();
210
                                                                } catch (RasterBufferInvalidAccessException e) {e.printStackTrace();}
211
                                                                dSum += valorBandai*valorBandaj;
212
                                                                iValues++;
213
                                                }
214
                                        }
215
                                        // Se asigna el valor a la matriz 
216
                                        if (iValues>1)
217
                                                coV[i][j]=dSum/(double)(iValues);        
218
                                        else
219
                                                coV[i][j]= inputGrid.getNoDataValue();
220
        
221
                                }
222
                
223
                        if (bandCount>1)
224
                                percent = (i+1)*100/(bandCount-1);
225
                        else
226
                                percent= (i+1)*100/(1);
227
                        }
228

    
229
                } // Fin tipo Short
230
                
231
                
232
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_INT){
233
                        // Se recorre el grid obener la matriz de cov
234
                        for (int i = 0; i < bandCount; i++) {
235
                                for (int j = i; j < bandCount; j++) {
236
                                        if(cancel)
237
                                                return cancelMatrix;
238
                                        iValues=0;
239
                                        dSum = 0;
240
                                        // Calculo covarianza entre las bandas i,j
241
                                        for (int k=0; k<inputGrid.getNX(); k++){
242
                                                for (int l=0;l<inputGrid.getNY();l++){
243
                                                                try{
244
                                                                        inputGrid.setBandToOperate(i);
245
                                                                        valorBandai=inputGrid.getCellValueAsInt(k,l) -inputGrid.getMeanValue();
246
                                                                        inputGrid.setBandToOperate(j);
247
                                                                        valorBandaj=inputGrid.getCellValueAsInt(k,l) -inputGrid.getMeanValue();
248
                                                                } catch (RasterBufferInvalidAccessException e) {e.printStackTrace();}
249
                                                                dSum += valorBandai*valorBandaj;
250
                                                                iValues++;
251
                                                }
252
                                        }
253
                                        // Se asigna el valor a la matriz 
254
                                        if (iValues>1)
255
                                                coV[i][j]=dSum/(double)(iValues);        
256
                                        else
257
                                                coV[i][j]= inputGrid.getNoDataValue();
258
                                }
259
                
260
                        if (bandCount>1)
261
                                percent = (i+1)*100/(bandCount-1);
262
                        else
263
                                percent= (i+1)*100/(1);
264
                        }
265

    
266
                } // Fin tipo Int
267
                
268
                
269
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_FLOAT){
270
                        // Se recorre el grid obener la matriz de cov
271
                        for (int i = 0; i < bandCount; i++) {
272
                                for (int j = i; j < bandCount; j++) {
273
                                        if(cancel)
274
                                                return  cancelMatrix;
275
                                        iValues=0;
276
                                        dSum = 0;
277
                                        // Calculo la covarianza entre las bandas i,j
278
                                        for (int k=0; k<inputGrid.getNX(); k++){
279
                                                for (int l=0;l<inputGrid.getNY();l++){                                                
280
                                                                try{
281
                                                                        inputGrid.setBandToOperate(i);
282
                                                                        valorBandai=inputGrid.getCellValueAsFloat(k,l) -inputGrid.getMeanValue();
283
                                                                        inputGrid.setBandToOperate(j);
284
                                                                        valorBandaj=inputGrid.getCellValueAsFloat(k,l) -inputGrid.getMeanValue();
285
                                                                } catch (RasterBufferInvalidAccessException e) {e.printStackTrace();}
286
                                                                dSum += valorBandai*valorBandaj;
287
                                                                iValues++;
288
                                                }
289
                                        }
290
                                        // Se asigna el valor a la matriz 
291
                                        if (iValues>1)
292
                                                coV[i][j]=dSum/(double)(iValues);        
293
                                        else
294
                                                coV[i][j]= inputGrid.getNoDataValue();
295
                                }
296
                
297
                        if (bandCount>1)
298
                                percent = (i+1)*100/(bandCount-1);
299
                        else
300
                                percent= (i+1)*100/(1);
301
                        }
302

    
303
                } // Fin tipo Float
304
                
305
        
306
                if(inputGrid.getRasterBuf().getDataType() == RasterBuffer.TYPE_DOUBLE){
307
                        // Se recorre el grid obener la matriz de cov
308
                        for (int i = 0; i < bandCount; i++) {
309
                                for (int j = i; j < bandCount; j++) {
310
                                        if(cancel)
311
                                                return cancelMatrix;
312
                                        iValues=0;
313
                                        dSum = 0;
314
                                        // Calculo la covarianza entre las bandas i,j
315
                                        for (int k=0; k<inputGrid.getNX(); k++){
316
                                                for (int l=0;l<inputGrid.getNY();l++){
317
                                                                try{
318
                                                                        inputGrid.setBandToOperate(i);
319
                                                                        valorBandai=inputGrid.getCellValueAsDouble(k,l) -inputGrid.getMeanValue();
320
                                                                        inputGrid.setBandToOperate(j);
321
                                                                        valorBandaj=inputGrid.getCellValueAsDouble(k,l) -inputGrid.getMeanValue();
322
                                                                } catch (RasterBufferInvalidAccessException e) {e.printStackTrace();}
323
                                                                dSum += valorBandai*valorBandaj;
324
                                                                iValues++;
325
                                                }
326
                                        }
327
                                        // Asigno el valor a la matriz 
328
                                        if (iValues>1)
329
                                                coV[i][j]=dSum/(double)(iValues);        
330
                                        else
331
                                                coV[i][j]= inputGrid.getNoDataValue();
332
                                }
333
                
334
                        if (bandCount>1)
335
                                percent = (i+1)*100/(bandCount-1);
336
                        else
337
                                percent= (i+1)*100/(1);
338
                        }
339

    
340
                } // Fin tipo Double
341

    
342
                for (int i = 0; i < bandCount; i++) {
343
                        for (int j = 0; j < bandCount; j++) {
344
                                if(j<i)
345
                                        coV[i][j]=coV[j][i];
346
                        }
347
                }
348
        
349
                return coV;
350
        }
351
        
352
        
353
        /**
354
         * Lanza el proceso.
355
         *
356
         */
357
        public void start() {
358
                cancel = false;
359
                blinker = new Thread(this);
360
                blinker.start();
361
        }
362
        
363
        
364
        /**
365
         * Proceso.
366
         */
367
        public void run() {
368
                
369
                RasterTaskQueue.register(rasterTask); //Registro de la tarea
370
                
371
                try{
372
                        // Se establece el grid con las bandas seleccionadas
373
                        setGrid();
374
                        //        Calculo de matriz de covarianza:
375
                        double coVar[][]= covarianceOptimize();
376
                        
377
                         // Calculo de autovectores:
378
                        coVarMatrix = new Matrix(coVar);
379
                        EigenvalueDecomposition eigenvalueDecomp = new EigenvalueDecomposition(coVarMatrix); 
380
                        //Autovectores
381
                        autoVectorMatrix= eigenvalueDecomp.getV();
382
            
383
                        // Autovalores
384
                        autovalors= eigenvalueDecomp.getRealEigenvalues();        
385

    
386
                        }finally{
387
                                
388
                                if (incrementableTask!=null){
389
                                        incrementableTask.processFinalize();
390
                                }
391
                                
392
                                if(!cancel){
393
                                        PrincipalComponentCalculusPanel altPrincipalComponentCalculusPanel = new PrincipalComponentCalculusPanel(view,this);
394
                                        PluginServices.getMDIManager().addWindow(altPrincipalComponentCalculusPanel);
395
                                }
396
                                RasterTaskQueue.remove(rasterTask);
397
                        }
398
        }
399

    
400
        
401
        /**
402
         * Construye el grid con las bandas seleccionadas
403
         */
404
        public void setGrid(){
405
        
406
                BufferFactory dataSource = new BufferFactory(raster);        
407
                int longitud=0;
408
                for (int i=0; i<selectedBands.length;i++)
409
                                if (selectedBands[i]) longitud++;
410
                        
411
                int bands[]= new int[longitud];
412
                int j=0;
413
                for (int i=0; i<selectedBands.length; i++)
414
                        if (selectedBands[i])
415
                                { bands[j]=i;
416
                                     j++;
417
                                }
418
                try {
419
                                inputGrid = new Grid(dataSource, bands);        
420
                } catch (RasterBufferInvalidException e) {
421
                                        e.printStackTrace();                        
422
                }
423
        }
424
        
425
        
426
        /*
427
         * (non-Javadoc)
428
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getLabel()
429
         */
430
        public String getLabel() {
431
                return  PluginServices.getText(this,"procesando");
432
        }
433

    
434
        /*
435
         * (non-Javadoc)
436
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getLog()
437
         */
438
        public String getLog() {
439
                return PluginServices.getText(this,"calculando_estadisticas")+"...";
440
        }
441

    
442
        
443
        /*
444
         * (non-Javadoc)
445
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
446
         */
447
        public int getPercent() {
448
                return percent;
449
        }
450

    
451
        /*
452
         * (non-Javadoc)
453
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
454
         */
455
        public String getTitle() {
456
                return PluginServices.getText(this,"principal_components");
457
        }
458

    
459
        /*
460
         * (non-Javadoc)
461
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#actionCanceled
462
         */
463
        public void actionCanceled(IncrementableEvent e) {
464
                cancel=true;
465
                rasterTask.setEvent(new CancelEvent(this));        
466
        }
467

    
468
        /*
469
         * (non-Javadoc)
470
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#actionResumed
471
         */
472
        public void actionResumed(IncrementableEvent e) {
473
        }
474

    
475
        /*
476
         * (non-Javadoc)
477
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#actionSuspended
478
         */
479
        public void actionSuspended(IncrementableEvent e) {
480
        }
481
        
482
        
483
        /*
484
         * (non-Javadoc)
485
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#setIncrementableTask
486
         */
487
        public void setIncrementableTask(IncrementableTask incrementableTask) {
488
                this.incrementableTask = incrementableTask;
489
                this.incrementableTask.addIncrementableListener(this);
490
        }
491

    
492

    
493
        /**
494
         * @return grid 
495
         */
496
        public Grid getInputGrid() {
497
                return inputGrid;
498
        }
499
        
500
        
501
        /**
502
         * @return r?ster de entrada
503
         */
504
        public IRasterDataSource getRaster(){
505
                return raster;        
506
        }
507
        
508
        /**
509
         * @return vista de la aplicacion
510
         */
511
        public View getView(){
512
                return view;        
513
        }
514
}