Statistics
| Revision:

root / trunk / extensions / extGeoreferencing / src / org / gvsig / georeferencing / process / geotransform / GeoTransformProcess.java @ 18530

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

    
43
import org.gvsig.raster.datastruct.GeoPoint;
44
import org.gvsig.raster.RasterProcess;
45

    
46
import Jama.Matrix;
47

    
48
import com.iver.andami.PluginServices;
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
 *         @version 20/1/2008
57
 **/
58
public class GeoTransformProcess extends RasterProcess {
59

    
60
        // Lista de puntos de control
61
        private GeoPoint gpcs[]= null;
62
        
63
        // porcentage del proceso global de la tarea
64
        private int percent=0;
65
        
66
        // orden del polinomio aproximador
67
        protected int orden = 0;
68
        
69
        // numero minimo de puntos 
70
        protected int minGPC=0;
71
        
72
        //coeficientes del polinomio de transformacion para las coordenadas en X
73
        private double []coefX=null;
74
        
75
    //coeficientes del polinomio de transformacion para las coordenadas en Y
76
        private double []coefY=null;
77
        
78
        // Lista con los valores de las potencias de x e y  
79
        private int exp[][] = null;
80
        
81
        // vector con error de la funcion en x para cada punto
82
        private double[] xError= null;
83
        
84
        //vector con el error de la funcion en y para cada punto
85
        private double [] yError=null;
86
        
87
        // rms vector con los rms para cada punto
88
        private double rms[]=null;
89
        
90
        // rms total en las x
91
        private double rmsXTotal=0;
92
        
93
        // rms total en las y
94
        private double rmsYTotal=0;
95
        
96
        // rms total
97
        private double rmsTotal=0;
98
        
99
        GeoTransformDataResult resultData= null;
100
        
101
        double xEvaluate[]= null;
102
        double yEvaluate[]=null;
103
        
104
        /** 
105
        * Metodo que recoge los parametros del proceso de transformaci?n 
106
        * <LI>gpcs: lista de puntos de control</LI>> 
107
        * <LI> orden: orden del polinomio de transformacion </LI> 
108
        */
109
        public void init() {                
110
                gpcs = (GeoPoint[])getParam("gpcs");
111
                orden= (int)getIntParam("orden");
112
                minGPC = (orden+1)*(orden+2)/2;
113
            exp=new int[minGPC][2];
114
            resultData= new GeoTransformDataResult();
115
                // Chequear si el numero de puntos es suficiente para determinar la transformacion de orden n. 
116
                if(!enoughPoints()){
117
                        // NOTIFICAR, NO SUFICIENTES PUNTOS PARA ORDEN SELECCIONADO
118
                        minGPC=0;                
119
                }
120
        }
121
        
122
        /**
123
         * @return true si se proporciona el numero minimo de puntos de entrada 
124
         * para la transformaci?n de orden seleccionado. false en caso contrario.
125
         * */                
126
        public boolean enoughPoints() {
127
                return (gpcs.length>=minGPC);
128
        }
129

    
130
        
131
        /**
132
         *  Proceso
133
         **/
134
        public void process() {
135
                if(minGPC>0){
136
                        // Obtencion  polinomio de transformacion en x
137
                        calculatePolinomialCoefX();
138
                        // Obtencion del polinomio de transformaci?n en y
139
                        calculatePolinomialCoefY();
140
                        // calculo de los resultados
141
                        calculateRMSerror();
142
                        // Se almacenan los resultados en dataResult
143
                        resultData.setGpcs(gpcs);
144
                        resultData.setPolxCoef(coefX);
145
                        resultData.setPolyCoef(coefY);
146
                        resultData.setRms(rms);
147
                        resultData.setRmsXTotal(rmsXTotal);
148
                        resultData.setRmsYTotal(rmsYTotal);
149
                        resultData.setXError(xError);
150
                        resultData.setYError(yError);
151
                        resultData.setRmsXTotal(rmsXTotal);
152
                        resultData.setRmsYTotal(rmsYTotal);
153
                        resultData.setRmsTotal(rmsTotal);
154
                        resultData.setXEvaluate(xEvaluate);
155
                        resultData.setYEvaluate(yEvaluate);
156
                        resultData.setPolynomialOrden(orden);
157
                        
158
                        if(externalActions!=null)
159
                                externalActions.end(resultData);
160
                }
161
        }
162

    
163

    
164
    /**
165
     *  Calculo de los coeficientes del polinimio aproximador.
166
     *  @return array con los coeficientes para las x. 
167
     * 
168
     * */
169
        public void calculatePolinomialCoefX(){
170
                double matrixDx[][]= new double [minGPC][minGPC]; 
171
                double result[]= new double[minGPC];
172
                int k=-1;
173
                // Obtencion de la primera fila de la matriz
174
                for (int filas=0; filas<minGPC;filas++)
175
                {        k=-1;                        
176
                for (int i=0; i<=orden; i++)
177
                        for(int j=0; j<=i; j++){
178
                                k++;
179
                                for(int v=0; v<gpcs.length;v++)
180
                                        matrixDx[filas][k]+=(Math.pow(gpcs[v].mapPoint.getX(),i-j)* Math.pow(gpcs[v].mapPoint.getX(),exp[filas][0]))
181
                                                        * (Math.pow(gpcs[v].mapPoint.getY(),j)* Math.pow(gpcs[v].mapPoint.getY(),exp[filas][1]));        
182
                                // Para la fila 0 se guardan los exponentes
183
                                if(filas==0){
184
                                        exp[k][0]=i-j;
185
                                        exp[k][1]=j;
186

    
187
                                        // Se calcula el resultado de !!!!!
188
                                        for(int v=0; v<gpcs.length;v++)
189
                                                result[k]+=(Math.pow(gpcs[v].mapPoint.getX(),i-j)* Math.pow(gpcs[v].mapPoint.getX(),exp[filas][0]))
190
                                                * (Math.pow(gpcs[v].mapPoint.getY(),j)* Math.pow(gpcs[v].mapPoint.getY(),exp[filas][1]))*gpcs[v].pixelPoint.getX();        
191
                                }
192
                        }
193
                }
194
                Matrix matrixResult= new Matrix(matrixDx);
195
                coefX=solveSistem(matrixResult,result);        
196
        }
197
        
198
        
199
        // TO DO: Ver la manera de unificar con setDxGeneral(Parametrizar un metodo general)..... Estudiar optimizaciones!!! 
200
        // Cambios necesarios para el caolculo de coeficientes para coordenadas y
201
         /**
202
     *  Calculo de los coeficientes del polinimio aproximador.
203
     *  @return array con los coeficientes para las x. 
204
     * 
205
     * */
206
        public void calculatePolinomialCoefY(){
207
                double matrixDy[][]= new double [minGPC][minGPC]; 
208
                double result[]= new double[minGPC];
209
                int k=-1;
210
                // Obtencion de la primera fila de la matriz
211
                for (int filas=0; filas<minGPC;filas++)
212
                {        k=-1;                        
213
                for (int i=0; i<=orden; i++)
214
                        for(int j=0; j<=i; j++){
215
                                k++;
216
                                for(int v=0; v<gpcs.length;v++)
217
                                        matrixDy[filas][k]+=(Math.pow(gpcs[v].mapPoint.getX(),i-j)* Math.pow(gpcs[v].mapPoint.getX(),exp[filas][0]))
218
                                                        * (Math.pow(gpcs[v].mapPoint.getY(),j)* Math.pow(gpcs[v].mapPoint.getY(),exp[filas][1]));        
219
                                // Para la fila 0 se guardan los exponentes
220
                                if(filas==0){
221
                                        exp[k][0]=i-j;
222
                                        exp[k][1]=j;
223

    
224
                                        // Se calcula el resultado de !!!!!
225
                                        for(int v=0; v<gpcs.length;v++)
226
                                                result[k]+=(Math.pow(gpcs[v].mapPoint.getX(),i-j)* Math.pow(gpcs[v].mapPoint.getX(),exp[filas][0]))
227
                                                * (Math.pow(gpcs[v].mapPoint.getY(),j)* Math.pow(gpcs[v].mapPoint.getY(),exp[filas][1]))*gpcs[v].pixelPoint.getY();        
228
                                }
229
                        }
230
                }
231
                Matrix matrixResult= new Matrix(matrixDy);
232
                coefY=solveSistem(matrixResult,result);        
233
        }
234
                
235
        /**
236
         * @return array con la solucion al sistema de ecuadiones.
237
         * */
238
        public double[] solveSistem(Matrix matrix, double columResult[]){
239
                double xCoef []= new double[minGPC];
240
                double [][]a= new double[columResult.length][1]; 
241
                for (int i=0; i<columResult.length;i++)
242
                        a[i][0]=columResult[i];
243
                Matrix c= matrix.solve(new Matrix(a));
244
                for (int i=0; i<columResult.length;i++)
245
                        xCoef[i]=c.get(i,0);
246
                return xCoef;
247
        }
248
        
249
        
250
        /**
251
         * @return vector con los RMS 
252
         * */
253
        public void calculateRMSerror(){
254
        
255
                int numgpcs= gpcs.length;
256
                xEvaluate= new double [numgpcs];
257
                yEvaluate= new double [numgpcs];
258
                rms = new double [numgpcs];
259
                xError= new double [numgpcs];
260
                yError= new double[numgpcs];
261
                double rmsxTotal=0;
262
                double rmsyTotal=0;
263
                
264
                for(int im_point=0; im_point<numgpcs;im_point++){
265
                
266
                        for(int i=0; i<minGPC;i++)
267
                        {
268
                                xEvaluate[im_point]+=coefX[i] * Math.pow(gpcs[im_point].mapPoint.getX(), exp[i][0]) * Math.pow(gpcs[im_point].mapPoint.getY(), exp[i][1]);
269
                                yEvaluate[im_point]+=coefY[i] * Math.pow(gpcs[im_point].mapPoint.getX(), exp[i][0]) * Math.pow(gpcs[im_point].mapPoint.getY(), exp[i][1]);
270

    
271
                        }        
272
                        
273
                        xError[im_point]= Math.pow(xEvaluate[im_point] -gpcs[im_point].pixelPoint.getX(), 2);
274
                        rmsxTotal+= xError[im_point];
275
                        yError[im_point]= Math.pow(yEvaluate[im_point] -gpcs[im_point].pixelPoint.getY(), 2);
276
                        rmsyTotal+= yError[im_point];
277
                        rms[im_point]=Math.sqrt
278
                        ( 
279
                                        xError[im_point]+ yError[im_point]                
280
                        );
281
                        rmsTotal+=rms[im_point];
282
                }
283
                
284
                this.rmsTotal= rmsTotal/numgpcs; 
285
                this.rmsXTotal= rmsxTotal/numgpcs;
286
                this.rmsYTotal= rmsyTotal/numgpcs;
287
                
288
        /*        System.out.print("Base X\t\t");
289
                System.out.print("Base Y\t\t");
290
                System.out.print("WarpX\t\t");
291
                System.out.print("WarpY\t\t");
292
                System.out.print("PredicX\t\t\t\t");
293
                System.out.print("PredicY\t\t\t\t");
294
                System.out.print("ErrorX\t\t\t\t");
295
                System.out.print("ErrorY\t\t\t\t");
296
                System.out.print("RMS");
297
                // Escribir resultados
298
                for(int i=0; i<numgpcs;i++)
299
                        {
300
                                System.out.print("\n");
301
                                System.out.print((new Double(gpcs[i].mapPoint.getX()).toString()+"\t\t"));
302
                                System.out.print((new Double(gpcs[i].mapPoint.getY()).toString()+"\t\t"));
303
                                System.out.print((new Double(gpcs[i].pixelPoint.getX()).toString()+"\t\t"));
304
                                System.out.print((new Double(gpcs[i].pixelPoint.getY()).toString()+"\t\t"));
305
                                System.out.print((new Double(xEvaluate[i]).toString()+"\t\t"));
306
                                System.out.print((new Double(yEvaluate[i]).toString()+"\t\t"));
307
                                System.out.print((new Double(xError[i]).toString()+"\t\t"));
308
                                System.out.print((new Double(yError[i]).toString()+"\t\t"));
309
                                System.out.print((new Double(rms[i]).toString()+"\t\t"));
310

311
                        }*/
312
                
313
        }
314
        
315
        
316
        /**
317
         * @return array con el error en la coordenada x para los puntos de entrada 
318
         * 
319
         * */
320
        public double[] getxError(){
321
                return xError;
322
                
323
        }
324
        
325
        /**
326
         * @return array con el error en la coordenada y para los puntos de entrada 
327
         * 
328
         * */
329
        public double[] getyError(){
330
                return xError;        
331
        }
332
        
333
        
334
        /**
335
         *  @return error total para la coordenada X
336
         * */
337
        public double getRMSx(){
338
                return rmsXTotal;        
339
        }
340
        
341
        
342
        /**
343
         *  @return error total para la coordenada y
344
         * */
345
        public double getRMSy(){
346
                return rmsYTotal;        
347
        }
348
        
349
        /**
350
         *  @return error total para la coordenada y
351
         * */
352
        public double getRMSTotal(){
353
                return rmsTotal;        
354
        }
355
        
356
                
357
        public String getTitle() {
358
                return PluginServices.getText(this,"transformacion");
359
        }
360

    
361
        public String getLog() {
362
                return PluginServices.getText(this,"calculando_transformacion");
363
        }
364

    
365
        
366
        public int getPercent() {
367
                return percent;
368
        }
369

    
370
        
371
}
372