Statistics
| Revision:

gvsig-raster / org.gvsig.raster.principalcomponents / trunk / org.gvsig.raster.principalcomponents / org.gvsig.raster.principalcomponents.algorithm / src / main / java / org / gvsig / raster / principalcomponents / algorithm / PCAStatisticsProcess.java @ 2474

History | View | Annotate | Download (10.8 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.principalcomponents.algorithm;
23

    
24

    
25
import java.awt.geom.Rectangle2D;
26
import java.util.List;
27

    
28
import org.cresques.Messages;
29
import org.gvsig.fmap.dal.coverage.RasterLocator;
30
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
31
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
32
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
33
import org.gvsig.fmap.dal.coverage.exception.CloneException;
34
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
35
import org.gvsig.fmap.dal.coverage.exception.ROIException;
36
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
37
import org.gvsig.fmap.dal.exception.CloseException;
38
import org.gvsig.raster.algorithm.process.DataProcess;
39
import org.gvsig.raster.algorithm.process.ProcessException;
40
import org.gvsig.raster.roi.ROI;
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43

    
44
import Jama.EigenvalueDecomposition;
45
import Jama.Matrix;
46

    
47
/**
48
 * This Process computes a <code>PCStatsDataStructure</code> Object from bands of two images in a study zone.
49
 * <code>PCStatsDataStructure</code> is a object that contains the needed statistics to Principal Components decomposition
50
 * of images.
51
 * 
52
 * @author Nacho Brodin (nachobrodin@gmail.com)
53
 * 
54
 */
55
public class PCAStatisticsProcess extends DataProcess {
56
    public static final String          LAYER_ZONA_ESTUDIO                         = "LAYER_ZONA_ESTUDIO";
57
    public static String         BANDS                                                         = "BANDS";
58
    public static String         PATH                                                         = "PATH";
59
    public static String         ROI_EPSG                       = "ROI_EPSG";
60
    public static String         WINDOW                         = "WINDOW";
61
    
62
        public static String         RASTER_STORE                   = "RASTER_STORE";
63
        public static String         STATS_RESULT                   = "STATS_RESULT";
64
        
65
    private boolean[]                          bands                                                         = null;
66
    private RasterDataStore      store                                                         = null;
67
    private Buffer               buffer                                                 = null;
68
    private Buffer               roiBuffer                                                 = null;
69
    private boolean              roiBufferCalculated            = false;
70
        private double                                 autovalors[]                                        = null;
71
        private Matrix                                  coVarMatrix                                        = null;
72
        private Matrix                                  autoVectorMatrix                                = null;
73
        private double                                  coVar[][]                                                 = null;
74
        private static Logger                  logger                                                       = LoggerFactory.getLogger(PCAStatisticsProcess.class.getName());
75
    private double[][]                          maxminmean                                                = null;
76
    private        Extent                                  extentResult                                        = null; 
77
    private String               path                           = null;
78
    private List<ROI>            rois                           = null;
79
    
80
    private boolean[]            statsByBandCalculated          = null;
81
         
82
        public static void registerParameters() {
83
                registerInputParameter(RASTER_STORE, RasterDataStore.class, PrincipalComponentsAlgorithmLibrary.PC_STATS_PROCESS_LABEL);
84
                registerInputParameter(BANDS, Boolean[].class, PrincipalComponentsAlgorithmLibrary.PC_STATS_PROCESS_LABEL);
85
                registerInputParameter(PATH, String.class, PrincipalComponentsAlgorithmLibrary.PC_STATS_PROCESS_LABEL);
86
                
87
                registerOutputParameter(STATS_RESULT, PCStatsDataStructure.class, PrincipalComponentsAlgorithmLibrary.PC_STATS_PROCESS_LABEL);
88
                registerOutputParameter(PATH, String.class, PrincipalComponentsAlgorithmLibrary.PC_STATS_PROCESS_LABEL);
89
                registerOutputParameter(BANDS, Boolean[].class, PrincipalComponentsAlgorithmLibrary.PC_STATS_PROCESS_LABEL);
90
                registerOutputParameter(ROI_EPSG, String.class, PrincipalComponentsAlgorithmLibrary.PC_STATS_PROCESS_LABEL);
91
        }
92
        
93
        @Override
94
        public void init() {
95
                store = (RasterDataStore)getParam(RASTER_STORE);
96
                bands = (boolean[])getParam(BANDS);
97
                path = getStringParam(PATH);
98
        }
99
        
100
        public double[] getAutoValors() {
101
                return  autovalors;
102
        }
103
        
104
        /**
105
         * @return Autovectors Matrix
106
         */
107
        public Matrix getAutoVectorMatrix() {
108
                return autoVectorMatrix;
109
        }
110
        
111
        /**
112
         * @return Varianze-covarianze Matrix
113
         */
114
        public Matrix getcoVarMatrix() {
115
                return coVarMatrix;
116
        }
117
        
118
        public boolean isInsideOfROI(int x, int y, List<ROI> rois, Extent extentResult) {
119
                if(roiBufferCalculated)
120
                        return (roiBuffer.getElemByte(y, x, 0) == 1);
121
                if(roiBuffer == null)
122
                        roiBuffer = createOutputBuffer(buffer.getWidth(), buffer.getHeight(), 1, Buffer.TYPE_BYTE);
123
                boolean a = super.isInsideOfROI(x, y, rois, extentResult);
124
                roiBuffer.setElem(y, x, 0, a ? (byte)1: (byte)0);
125
                return a;
126
        }
127
        
128
        /**
129
         * Calculate the Varianze-covarianze Matrix from bands of a Grid
130
         * @throws InterruptedException 
131
         * @throws ProcessInterruptedException 
132
         */
133
        private double[][] covarianceOptimize() throws InterruptedException, ProcessInterruptedException {
134
        //NoData
135
        NoData nd = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, Buffer.TYPE_DOUBLE);
136
        
137
        double nodata = nd.getValue().doubleValue();
138
                double dSum = 0;
139
                int iValues = 0;
140
                double[][] coV = new double[buffer.getBandCount()][buffer.getBandCount()];
141
                
142
                double valorBandai = 0, valorBandaj = 0;
143
                maxminmean = new double[buffer.getBandCount()][4];
144
                statsByBandCalculated = new boolean[buffer.getBandCount()];
145
                for (int i = 0; i < statsByBandCalculated.length; i++) {
146
                        statsByBandCalculated[i] = false;
147
                }
148
                
149
                loadDataStoreStatistics();
150
                
151
                int percent = 0;
152
                int maxCounter = 0;
153
                for (int i = buffer.getBandCount(); i >= 0; i--) {
154
                        maxCounter += i;
155
                }
156
                
157
                for (int i = 0; i < buffer.getBandCount(); i++) {
158
                        double meanBufferToOperatei = getMeanValue(i, buffer);
159
                        for (int j = i; j < buffer.getBandCount(); j++) {
160
                                iValues = 0;
161
                                dSum = 0;
162
                                double meanBufferToOperatej = getMeanValue(j, buffer);
163

    
164
                                for (int row = 0; row < buffer.getHeight(); row++) {
165
                                        for (int col = 0; col < buffer.getWidth(); col++) {
166
                                                if(isInsideOfROI(col, row, rois, extentResult)) {
167
                                                        valorBandai = getData(buffer, row, col, i) - meanBufferToOperatei;
168
                                                        valorBandaj = getData(buffer, row, col, j) - meanBufferToOperatej;
169

    
170
                                                        dSum += valorBandai * valorBandaj;
171
                                                        iValues++;
172
                                                }
173
                                        }
174
                                        updatePercent(percent, maxCounter);
175
                                }
176
                                roiBufferCalculated = true;
177
                                
178
                                // Asigno el valor a la matriz 
179
                                if (iValues > 1)
180
                                        coV[i][j] = dSum / (double)(iValues);        
181
                                else
182
                                        coV[i][j] = nodata;
183
                                
184
                                percent ++;
185
                                updatePercent(percent, maxCounter);
186
                        }
187

    
188
                }
189
                
190
                for (int i = 0; i < buffer.getBandCount(); i++) {
191
                        for (int j = 0; j < buffer.getBandCount(); j++) {
192
                                if(j < i)
193
                                        coV[i][j] = coV[j][i];
194
                        }
195
                }
196

    
197
                return coV;
198
        }
199
        
200
//         * Devuelve la media de los valores de los pixeles de un buffer incluidos en la zona de estudio
201
        /**
202
         * Get the mean of values of pixels from a buffer in a study zone
203
         * @param bufferToOperate
204
         * @return
205
         */
206
        private double getMeanValue(int band, Buffer bufferToOperate) {
207
                if(statsByBandCalculated[band])
208
                        return maxminmean[band][2];
209
                
210
                double mean = 0;
211
                double variance = 0;
212
                double min = Double.MAX_VALUE;
213
                double max = Double.MIN_VALUE;
214
                int valuesCounter = 0;
215
                for (int j = 0; j < bufferToOperate.getHeight(); j++) {
216
                        for (int i = 0; i < bufferToOperate.getWidth(); i++) {
217
                                if (isInsideOfROI(i, j, rois, extentResult)) {
218
                                        double value = getData(bufferToOperate, j, i, band);
219
                                        
220
                                        if(value < min) {
221
                                                min = value;
222
                                        }
223

    
224
                                        if(value > max) {
225
                                                max = value;
226
                                        }
227
                                        
228
                                        mean += value;
229
                                        variance += value * value;
230
                                        valuesCounter++;
231
                                }
232
                        }
233

    
234
                }
235
                roiBufferCalculated = true;
236
                mean = (mean / valuesCounter);
237
                variance = variance / (double) valuesCounter - mean * mean;
238
                maxminmean[band][0] = max;
239
                maxminmean[band][1] = min;
240
                maxminmean[band][2] = mean;
241
                maxminmean[band][3] = variance;
242
                statsByBandCalculated[band] = true;
243
                return mean;
244
        }
245
        
246
        private void loadDataStoreStatistics() {
247
                if(isAnalizedEntireLayer(getOutputWindow(), rois, store) && store.getStatistics().isCalculated()) {
248
                        double[] max = store.getStatistics().getMax();
249
                        double[] min = store.getStatistics().getMin();
250
                        double[] mean = store.getStatistics().getMean();
251
                        double[] variance = store.getStatistics().getVariance();
252
                        int iBand = 0;
253
                        for (int i = 0; i < mean.length; i++) {
254
                                if(bands[i]) {
255
                                        maxminmean[iBand][0] = max[i];
256
                                        maxminmean[iBand][1] = min[i];
257
                                        maxminmean[iBand][2] = mean[i];
258
                                        maxminmean[iBand][3] = variance[i];
259
                                        statsByBandCalculated[iBand] = true;
260
                                        iBand ++;
261
                                }
262
                        }
263
                }
264
        }
265

    
266
        @Override
267
        public void process() throws ProcessInterruptedException, ProcessException {
268
                insertLineLog(Messages.getText("preparing_buffers"));
269

    
270
                if(getROIEPSG() != null) {
271
                        try {
272
                                rois = store.getRois(getROIEPSG());
273
                        } catch (ROIException e2) {
274
                                logger.error(Messages.getText("error_getting_rois"), e2);
275
                        }
276
                }
277
                        
278
                try {
279
                        store = store.cloneDataStore();
280
                } catch (CloneException e1) {
281
                        throw new ProcessException("Error cloning the sources", e1);
282
                }
283
                        
284
                //Calculo de datos de entrada
285
                extentResult = getExtentResult(getOutputWindow(), rois, store);
286
                Rectangle2D sourcePxBBox = getSourcePxBox(extentResult, store);
287

    
288
                buffer = createSourceBuffer(store, sourcePxBBox, bands);
289

    
290
                insertLineLog(Messages.getText("calc_stats"));
291

    
292
                try {
293
                        coVar = covarianceOptimize();
294
                } catch (InterruptedException e) {
295
                        logger.error(Messages.getText("error_covarianza_optimize"), e);
296
                }
297
                // Calculo de autovectores:
298
                coVarMatrix = new Matrix(coVar);
299
                EigenvalueDecomposition eigenvalueDecomp = new EigenvalueDecomposition(coVarMatrix); 
300
                //Autovectores
301
                autoVectorMatrix = eigenvalueDecomp.getV();
302

    
303
                // Autovalores
304
                autovalors = eigenvalueDecomp.getRealEigenvalues();        
305

    
306
                PCStatsDataStructure resultStatistics = new PCStatsDataStructure(autoVectorMatrix, autovalors, coVarMatrix);
307
                resultStatistics.setMaxMinMean(maxminmean);
308
                
309
                roiBuffer.dispose();
310
                //Object[] dataROI = new Object[]{vectROI, (int)shift[0].getX(), (int)shift[0].getY()};        
311
                addOutputValue(STATS_RESULT, resultStatistics);
312
                addOutputValue(PATH, path);
313
                addOutputValue(BANDS, bands);
314
                addOutputValue(ROI_EPSG, getROIEPSG());
315
                try {
316
                        store.close();
317
                } catch (CloseException e) {
318
                        throw new ProcessException("Error closing the sources", e);
319
                }
320
        }
321
 
322

    
323
        public String getTitle() {
324
                return null;
325
        }
326
}