Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / extRemoteSensing / src / org / gvsig / remotesensing / classification / NoSupervisedClassificationProcess.java @ 26348

History | View | Annotate | Download (13.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.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
 * 
72
 * @author Victor Olaya volaya@unex.es
73
 * @author Alejandro Mu?oz Sanchez (alejandro.munoz@uclm.es)
74
 * @version 15/8/2008 
75
*/
76

    
77
public class NoSupervisedClassificationProcess extends ClassificationGeneralProcess{
78

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

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

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

    
266
                writeToFile();
267
        }
268
        
269

    
270

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

    
276

    
277
        public String getLog(){
278
                return super.getLog()+"\n\n"+ PluginServices.getText(this,"reclasified_cells")+ iChangedCells +"\n";        
279
        }
280
        
281
        /**
282
        * M?todo que implementa el clasificador no supervisado  
283
        * @param  array de tipo byte con los valores del pixel en cada una de las bandas 
284
        * @return clase a la que pertenece el pixel
285
    */
286
        public int getPixelClassForTypeByte(byte[] pixelBandsValues) {
287
                int iClass = 0;
288
                double dMinDist = Double.MAX_VALUE;
289
                double dDist=0;
290
                double dDif=0;
291

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

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

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

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

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

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

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

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

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