Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extRemoteSensing / src / es / idr / teledeteccion / classification / ClassificationProcess.java @ 13671

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

    
42
package es.idr.teledeteccion.classification;
43

    
44
import java.awt.Component;
45
import java.awt.geom.AffineTransform;
46
import java.io.File;
47
import java.io.IOException;
48
import java.lang.reflect.Array;
49

    
50
import javax.swing.JOptionPane;
51

    
52
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
53
import org.gvsig.gui.beans.incrementabletask.IIncrementable;
54
import org.gvsig.gui.beans.incrementabletask.IncrementableEvent;
55
import org.gvsig.gui.beans.incrementabletask.IncrementableListener;
56
import org.gvsig.gui.beans.incrementabletask.IncrementableTask;
57
import org.gvsig.raster.buffer.RasterBuffer;
58
import org.gvsig.raster.dataset.GeoRasterWriter;
59
import org.gvsig.raster.dataset.IBuffer;
60
import org.gvsig.raster.dataset.NotSupportedExtensionException;
61
import org.gvsig.raster.dataset.RasterDriverException;
62
import org.gvsig.raster.grid.Grid;
63
import org.gvsig.raster.grid.roi.ROI;
64
import org.gvsig.rastertools.cutting.WriterBufferServer;
65

    
66
import Jama.Matrix;
67

    
68
import com.iver.andami.PluginServices;
69
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException;
70
import com.iver.cit.gvsig.fmap.MapContext;
71
import com.iver.cit.gvsig.fmap.layers.FLayer;
72

    
73
/**
74
 * Proceso de clasificacion de una imagen. Obtencion de una imagen tematica cuyos valores 
75
 * han sido clasificados atendiendo a un grupo de clases.
76
 * Metodo de clasificacion: Maxima Probabilidad
77
 * 
78
 * */
