Statistics
| Revision:

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
}