Statistics
| Revision:

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

History | View | Annotate | Download (10.8 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

    
45
import org.gvsig.raster.buffer.RasterBuffer;
46
import org.gvsig.raster.dataset.IBuffer;
47
import org.gvsig.raster.grid.GridException;
48
import org.gvsig.raster.grid.roi.ROI;
49

    
50
import com.iver.cit.gvsig.project.documents.view.gui.View;
51

    
52
/** ClassificationMinimumDistanceProcess implementa el m?todo de clasificaci?n de 
53
 * m?nima distancia.
54
 * 
55
 * @see ClassificationGeneralProcess
56
 * @author Alejandro Mu?oz Sanchez (alejandro.munoz@uclm.es)
57
 * @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
58
 * @version 19/10/2007 
59
 */
60
public class ClassificationMinimumDistanceProcess extends ClassificationGeneralProcess {
61
        
62
        private double                 means[][]         = null;
63
        private int                 bandCount         = 0;
64
        
65
        /**
66
         * Constructor
67
         * */
68
        public  ClassificationMinimumDistanceProcess(){
69
        }
70
                
71
        
72
        /**
73
        * M?todo que implementa el clasificador de m?nima distancia. 
74
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
75
        * vector de medias es m?nima
76
        * 
77
        * @param  array de tipo byte con los valores del pixel en cada una de las bandas 
78
        * @return clase a la que pertenece el pixel
79
    */
80
        public int getPixelClassForTypeByte(byte[] pixelBandsValues) {
81
                int clasefinal=0; double distanciaFinal=0.0;
82
                for (int clase=0; clase<numClases; clase++)
83
                {
84
                        double[] y = new double[bandCount];
85
                        double distancia=0;
86
                        for (int i=0;i<bandCount;i++){
87
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
88
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
89
                                distancia+=y[i];
90
                        }
91
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
92
                        if (clase==0)
93
                                distanciaFinal=distancia;
94
                        
95
                        else if (distancia<distanciaFinal){
96
                                distanciaFinal = distancia;
97
                                clasefinal = clase;
98
                                }
99
                }        
100
                return clasefinal;
101
        }
102
        
103
        
104
        /**
105
        * M?todo que implementa el clasificador de m?nima distancia. 
106
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
107
        * vector de medias es m?nima
108
        * 
109
        * @param  array de tipo short con los valores del pixel en cada una de las bandas 
110
        * @return clase a la que pertenece el pixel
111
    */
112
        public int getPixelClassForTypeShort(short[] pixelBandsValues) {
113
                int clasefinal=0; double distanciaFinal=0.0;
114
                for (int clase=0; clase<numClases; clase++)
115
                {
116
                        double[] y = new double[bandCount];
117
                        double distancia=0;
118
                        for (int i=0;i<bandCount;i++){
119
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
120
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
121
                                distancia+=y[i];
122
                        }
123
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
124
                        if (clase==0)
125
                                distanciaFinal=distancia;        
126
                        else if (distancia<distanciaFinal){
127
                                distanciaFinal= distancia;
128
                                clasefinal=clase;
129
                                }
130
                }        
131
                return clasefinal;
132
        }
133
        
134
        
135
        /**
136
        * M?todo que implementa el clasificador de m?nima distancia. 
137
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
138
        * vector de medias es m?nima
139
        * 
140
        * @param  array de tipo int con los valores del pixel en cada una de las bandas 
141
        * @return clase a la que pertenece el pixel
142
    */
143
        public int getPixelClassForTypeInt(int[] pixelBandsValues) {
144
                
145
                int clasefinal=0; double distanciaFinal=0.0;
146
                for (int clase=0; clase<numClases; clase++)
147
                {
148
                        double[] y = new double[bandCount];
149
                        double distancia=0;
150
                        for (int i=0;i<bandCount;i++){
151
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
152
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
153
                                distancia+=y[i];
154
                        }
155
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
156
                        if (clase==0)
157
                                distanciaFinal=distancia;
158
                        else if (distancia<distanciaFinal){
159
                                distanciaFinal= distancia;
160
                                clasefinal=clase;
161
                                }
162
                }        
163
                return clasefinal;
164
        }
165
        
166
        
167
        /**
168
        * M?todo que implementa el clasificador de m?nima distancia. 
169
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
170
        * vector de medias es m?nima
171
        * 
172
        * @param  array de tipo float con los valores del pixel en cada una de las bandas 
173
        * @return clase a la que pertenece el pixel
174
    */
175
        public int getPixelClassForTypeFloat(float[] pixelBandsValues) {
176
                int clasefinal=0; double distanciaFinal=0.0;
177
                for (int clase=0; clase<numClases; clase++)
178
                {
179
                        double[] y = new double[bandCount];
180
                        double distancia=0;
181
                        for (int i=0;i<bandCount;i++){
182
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
183
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
184
                                distancia+=y[i];
185
                        }
186
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
187
                        if (clase==0)
188
                                distanciaFinal=distancia;
189
                        else if (distancia<distanciaFinal){
190
                                distanciaFinal= distancia;
191
                                clasefinal=clase;
192
                                }
193
                }        
194
                return clasefinal;
195
        }
196
        
197
        
198
        /**
199
        * M?todo que implementa el clasificador de m?nima distancia. 
200
        * Para cada pixel, obtiene la clase para la que la distancia eucl?dea respecto al 
201
        * vector de medias es m?nima
202
        * 
203
        * @param  array de tipo double con los valores del pixel en cada una de las bandas 
204
        * @return clase a la que pertenece el pixel
205
    */
206
        public int getPixelClassForTypeDouble(double[] pixelBandsValues) {
207
                int clasefinal=0; double distanciaFinal=0.0;
208
                for (int clase=0; clase<numClases; clase++)
209
                {
210
                        double[] y = new double[bandCount];
211
                        double distancia=0;
212
                        for (int i=0;i<bandCount;i++){
213
                                y[i]=(pixelBandsValues[i]-means[clase][i]) * (pixelBandsValues[i]-means[clase][i]);
214
                                //y[i]=Math.pow((pixelBandsValues[i]-means[clase][i]),2);
215
                                distancia+=y[i];
216
                        }
217
                        //distancia= Math.sqrt(distancia); //No hacer la raiz: Para comparar da igual la distancia que la distancia al cuadrado...
218
                        if (clase==0)
219
                                distanciaFinal=distancia;
220
                        else if (distancia<distanciaFinal){
221
                                distanciaFinal= distancia;
222
                                clasefinal=clase;
223
                                }
224
                }        
225
                return clasefinal;
226
        }
227

    
228
        
229
        /** Metodo que recoge los parametros del proceso de clasificacion de 
230
        * m?nima distancia 
231
        * <LI>rasterSE: Capa de entrada para la clasificaci?n</LI>
232
        * <LI> rois: lista de rois</LI> 
233
        * <LI> bandList:bandas habilitadas </LI> 
234
        * <LI>view: vista sobre la que se carga la capa al acabar el proceso</LI>
235
        * <LI>filename: path con el fichero de salida</LI>
236
        */
237
        public void init() {
238
                rasterSE= getLayerParam("layer");
239
                rois = (ArrayList)getParam("rois");
240
                view=(View)getParam("view");
241
                filename= getStringParam("filename");
242
                bandList = (int[])getParam("bandList");
243
                numClases = rois.size();        
244
        }
245

    
246
        
247
        /** Proceso de clasificaci?n de m?nima distancia */
248
        public void process() throws InterruptedException {
249
                setGrid();
250
                rasterResult= RasterBuffer.getBuffer(IBuffer.TYPE_BYTE, inputGrid.getRasterBuf().getWidth(), inputGrid.getRasterBuf().getHeight(), 1, true);
251
                int c=0;
252
                int iNY= inputGrid.getLayerNY();
253
                int iNX= inputGrid.getLayerNX();        
254
                
255
                bandCount  = inputGrid.getBandCount();
256
                means = new double[numClases][bandCount];
257
                for (int clase=0; clase<numClases; clase++)
258
                        for (int i=0;i<bandCount;i++){
259
                                ((ROI)rois.get(clase)).setBandToOperate(bandList[i]);
260
                                        try {
261
                                                means[clase][i]=((ROI)rois.get(clase)).getMeanValue();
262
                                                
263
                                        } catch (GridException e) {
264
                                                e.printStackTrace();
265
                                        }
266
                        }
267
                
268
                                
269
                int inputGridNX = inputGrid.getNX();
270
                int datType = inputGrid.getRasterBuf().getDataType();
271
                        
272
//                Caso Buffer tipo Byte
273
                if (datType == RasterBuffer.TYPE_BYTE){
274
                        byte data[]= new byte[bandCount];
275
                        for(int i=0; i<iNY;i++){
276
                                for(int j=0; j<iNX;j++){
277
                                        inputGrid.getRasterBuf().getElemByte(i, j, data);
278
                                        c= getPixelClassForTypeByte(data);
279
                                        rasterResult.setElem(i, j, 0,(byte) c);
280
                                }
281
                                percent = i*100/inputGridNX;
282
                        }
283
                }
284
                
285
//                Caso Buffer tipo Short
286
                else if (datType == RasterBuffer.TYPE_SHORT){
287
                        short data[]= new short[bandCount];
288
                        for(int i=0; i<iNY;i++){
289
                                for(int j=0; j<iNX;j++){
290
                                        inputGrid.getRasterBuf().getElemShort(i, j, data);
291
                                        c= getPixelClassForTypeShort(data);
292
                                        rasterResult.setElem(i, j, 0,(byte)c);
293
                                }
294
                                percent = i*100/inputGridNX;
295
                        }
296
                }
297
                        
298
//                Caso Buffer tipo Int
299
                else if (datType == RasterBuffer.TYPE_INT){
300
                        int data[]= new int[bandCount];
301
                        for(int i=0; i<iNY;i++){
302
                                for(int j=0; j<iNX;j++){
303
                                        inputGrid.getRasterBuf().getElemInt(i, j, data);
304
                                        c= getPixelClassForTypeInt(data);
305
                                        rasterResult.setElem(i, j, 0,(byte) c);
306
                                }
307
                                percent = i*100/inputGridNX;
308
                        }
309
                }
310
                
311
                
312
//                Caso Buffer tipo Float
313
                else if (datType == RasterBuffer.TYPE_FLOAT){
314
                        float data[]= new float[bandCount];
315
                        for(int i=0; i<iNY;i++){
316
                                for(int j=0; j<iNX;j++){
317
                                        inputGrid.getRasterBuf().getElemFloat(i, j, data);
318
                                        c= getPixelClassForTypeFloat(data);
319
                                        rasterResult.setElem(i, j, 0,(byte) c);
320
                                }
321
                                percent = i*100/inputGridNX;
322
                        }
323
                }
324
                                
325
                        
326
//                Caso Buffer tipo Float
327
                else if (datType == RasterBuffer.TYPE_DOUBLE){
328
                        double data[]= new double[bandCount];
329
                        for(int i=0; i<iNY;i++){
330
                                for(int j=0; j<iNX;j++){
331
                                        inputGrid.getRasterBuf().getElemDouble(i, j, data);
332
                                        c= getPixelClassForTypeDouble(data);
333
                                        rasterResult.setElem(i, j, 0,(byte) c);
334
                                }
335
                                percent = i*100/inputGridNX;
336
                        }
337
                }
338
                        
339
                writeToFile();
340
        }
341
                        
342
}