79

    
80
public class ClassificationProcess  implements Runnable, IIncrementable, IncrementableListener{
81

    
82
        private Grid                                         inputGrid                        = null;
83
        private RasterBuffer                         rasterResult                = null;
84
        private MapContext                                 mapContext                         = null;
85
        private int                                         percent                           = 0;
86
        private boolean                                 cancel                                 = false;
87
        private Thread                                         blinker                                = null;
88
        private ROI                                         classVector[]                = null;
89
        private IncrementableTask                incrementableTask         = null;
90
        private WriterBufferServer                 writerBufferServer        = null;
91
        private String                                         fileNameOutput                 = null;
92
        
93
        public  ClassificationProcess(Grid imageGrid, ROI roisArray[], MapContext mapContext, String fileNameOutput){
94
                inputGrid= imageGrid;
95
                classVector= roisArray;
96
                this.mapContext=mapContext;
97
                this.fileNameOutput= fileNameOutput;
98
        }
99
        
100
        public void start() {
101
                cancel = false;
102
                blinker = new Thread(this);
103
                blinker.start();
104
        }
105
        
106

    
107
        /**Proceso de clasificacion para cada uno de los pixeles de la imagen*/
108
        public void run() {
109
                rasterResult= RasterBuffer.getBuffer(IBuffer.TYPE_DOUBLE, inputGrid.getRasterBuf().getWidth(), inputGrid.getRasterBuf().getHeight(), 3, true);
110
                int c=0;
111
                byte data[]= new byte[inputGrid.getBandCount()];
112
                for(int i=0; i<inputGrid.getLayerNY();i++){
113
                        for(int j=0; j<inputGrid.getLayerNX();j++){
114
                                inputGrid.getRasterBuf().getElemByte(i, j, data);
115
                                c= getPixelClass(data);
116
                                rasterResult.setElem(i, j, 0,(double) classVector[c].getColor().getRed());
117
                                rasterResult.setElem(i, j, 1,(double) classVector[c].getColor().getGreen());
118
                                rasterResult.setElem(i, j, 2,(double) classVector[c].getColor().getBlue());
119
                        }
120
                        percent = i*100/inputGrid.getNX();
121
                }
122
                // Escribir en fichero
123
                writeToFile();
124
        }
125

    
126
        
127
        /**
128
         * Metodo que implementa el clasificador de maxima probabilidad. 
129
         * Para cada pixel, obtiene la calase que minimiza la expresion: -Ln(P(x))= Ln(|Si|)+Y'* inverse(Si)*Y
130
         * 
131
         * @param pixelBandBalues: array con los valores de un pixel 
132
         * @return clase a la que pertenece el pixel (por el metodo de maxima probabilidad)
133
         * */
134
        public int getPixelClass(byte pixelBandsValues[]){
135
                
136
                double probabilidades[]=new double[classVector.length];
137
                
138
                // Para todas las clases definidas obtnemos el grado de pertenencia
139
                for (int clase=0; clase<classVector.length;clase++)
140
                {
141
                        // Vector Y
142
                        double[][] y = new double[inputGrid.getBandCount()][1];
143
                        for (int i=0;i<inputGrid.getBandCount();i++){
144
                                classVector[clase].getGrid().setBandToOperate(i);
145
                                y[i][0]=pixelBandsValues[i]-classVector[clase].getMeanValue();
146
                        }
147
                        
148
                        Matrix Y = new Matrix(y);
149
                        Matrix S= new Matrix(classVector[clase].getVarCovMatrix());
150
                        Matrix result= (Y.transpose().times(S)).times(Y);
151
                        // Obtencion probabilidad de pertenencia del pixel a la clase clase
152
                        double probability= Math.log(Math.abs(S.det()))+ result.get(0, 0);
153
                        probabilidades[clase]=probability;
154
                        
155
                }        
156
                
157
                // Obtner clase para la que la probabilidad es minima
158
                int clasefinal=0;
159
                if(probabilidades.length>1){
160
                        for (int x=0; x<classVector.length;x++){
161
                                if (probabilidades[x]<probabilidades[clasefinal])
162
                                        clasefinal=x;
163
                                
164
                        }
165
                }
166
                
167
                return clasefinal;
168
        }
169
        
170
        
171

    
172
        public void writeToFile(){
173
                
174
//                 Escritura del raster a disco en fichero temporal
175
                // To Do: Parametrizar el path y el nombre del fichero de salida.
176
                GeoRasterWriter grw = null;
177
                writerBufferServer = new WriterBufferServer(rasterResult);
178
        
179
                try {
180
                        grw = GeoRasterWriter.getWriter(writerBufferServer, fileNameOutput, rasterResult.getBandCount(),new AffineTransform(), rasterResult.getWidth(), rasterResult.getHeight(), rasterResult.getDataType(), GeoRasterWriter.getWriter(fileNameOutput).getParams(), null);
181
                } catch (NotSupportedExtensionException e) {
182
                        e.printStackTrace();
183
                } catch (RasterDriverException e) {
184
                        e.printStackTrace();
185
                }
186
                try {
187
                        grw.dataWrite();
188
                } catch (IOException e) {
189
                        e.printStackTrace();
190
                }
191
                
192
                grw.writeClose();
193
            rasterResult.free();
194
            
195
            mapContext.beginAtomicEvent();
196
                FLayer lyr = null;
197
                
198
                int endIndex = fileNameOutput.lastIndexOf(".");
199
                if (endIndex < 0)
200
                         endIndex = fileNameOutput.length();
201
                
202
                try {
203
                         lyr = FLyrRasterSE.createLayer(fileNameOutput.substring(fileNameOutput.lastIndexOf(File.separator) + 1, endIndex),new File(fileNameOutput), mapContext.getProjection());
204
                } catch (LoadLayerException e) {
205
                         
206
                         JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
207
                         PluginServices.getText(this, "error_cargar_capa"));
208
                 }
209

    
210
                mapContext.getLayers().addLayer(lyr);
211
                mapContext.endAtomicEvent();
212
                mapContext.invalidate();
213
                if (incrementableTask != null)
214
                        incrementableTask.processFinalize();
215
                
216
        }
217
        
218
        
219
        public  RasterBuffer getGridResult(){
220
                return rasterResult;
221
        }
222
        
223
        public String getLabel() {
224
                return  PluginServices.getText(this,"procesando");
225
        }
226

    
227
        public String getLog() {
228
                if (writerBufferServer==null)
229
                        return PluginServices.getText(this,"obteniendo_imagen")+"...";
230
                else
231
                        return PluginServices.getText(this,"escribiendo_resultado")+"...";
232
        }
233

    
234
        public int getPercent() {
235
                if (writerBufferServer==null)
236
                        return percent;
237
                else
238
                        return writerBufferServer.getPercent();
239
        }
240

    
241
        public String getTitle() {
242
                return PluginServices.getText(this,"clasificacion");
243
        }
244

    
245
        public void actionCanceled(IncrementableEvent e) {
246
                if(writerBufferServer != null)
247
                        writerBufferServer.setCanceled(true, 0);
248
                cancel = true;
249
        }
250

    
251
        public void actionResumed(IncrementableEvent e) {
252
                
253
        }
254

    
255
        public void actionSuspended(IncrementableEvent e) {
256
        }
257

    
258
        public void setIncrementableTask(IncrementableTask incrementableTask) {
259
                this.incrementableTask = incrementableTask;
260
                this.incrementableTask.addIncrementableListener(this);
261
        }        
262

    
263
}