Statistics
| Revision:

root / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / classification / NoSupervisedClassificationProcess.java @ 23225

History | View | Annotate | Download (13.7 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.awt.Color;
44
import java.io.File;
45
import java.io.IOException;
46
import java.util.ArrayList;
47
import java.util.Arrays;
48

    
49
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
50
import org.gvsig.raster.buffer.RasterBuffer;
51
import org.gvsig.raster.buffer.WriterBufferServer;
52
import org.gvsig.raster.dataset.GeoRasterWriter;
53
import org.gvsig.raster.dataset.IBuffer;
54
import org.gvsig.raster.dataset.NotSupportedExtensionException;
55
import org.gvsig.raster.dataset.io.RasterDriverException;
56
import org.gvsig.raster.datastruct.ColorItem;
57
import org.gvsig.raster.grid.GridException;
58
import org.gvsig.raster.grid.filter.FilterTypeException;
59
import org.gvsig.raster.util.RasterToolsUtil;
60
import org.gvsig.remotesensing.RemoteSensingUtils;
61

    
62
import com.iver.andami.PluginServices;
63
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException;
64
import com.iver.cit.gvsig.fmap.layers.FLayer;
65
import com.iver.cit.gvsig.project.documents.view.gui.View;
66

    
67
/** NoSupervisedClassificationProcess implementa el m?todo de clasificaci?n de 
68
 * no supervisada
69
 * 
70
 * @see ClassificationGeneralProcess
71
 * @author Alejandro Mu?oz Sanchez (alejandro.munoz@uclm.es)
72
 * @author volaya
73
 * @version 15/8/2008 
74
*/
75

    
76
public class NoSupervisedClassificationProcess extends ClassificationGeneralProcess{
77

    
78
        double mean[][]=null;
79
        double dmax[]= null;
80
        double dmin[]= null;
81
        int m_iCells[]=null;
82
        int m_iThreshold=0;
83
        
84
        private static Color[]           colors  = new Color[] {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.MAGENTA, Color.CYAN,
85
                Color.ORANGE, Color.PINK, Color.WHITE, Color.BLACK};
86
        
87
        
88
        /** Metodo que recoge los parametros del proceso de clasificacion no supervisada
89
        * <LI>rasterSE: Capa de entrada para la clasificaci?n</LI>
90
        * <LI> bandList:bandas habilitadas </LI> 
91
        * <LI>view: vista sobre la que se carga la capa al acabar el proceso</LI>
92
        * <LI>filename: path con el fichero de salida</LI>
93
        */
94
        public void init() {
95
                
96
                rasterSE= (FLyrRasterSE)getParam("layer");
97
                view=(View)getParam("view");
98
                filename= getStringParam("filename");
99
                bandList = (int[])getParam("bandList");
100
                numClases = getIntParam("numClases");
101
                if (bandList.length == 0 || numClases == 0)
102
                        // no se puede clasificar 
103
                        return;
104
                setGrid();
105
                rasterResult= RasterBuffer.getBuffer(IBuffer.TYPE_BYTE, inputGrid.getRasterBuf().getWidth(), inputGrid.getRasterBuf().getHeight(), 1, true);
106
                mean= new double[numClases][inputGrid.getBandCount()];
107
                
108
                dmax=new double [inputGrid.getBandCount()];
109
                dmin= new double [inputGrid.getBandCount()];
110
                
111
                // Se completan los datos  de 
112
                for(int i=0; i< inputGrid.getBandCount();i++){
113
                        inputGrid.setBandToOperate(i);
114
                        try {
115
                                dmax[i]= inputGrid.getMaxValue();
116
                                dmin[i]= inputGrid.getMinValue();
117
                        } catch (GridException e) {
118
                                // TODO Auto-generated catch block
119
                                e.printStackTrace();
120
                        }
121
                }
122
                
123
                double dStep=0.0;
124
                for (int i = 0; i < inputGrid.getBandCount(); i++){
125
                        dStep = (dmax[i] - dmin[i]) / ((double) (numClases + 1));
126
                        for (int j = 0; j < numClases; j++) {
127
                                mean[j][i] = dmin[i] + dStep * (j + 1);
128
                        }
129
                }
130
                m_iThreshold = (int) (inputGrid.getLayerNX()*inputGrid.getNY() * 0.02);
131
        }
132
        
133
        /** Proceso de clasificacion no supervisada*/
134
        public void process() throws InterruptedException {
135
                
136
                        int i;
137
                        int x,y;
138
                        int iChangedCells=0;
139
                        int iPrevClass=0;
140
                        int iClass=0;
141
                        double dNewMean[][] = null;
142
                        double swap[][];
143
                        m_iCells = new int [numClases];
144
                
145
                        do{
146
                                Arrays.fill(m_iCells, (byte)0);
147
                                iChangedCells = 0;
148
                                dNewMean = new double [numClases][inputGrid.getBandCount()];
149
                                for (i = 0; i < numClases; i++){
150
                                        Arrays.fill(dNewMean[i], 0.0);
151
                                }
152
                                if(inputGrid.getRasterBuf().getDataType()==RasterBuffer.TYPE_BYTE){
153
                                        byte dValues[] = new byte[inputGrid.getBandCount()];
154
                                        for(y=0; y<inputGrid.getNY(); y++){
155
                                                for(x=0; x<inputGrid.getNX(); x++){
156
                                                        iPrevClass = rasterResult.getElemByte(y,x,0);
157
                                                        inputGrid.getRasterBuf().getElemByte(y,x,dValues);
158
                                                        iClass = getPixelClassForTypeByte(dValues);
159
                                                        rasterResult.setElem(y, x, 0,(byte)iClass);
160
                                
161
                                                        for (i = 0; i < inputGrid.getBandCount(); i++){
162
                                                                dNewMean[iClass][i] += dValues[i]&0xff;
163
                                                        }
164
                                                        m_iCells[iClass]++;
165
                                                        if (iClass != iPrevClass){
166
                                                                iChangedCells++;        
167
                                                        }
168
                                                }
169
                                        }
170
                                }
171
                                
172
                                if(inputGrid.getRasterBuf().getDataType()==RasterBuffer.TYPE_SHORT){
173
                                        short dValues[] = new short[inputGrid.getBandCount()];
174
                                        for(y=0; y<inputGrid.getNY(); y++){
175
                                                for(x=0; x<inputGrid.getNX(); x++){
176
                                                        iPrevClass = rasterResult.getElemByte(y,x,0);
177
                                                        inputGrid.getRasterBuf().getElemShort(y,x,dValues);
178
                                                        iClass = getPixelClassForTypeShort(dValues);
179
                                                        rasterResult.setElem(y, x, 0,(byte)iClass);
180
                                
181
                                                        for (i = 0; i < inputGrid.getBandCount(); i++){
182
                                                                dNewMean[iClass][i] += dValues[i];
183
                                                        }
184
                                                        m_iCells[iClass]++;
185
                                                        if (iClass != iPrevClass){
186
                                                                iChangedCells++;        
187
                                                        }
188
                                                }
189
                                        }
190
                                }
191
                                
192
                                if(inputGrid.getRasterBuf().getDataType()==RasterBuffer.TYPE_INT){
193
                                        int dValues[] = new int[inputGrid.getBandCount()];
194
                                        for(y=0; y<inputGrid.getNY(); y++){
195
                                                for(x=0; x<inputGrid.getNX(); x++){
196
                                                        iPrevClass = rasterResult.getElemByte(y,x,0);
197
                                                        inputGrid.getRasterBuf().getElemInt(y,x,dValues);
198
                                                        iClass = getPixelClassForTypeInt(dValues);
199
                                                        rasterResult.setElem(y, x, 0,(byte)iClass);
200
                                
201
                                                        for (i = 0; i < inputGrid.getBandCount(); i++){
202
                                                                dNewMean[iClass][i] += dValues[i];
203
                                                        }
204
                                                        m_iCells[iClass]++;
205
                                                        if (iClass != iPrevClass){
206
                                                                iChangedCells++;        
207
                                                        }
208
                                                }
209
                                        }
210
                                }
211

    
212
                                if(inputGrid.getRasterBuf().getDataType()==RasterBuffer.TYPE_FLOAT){
213
                                        float dValues[] = new float[inputGrid.getBandCount()];
214
                                        for(y=0; y<inputGrid.getNY(); y++){
215
                                                for(x=0; x<inputGrid.getNX(); x++){
216
                                                        iPrevClass = rasterResult.getElemByte(y,x,0);
217
                                                        inputGrid.getRasterBuf().getElemFloat(y,x,dValues);
218
                                                        iClass = getPixelClassForTypeFloat(dValues);
219
                                                        rasterResult.setElem(y, x, 0,(byte)iClass);
220
                                
221
                                                        for (i = 0; i < inputGrid.getBandCount(); i++){
222
                                                                dNewMean[iClass][i] += dValues[i];
223
                                                        }
224
                                                        m_iCells[iClass]++;
225
                                                        if (iClass != iPrevClass){
226
                                                                iChangedCells++;        
227
                                                        }
228
                                                }
229
                                        }
230
                                }
231
                                
232
                                if(inputGrid.getRasterBuf().getDataType()==RasterBuffer.TYPE_DOUBLE){
233
                                        double dValues[] = new double[inputGrid.getBandCount()];
234
                                        for(y=0; y<inputGrid.getNY(); y++){
235
                                                for(x=0; x<inputGrid.getNX(); x++){
236
                                                        iPrevClass = rasterResult.getElemByte(y,x,0);
237
                                                        inputGrid.getRasterBuf().getElemDouble(y,x,dValues);
238
                                                        iClass = getPixelClassForTypeDouble(dValues);
239
                                                        rasterResult.setElem(y, x, 0,(byte)iClass);
240
                                
241
                                                        for (i = 0; i < inputGrid.getBandCount(); i++){
242
                                                                dNewMean[iClass][i] += dValues[i];
243
                                                        }
244
                                                        m_iCells[iClass]++;
245
                                                        if (iClass != iPrevClass){
246
                                                                iChangedCells++;        
247
                                                        }
248
                                                }
249
                                        }
250
                                }
251
                                
252
                                for (i = 0; i <inputGrid.getBandCount(); i++){
253
                                        for (int j = 0; j < numClases; j++) {
254
                                                dNewMean[j][i] /= (double)m_iCells[j];
255
                                        }
256
                                }
257

    
258
                                swap = mean;
259
                                mean= dNewMean;
260
                                dNewMean = swap;
261
                                
262
                        }while (iChangedCells > m_iThreshold);
263

    
264
                writeToFile();
265
        }
266
        
267

    
268
        public String getTitle() {
269
                // TODO Auto-generated method stub
270
                return null;
271
        }
272

    
273
        public int getPercent() {
274
                // TODO Auto-generated method stub
275
                return 0;
276
        }
277

    
278

    
279
        /**
280
        * M?todo que implementa el clasificador no supervisado  
281
        * @param  array de tipo byte con los valores del pixel en cada una de las bandas 
282
        * @return clase a la que pertenece el pixel
283
    */
284
        public int getPixelClassForTypeByte(byte[] pixelBandsValues) {
285
                int iClass = 0;
286
                double dMinDist = Double.MAX_VALUE;
287
                double dDist=0;
288
                double dDif=0;
289

    
290
                for (int i = 0; i < numClases; i++) {
291
                        dDist = 0;
292
                        for (int j = 0; j < pixelBandsValues.length; j++) {
293
                                dDif = mean[i][j] - (pixelBandsValues[j]&0xff);
294
                                dDist += (dDif* dDif);
295
                        }
296
                        if (dDist < dMinDist){
297
                                dMinDist = dDist;
298
                                iClass = i;
299
                        }
300
                }
301
                return iClass;
302
        }
303

    
304
        /**
305
        * M?todo que implementa el clasificador no supervisado  
306
        * @param  array de tipo double con los valores del pixel en cada una de las bandas 
307
        * @return clase a la que pertenece el pixel
308
    */
309
        public int getPixelClassForTypeShort(short[] pixelBandsValues) {
310
                int iClass = 0;
311
                double dMinDist = Double.MAX_VALUE;
312
                double dDist;
313
                double dDif;
314

    
315
                for (int i = 0; i < numClases; i++) {
316
                        dDist = 0;
317
                        for (int j = 0; j < pixelBandsValues.length; j++) {
318
                                dDif = mean[i][j] - pixelBandsValues[j];
319
                                dDist += (dDif* dDif);
320
                        }
321
                        if (dDist < dMinDist){
322
                                dMinDist = dDist;
323
                                iClass = i;
324
                        }
325
                }
326
                return iClass;
327
        }
328

    
329
        /**
330
        * M?todo que implementa el clasificador no supervisado  
331
        * @param  array de tipo int con los valores del pixel en cada una de las bandas 
332
        * @return clase a la que pertenece el pixel
333
    */
334
        public int getPixelClassForTypeInt(int[] pixelBandsValues) {
335
                int iClass = 0;
336
                double dMinDist = Double.MAX_VALUE;
337
                double dDist;
338
                double dDif;
339

    
340
                for (int i = 0; i < numClases; i++) {
341
                        dDist = 0;
342
                        for (int j = 0; j < pixelBandsValues.length; j++) {
343
                                dDif = mean[i][j] - pixelBandsValues[j];
344
                                dDist += (dDif* dDif);
345
                        }
346
                        if (dDist < dMinDist){
347
                                dMinDist = dDist;
348
                                iClass = i;
349
                        }
350
                }
351
                return iClass;
352
        }
353

    
354
        
355
        /**
356
        * M?todo que implementa el clasificador no supervisado  
357
        * @param  array de tipo float con los valores del pixel en cada una de las bandas 
358
        * @return clase a la que pertenece el pixel
359
    */
360
        public int getPixelClassForTypeFloat(float[] pixelBandsValues) {
361
                int iClass = 0;
362
                double dMinDist = Double.MAX_VALUE;
363
                double dDist;
364
                double dDif;
365

    
366
                for (int i = 0; i < numClases; i++) {
367
                        dDist = 0;
368
                        for (int j = 0; j < pixelBandsValues.length; j++) {
369
                                dDif = mean[i][j] - pixelBandsValues[j];
370
                                dDist += (dDif* dDif);
371
                        }
372
                        if (dDist < dMinDist){
373
                                dMinDist = dDist;
374
                                iClass = i;
375
                        }
376
                }
377
                return iClass;
378
        }
379

    
380
        
381
        /**
382
        * M?todo que implementa el clasificador no supervisado  
383
        * @param  array de tipo double con los valores del pixel en cada una de las bandas 
384
        * @return clase a la que pertenece el pixel
385
    */
386
        public int getPixelClassForTypeDouble(double[] pixelBandsValues) {
387
                int iClass = 0;
388
                double dMinDist = Double.MAX_VALUE;
389
                double dDist;
390
                double dDif;
391

    
392
                for (int i = 0; i < numClases; i++) {
393
                        dDist = 0;
394
                        for (int j = 0; j < pixelBandsValues.length; j++) {
395
                                dDif = mean[i][j] - pixelBandsValues[j];
396
                                dDist += (dDif* dDif);
397
                        }
398
                        if (dDist < dMinDist){
399
                                dMinDist = dDist;
400
                                iClass = i;
401
                        }
402
                }
403
                return iClass;
404
        }
405
        
406
        
407
        
408
        
409
        public void writeToFile() {
410
                try{
411
                        if(filename==null)
412
                                return;
413
                        GeoRasterWriter grw = null;
414
                        writerBufferServer = new WriterBufferServer(rasterResult);
415
                        grw = GeoRasterWriter.getWriter(writerBufferServer, filename, rasterResult.getBandCount(),rasterSE.getAffineTransform(), rasterResult.getWidth(), rasterResult.getHeight(), rasterResult.getDataType(), GeoRasterWriter.getWriter(filename).getParams(), null);
416
                        grw.dataWrite();
417
                        grw.setWkt(rasterSE.getWktProjection());
418
                        grw.writeClose();
419
                        rasterResult.free();
420
                        mapContext= view.getModel().getMapContext();
421
                        mapContext.beginAtomicEvent();
422
                        FLayer lyr = null;
423
                        int endIndex = filename.lastIndexOf(".");
424
                        if (endIndex < 0)
425
                                endIndex = filename.length();
426
                
427
                        lyr = FLyrRasterSE.createLayer(
428
                                        filename.substring(filename.lastIndexOf(File.separator) + 1, endIndex),
429
                                        filename,
430
                                        view.getMapControl().getProjection()
431
                                        );
432
                        
433
                        ArrayList colorItems = new ArrayList();
434
                        ColorItem colorItem = null;
435
                        int classValue = 0;
436
                        for (int i=0; i< numClases; i++) {
437
                                colorItem = new ColorItem();
438
                                colorItem.setColor(colors[i]);
439
                                colorItem.setNameClass("class"+i);
440
                                colorItem.setValue(classValue);
441
                                colorItems.add(colorItem);
442
                                classValue++;
443
                        }
444
                        RemoteSensingUtils.setLeyend(lyr,colorItems);
445
                        mapContext.getLayers().addLayer(lyr);
446
                        mapContext.endAtomicEvent();
447
                        mapContext.invalidate();
448
                        
449
        } catch (NotSupportedExtensionException e) {
450
                RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer_notsupportedextension"), this, e);
451
        } catch (RasterDriverException e) {
452
                RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer"), this, e);        
453
        } catch (IOException e) {
454
                RasterToolsUtil.messageBoxError(PluginServices.getText(this, "error_writer"), this, e);
455
        }catch (LoadLayerException e) {
456
                RasterToolsUtil.messageBoxError("error_cargar_capa", this, e);
457
        }catch (InterruptedException e) {
458
                Thread.currentThread().interrupt();
459
        } catch (FilterTypeException e) {
460
                // TODO Auto-generated catch block
461
                e.printStackTrace();
462
        }
463
        }
464
}