Statistics
| Revision:

root / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / georeferencing / geotransform / GeoTransformProcess.java @ 18384

History | View | Annotate | Download (10.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.georeferencing.geotransform;
42

    
43
import org.gvsig.rastertools.RasterProcess;
44

    
45

    
46
import com.iver.andami.PluginServices;
47

    
48
import Jama.Matrix;
49

    
50
/**
51
 *  Clase que representa una transformacion polinomial  para la convertir las
52
 *  coordenadas de una imagen en la imagen rectificada.
53
 *  
54
 *  
55
 *  @author Alejandro Mu?oz Sanchez (alejandro.munoz@uclm.es)
56
 *         @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)  
57
 *         @version 20/1/2008
58
 **/
59
public class GeoTransformProcess extends RasterProcess {
60

    
61
        // Esto va a cambiar dependiendo del formato de los punto de la interfaz
62
        // de momento geo_points puntos sobre imagen georeferenciada, image_points
63
        // puntos sobre imagen a georeferenciar.
64
        
65
        // Utilizar GeoPoint
66
        protected double geo_points[][]=new double[2][];
67
        protected double image_points[][]=new double[2][];
68
        
69
        // porcentage del proceso global de la tarea
70
        private int percent=0;
71
        
72
        // orden del polinomio aproximador
73
        protected int orden = 0;
74
        
75
        // numero minimo de puntos 
76
        protected int minGPC=0;
77
        
78
        //coeficientes del polinomio de transformacion para las coordenadas en X
79
        private double []coefX=null;
80
        
81
    //coeficientes del polinomio de transformacion para las coordenadas en Y
82
        private double []coefY=null;
83
        
84
        // Lista con los valores de las potencias de x e y  
85
        private int exp[][] = null;
86
        
87
        // error de la funcion en x
88
        private double[] xError= null;
89
        
90
        // error de la funcion para las y
91
        private double [] yError=null;
92
        
93
        // rms
94
        private double rms[]=null;
95
        
96
        /** Metodo que recoge los parametros del proceso de clasificacion de 
97
        * m?xima probabilidad 
98
        * <LI>geo_points: lista de puntos con coordenadas reales</LI>
99
        * <LI> image_points: lista de puntos coordenadas pixel</LI> 
100
        * <LI> orden: orden del polinomio de transformacion </LI> 
101
        */
102
        public void init() {                
103
                geo_points =(double[][]) getParam("geoPoints");
104
                image_points=(double[][]) getParam("imagePoints");
105
                orden= (int)getIntParam("orden");
106
                minGPC = (orden+1)*(orden+2)/2;
107
            exp=new int[minGPC][2];
108
                // Chequear si el numero de puntos es suficiente para determinar la transformacion de orden n. 
109
                if(!enoughPoints()){
110
                        // NOTIFICAR, NO SUFICIENTES PUNTOS PARA ORDEN SELECCIONADO
111
                        minGPC=0;
112
                        // Detener ejecucion del calculo.
113
                        
114
                }
115
        }
116
        
117
        /**
118
         * @return true si se proporciona el numero minimo de puntos de entrada 
119
         * para la transformaci?n. false en caso contrario.
120
         * */                
121
        public boolean enoughPoints() {
122
                // obligar a que las listas de puntos tengan la misma longitud
123
                return (geo_points.length>=minGPC && image_points.length==geo_points.length);
124
        }
125

    
126
        /**
127
         *  Proceso de calculo de los coeficientes del polinomio. 
128
         **/
129
        public void process() throws InterruptedException {
130
                // Obtencion  polinomio de transformacion en x
131
                getPolinomyalCoefX();
132
                // Obtencion del polinomio de transformaci?n en y
133
                getPolinomialCoefY();
134
                // calculo de los resultados
135
                getRMSerror();
136
        }
137

    
138

    
139
        /**
140
         * @return coeficientes para el polinomio de transformaci?n en x.
141
         **/
142
        public double[] getPolinomyalCoefX(){
143
                if(coefX==null)
144
                        setDxGeneral();
145
                return coefX;
146
        }
147
        
148
        
149
        /**
150
         * @return coeficientes para el polinomio de transformaci?n en y.
151
         * */
152
        public double[] getPolinomialCoefY(){
153
                if(coefY==null)
154
                        setDyGeneral();
155
                return coefY;
156
        }
157
        
158

    
159
/////////!!!!!!! Obtiene matriz general a partir de los puntos de control y el orden del polinomio aproximador
160
        public void setDxGeneral(){
161
                double matrixDx[][]= new double [minGPC][minGPC]; 
162
                double result[]= new double[minGPC];
163
                int exp[][]=new int[minGPC][2];
164
                int k=-1;
165
                // Obtencion de la primera fila de la matriz
166
                
167
                for (int filas=0; filas<minGPC;filas++)
168
                {        k=-1;
169
                for (int i=0; i<=orden; i++)
170
                        for(int j=0; j<=i; j++){
171
                                k++;
172
                                for(int v=0; v<geo_points.length;v++)
173
                                        matrixDx[filas][k]+=(Math.pow(geo_points[v][0],i-j)* Math.pow(geo_points[v][0],exp[filas][0]))
174
                                                        * (Math.pow(geo_points[v][1],j)* Math.pow(geo_points[v][1],exp[filas][1]));                        
175
                                // Para la fila 0 se guardan los exponentes
176
                                if(filas==0){
177
                                        exp[k][0]=i-j;
178
                                        exp[k][1]=j;
179

    
180
                                        // Se calcula el resultado de !!!!!
181
                                        for(int v=0; v<geo_points.length;v++)
182
                                                result[k]+=(Math.pow(geo_points[v][0],i-j)* Math.pow(geo_points[v][0],exp[filas][0]))
183
                                                * (Math.pow(geo_points[v][1],j)* Math.pow(geo_points[v][1],exp[filas][1]))*image_points[v][0];                                
184
                                }
185
        
186
                        }
187
                }
188
                Matrix matrixResult= new Matrix(matrixDx);
189
                coefX=solveSistem(matrixResult,result);
190
        }
191
        
192
        
193
        // TO DO: Ver la manera de unificar con setDxGeneral(Parametrizar un metodo general)..... Estudiar optimizaciones!!! 
194
        // Cambios necesarios para el caolculo de coeficientes para coordenadas y
195
        public void setDyGeneral(){
196
                double matrixDy[][]= new double [minGPC][minGPC]; 
197
                double result[]= new double[minGPC];
198
                int k=-1;
199
                // Obtencion de la primera fila de la matriz
200
                
201
                for (int filas=0; filas<minGPC;filas++)
202
                {        k=-1;
203
                for (int i=0; i<=orden; i++)
204
                        for(int j=0; j<=i; j++){
205
                                k++;
206
                                for(int v=0; v<geo_points.length;v++)
207
                                        matrixDy[filas][k]+=(Math.pow(geo_points[v][0],i-j)* Math.pow(geo_points[v][0],exp[filas][0]))
208
                                                        * (Math.pow(geo_points[v][1],j)* Math.pow(geo_points[v][1],exp[filas][1]));                        
209
                                // Para la fila 0 se guardan los exponentes
210
                                if(filas==0){
211
                                        exp[k][0]=i-j;
212
                                        exp[k][1]=j;
213

    
214
                                        // Se calcula el resultado de !!!!!
215
                                        for(int v=0; v<geo_points.length;v++)
216
                                                result[k]+=(Math.pow(geo_points[v][0],i-j)* Math.pow(geo_points[v][0],exp[filas][0]))
217
                                                * (Math.pow(geo_points[v][1],j)* Math.pow(geo_points[v][1],exp[filas][1]))*image_points[v][1];                                
218
                                }
219
        
220
                        }
221
                }
222
                Matrix matrixResult= new Matrix(matrixDy);
223
                coefY=solveSistem(matrixResult,result);        
224
        }
225
                
226
        /**
227
         * @return array con la solucion al sistema de ecuadiones.
228
         * */
229
        public double[] solveSistem(Matrix matrix, double columResult[]){
230
                double xCoef []= new double[minGPC];
231
                double [][]a= new double[columResult.length][1]; 
232
                for (int i=0; i<columResult.length;i++)
233
                        a[i][0]=columResult[i];
234
                Matrix c= matrix.solve(new Matrix(a));
235
                for (int i=0; i<columResult.length;i++)
236
                        xCoef[i]=c.get(i,0);
237
                return xCoef;
238
        }
239
        
240
        
241
        /**
242
         * @return vector con los RMS 
243
         * */
244
        public double[] getRMSerror(){
245
        
246
                double xEvaluate[]= new double [image_points.length];
247
                double yEvaluate[]= new double [image_points.length];
248
                rms = new double [image_points.length];
249
                xError= new double [image_points.length];
250
                yError= new double[image_points.length];
251
                for(int im_point=0; im_point<image_points.length;im_point++){
252
                
253
                        for(int i=0; i<minGPC;i++)
254
                        {
255
                                xEvaluate[im_point]+=coefX[i] * Math.pow(geo_points[im_point][0], exp[i][0]) * Math.pow(geo_points[im_point][1], exp[i][1]);
256
                                yEvaluate[im_point]+=coefY[i] * Math.pow(geo_points[im_point][0], exp[i][0]) * Math.pow(geo_points[im_point][1], exp[i][1]);
257

    
258
                        }        
259
                        
260
                        xError[im_point]= Math.pow(xEvaluate[im_point] -image_points[im_point][0], 2);
261
                        yError[im_point]= Math.pow(yEvaluate[im_point] -image_points[im_point][1], 2);
262
                        rms[im_point]=Math.sqrt
263
                        ( 
264
                                        xError[im_point]+ yError[im_point]                
265
                        );
266
                        
267
                }
268

    
269
                System.out.print("Base X\t\t");
270
                System.out.print("Base Y\t\t");
271
                System.out.print("WarpX\t\t");
272
                System.out.print("WarpY\t\t");
273
                System.out.print("PredicX\t\t\t\t");
274
                System.out.print("PredicY\t\t\t\t");
275
                System.out.print("ErrorX\t\t\t\t");
276
                System.out.print("ErrorY\t\t\t\t");
277
                System.out.print("RMS");
278
                // Escriir resultados
279
                for(int i=0; i<image_points.length;i++)
280
                        {
281
                                System.out.print("\n");
282
                                System.out.print((new Double(geo_points[i][0]).toString()+"\t\t"));
283
                                System.out.print((new Double(geo_points[i][1]).toString()+"\t\t"));
284
                                System.out.print((new Double(image_points[i][0]).toString()+"\t\t"));
285
                                System.out.print((new Double(image_points[i][1]).toString()+"\t\t"));
286
                                System.out.print((new Double(xEvaluate[i]).toString()+"\t\t"));
287
                                System.out.print((new Double(yEvaluate[i]).toString()+"\t\t"));
288
                                System.out.print((new Double(xError[i]).toString()+"\t\t"));
289
                                System.out.print((new Double(yError[i]).toString()+"\t\t"));
290
                                System.out.print((new Double(rms[i]).toString()+"\t\t"));
291

    
292
                        }
293
                return rms;        
294
        }
295
        
296
        
297
        /**
298
         * @return array con el error en la coordenada x para los puntos de entrada 
299
         * 
300
         * */
301
        public double[] getxError(){
302
                return xError;
303
                
304
        }
305
        
306
        /**
307
         * @return array con el error en la coordenada y para los puntos de entrada 
308
         * 
309
         * */
310
        public double[] getyError(){
311
                return xError;
312
                
313
        }
314
        
315
        
316
        
317
        /**
318
         *  Funci?n que evalua el polinomio de transformaci?n para un punto especifico
319
         * @param x coordenada x del punto
320
         * @param y coordenada y del punto
321
         * @return resultado de la evaluaci?n
322
         * */
323
        double[] evaluate(double x, double y){
324
                double eval[]= new double [2];        
325
                for(int i=0; i<minGPC;i++)
326
                {
327
                        eval[0]+=coefX[i] * Math.pow(x, exp[i][0]) * Math.pow(y, exp[i][1]);
328
                        eval[1]+=coefY[i] * Math.pow(x, exp[i][0]) * Math.pow(y, exp[i][1]);
329

    
330
                }        
331
                return eval;
332
        }
333
        
334
        
335
        
336
        public String getTitle() {
337
                return PluginServices.getText(this,"transformacion");
338
        }
339

    
340

    
341
        public String getLog() {
342
                return PluginServices.getText(this,"calculando_transformacion");
343
        }
344

    
345
        
346
        public int getPercent() {
347
                // TODO Auto-generated method stub
348
                return percent;
349
        }
350
        
351
        
352
}
353
        
354
        
355
        
356
        
357