Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / classification / ClassificationMinimumDistanceProcess.java @ 16598

History | View | Annotate | Download (11.3 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
         *
3
         * Copyright (C) 2006 Instituto de Desarrollo Regional and Generalitat Valenciana.
4
         *
5
         * This program is free software; you can redistribute it and/or
6
         * modify it under the terms of the GNU General Public License
7
         * as published by the Free Software Foundation; either version 2
8
         * of the License, or (at your option) any later version.
9
         *
10
         * This program is distributed in the hope that it will be useful,
11
         * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
         * GNU General Public License for more details.
14
         *
15
         * You should have received a copy of the GNU General Public License
16
         * along with this program; if not, write to the Free Software
17
         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
         *
19
         * For more information, contact:
20
         *
21
         *  Generalitat Valenciana
22
         *   Conselleria d'Infraestructures i Transport
23
         *   Av. Blasco Iba?ez, 50
24
         *   46010 VALENCIA
25
         *   SPAIN
26
         *
27
         *      +34 963862235
28
         *   gvsig@gva.es
29
         *      www.gvsig.gva.es
30
         *
31
         *    or
32
         *
33
         *   Instituto de Desarrollo Regional (Universidad de Castilla La-Mancha)
34
         *   Campus Universitario s/n
35
         *   02071 Alabacete
36
         *   Spain
37
         *
38
         *   +34 967 599 200
39
         */
40

    
41
package org.gvsig.remotesensing.classification;
42

    
43
import java.util.ArrayList;
44
import org.gvsig.raster.buffer.RasterBuffer;
45
import org.gvsig.raster.dataset.IBuffer;
46
import org.gvsig.raster.dataset.IRasterDataSource;
47
import org.gvsig.raster.grid.GridException;
48
import org.gvsig.raster.grid.roi.ROI;
49
import org.gvsig.raster.process.RasterTaskQueue;
50
import org.gvsig.raster.util.RasterToolsUtil;
51

    
52
import com.iver.andami.PluginServices;
53
import com.iver.cit.gvsig.project.documents.view.gui.View;
54

    
55
/** ClassificationMinimumDistanceProcess implementa el m?todo de clasificaci?n de 
56
 * m?nima distancia.
57
 * 
58
 * @see ClassificationGeneralProcess
59
 * @author Alejandro Mu?oz Sanchez (alejandro.munoz@uclm.es)
60
 * @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
61
 * @version 19/10/2007 
62
 */
63
public class ClassificationMinimumDistanceProcess extends ClassificationGeneralProcess {
64
        
65
        private double                 means[][]         = null;
66
        private int                 bandCount         = 0;
67
        
68
        /** 
69
        * Class constructor.
70
        * @param raster                         raster a clasificar 
71
        * @param rois                           lista de rois
72
        * @param bandList                         bandas habilitadas 
73
        * @param view                                 vista
74
        * @param fileNameOutput         path de fichero de salida
75
        */
76
        public  ClassificationMinimumDistanceProcess(IRasterDataSource raster, ArrayList rois, int bandList[], View view, String fileNameOutput){
77
                this.raster= raster;
78
                this.rois = rois;
79
                this.view=view;
80
                this.fileNameOutput= fileNameOutput;
81
                this.bandList = bandList;
82
                numClases = rois.size();
83
        }
84
        
85
        /**
86
         * Lanzar el Thread del proceso de clasificaci?n por el m?todo de m?nima distancia.
87
         */
88
        public void start() {
89
                blinker = new Thread(this);
90
                blinker.start();
91
        }
92
        
93
        
94
        /*
95
         * (non-Javadoc)
96
         * @see java.lang.Runnable#run()
97
         */
98
        public void run() {
99
                RasterTaskQueue.register(rasterTask);
100
                setGrid();
101
                rasterResult= RasterBuffer.getBuffer(IBuffer.TYPE_DOUBLE, inputGrid.getRasterBuf().getWidth(), inputGrid.getRasterBuf().getHeight(), 1, true);
102
                int c=0;
103
                int iNY= inputGrid.getLayerNY();
104
                int iNX= inputGrid.getLayerNX();        
105
                
106
                bandCount  = inputGrid.getBandCount();
107
                
108
                
109
                try{        
110
                
111
                        means = new double[numClases][bandCount];
112
                        for (int clase=0; clase<numClases; clase++)
113
                                for (int i=0;i<bandCount;i++){
114
                                        ((ROI)rois.get(clase)).setBandToOperate(bandList[i]);
115
                                                means[clase][i]=((ROI)rois.get(clase)).getMeanValue();
116
                }
117
                
118
                                
119
                
120
                        int inputGridNX = inputGrid.getNX();
121
                        int datType = inputGrid.getRasterBuf().getDataType();
122
                        
123
//                        Caso Buffer tipo Byte
124
                        if (datType == RasterBuffer.TYPE_BYTE){
125
                                byte data[]= new byte[bandCount];
126
                                for(int i=0; i<iNY;i++){
127
                                        for(int j=0; j<iNX;j++){
128
                                                inputGrid.getRasterBuf().getElemByte(i, j, data);
129
                                                c= getPixelClassForTypeByte(data);
130
                                                rasterResult.setElem(i, j, 0,(double) c);
131
                                        }
132
                                        percent = i*100/inputGridNX;
133
                                }
134
                        }
135
                
136
//                        Caso Buffer tipo Short
137
                        else if (datType == RasterBuffer.TYPE_SHORT){
138
                                short data[]= new short[bandCount];
139
                                for(int i=0; i<iNY;i++){
140
                                        for(int j=0; j<iNX;j++){
141
                                                inputGrid.getRasterBuf().getElemShort(i, j, data);
142
                                                c= getPixelClassForTypeShort(data);
143
                                                rasterResult.setElem(i, j, 0,(double)c);
144
                                        }
145
                                        percent = i*100/inputGridNX;
146
                                }
147
                        }
148
                        
149
//                        Caso Buffer tipo Int
150
                        else if (datType == RasterBuffer.TYPE_INT){
151
                                int data[]= new int[bandCount];
152
                                for(int i=0; i<iNY;i++){
153
                                        for(int j=0; j<iNX;j++){
154
                                                inputGrid.getRasterBuf().getElemInt(i, j, data);
155
                                                c= getPixelClassForTypeInt(data);
156
                                                rasterResult.setElem(i, j, 0,(double) c);
157
                                        }
158
                                        percent = i*100/inputGridNX;
159
                                }
160
                        }
161
                
162
                
163
//                        Caso Buffer tipo Float
164
                        else if (datType == RasterBuffer.TYPE_FLOAT){
165
                                float data[]= new float[bandCount];
166
                                for(int i=0; i<iNY;i++){
167
                                        for(int j=0; j<iNX;j++){
168
                                                inputGrid.getRasterBuf().getElemFloat(i, j, data);
169
                                                c= getPixelClassForTypeFloat(data);
170
                                                rasterResult.setElem(i, j, 0,(double) c);
171
                                        }
172
                                        percent = i*100/inputGridNX;
173
                                }
174
                        }
175
                                
176
                        
177
//                        Caso Buffer tipo Float
178
                        else if (datType == RasterBuffer.TYPE_DOUBLE){
179
                                double data[]= new double[bandCount];
180
                                for(int i=0; i<iNY;i++){
181
                                        for(int j=0; j<iNX;j++){
182
                                                inputGrid.getRasterBuf().getElemDouble(i, j, data);
183
                                                c= getPixelClassForTypeDouble(data);
184
                                                rasterResult.setElem(i, j, 0,(double) c);
185
                                        }
186
                                        percent = i*100/inputGridNX;
187
                                }
188
                        }
189
                        
190
                        writeToFile();
191
                        
192
                        
193
                }catch (GridException e) {
194
                        RasterToolsUtil.messageBoxError(PluginServices.getText(this, "grid_error"), this, e);
195
                }finally {
196
                                RasterTaskQueue.remove(rasterTask);
197
                }                
198
        }
199

    
200
        
201
        /**
202
        * M?todo que implementa el clasificador de m?nima distancia. 
203
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
204
        * vector de medias es m?nima
205
        * 
206
        * @param  array de tipo byte con los valores del pixel en cada una de las bandas 
207
        * @return clase a la que pertenece el pixel
208
    */
209
        public int getPixelClassForTypeByte(byte[] pixelBandsValues) {
210
                int clasefinal=0; double distanciaFinal=0.0;
211
                for (int clase=0; clase<numClases; clase++)
212
                {
213
                        double[] y = new double[bandCount];
214
                        double distancia=0;
215
                        for (int i=0;i<bandCount;i++){
216
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
217
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
218
                                distancia+=y[i];
219
                        }
220
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
221
                        if (clase==0)
222
                                distanciaFinal=distancia;
223
                        
224
                        else if (distancia<distanciaFinal){
225
                                distanciaFinal = distancia;
226
                                clasefinal = clase;
227
                                }
228
                }        
229
                return clasefinal;
230
        }
231
        
232
        
233
        /**
234
        * M?todo que implementa el clasificador de m?nima distancia. 
235
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
236
        * vector de medias es m?nima
237
        * 
238
        * @param  array de tipo short con los valores del pixel en cada una de las bandas 
239
        * @return clase a la que pertenece el pixel
240
    */
241
        public int getPixelClassForTypeShort(short[] pixelBandsValues) {
242
                int clasefinal=0; double distanciaFinal=0.0;
243
                for (int clase=0; clase<numClases; clase++)
244
                {
245
                        double[] y = new double[bandCount];
246
                        double distancia=0;
247
                        for (int i=0;i<bandCount;i++){
248
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
249
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
250
                                distancia+=y[i];
251
                        }
252
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
253
                        if (clase==0)
254
                                distanciaFinal=distancia;        
255
                        else if (distancia<distanciaFinal){
256
                                distanciaFinal= distancia;
257
                                clasefinal=clase;
258
                                }
259
                }        
260
                return clasefinal;
261
        }
262
        
263
        
264
        /**
265
        * M?todo que implementa el clasificador de m?nima distancia. 
266
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
267
        * vector de medias es m?nima
268
        * 
269
        * @param  array de tipo int con los valores del pixel en cada una de las bandas 
270
        * @return clase a la que pertenece el pixel
271
    */
272
        public int getPixelClassForTypeInt(int[] pixelBandsValues) {
273
                
274
                int clasefinal=0; double distanciaFinal=0.0;
275
                for (int clase=0; clase<numClases; clase++)
276
                {
277
                        double[] y = new double[bandCount];
278
                        double distancia=0;
279
                        for (int i=0;i<bandCount;i++){
280
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
281
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
282
                                distancia+=y[i];
283
                        }
284
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
285
                        if (clase==0)
286
                                distanciaFinal=distancia;
287
                        else if (distancia<distanciaFinal){
288
                                distanciaFinal= distancia;
289
                                clasefinal=clase;
290
                                }
291
                }        
292
                return clasefinal;
293
        }
294
        
295
        
296
        /**
297
        * M?todo que implementa el clasificador de m?nima distancia. 
298
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
299
        * vector de medias es m?nima
300
        * 
301
        * @param  array de tipo float con los valores del pixel en cada una de las bandas 
302
        * @return clase a la que pertenece el pixel
303
    */
304
        public int getPixelClassForTypeFloat(float[] pixelBandsValues) {
305
                int clasefinal=0; double distanciaFinal=0.0;
306
                for (int clase=0; clase<numClases; clase++)
307
                {
308
                        double[] y = new double[bandCount];
309
                        double distancia=0;
310
                        for (int i=0;i<bandCount;i++){
311
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
312
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
313
                                distancia+=y[i];
314
                        }
315
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
316
                        if (clase==0)
317
                                distanciaFinal=distancia;
318
                        else if (distancia<distanciaFinal){
319
                                distanciaFinal= distancia;
320
                                clasefinal=clase;
321
                                }
322
                }        
323
                return clasefinal;
324
        }
325
        
326
        
327
        /**
328
        * M?todo que implementa el clasificador de m?nima distancia. 
329
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
330
        * vector de medias es m?nima
331
        * 
332
        * @param  array de tipo double con los valores del pixel en cada una de las bandas 
333
        * @return clase a la que pertenece el pixel
334
    */
335
        public int getPixelClassForTypeDouble(double[] pixelBandsValues) {
336
                int clasefinal=0; double distanciaFinal=0.0;
337
                for (int clase=0; clase<numClases; clase++)
338
                {
339
                        double[] y = new double[bandCount];
340
                        double distancia=0;
341
                        for (int i=0;i<bandCount;i++){
342
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
343
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
344
                                distancia+=y[i];
345
                        }
346
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
347
                        if (clase==0)
348
                                distanciaFinal=distancia;
349
                        else if (distancia<distanciaFinal){
350
                                distanciaFinal= distancia;
351
                                clasefinal=clase;
352
                                }
353
                }        
354
                return clasefinal;
355
        }
356
}