Statistics
| Revision:

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

History | View | Annotate | Download (13.4 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.RasterProcess;
44
import org.gvsig.raster.datastruct.GeoPoint;
45
import org.gvsig.raster.util.RasterToolsUtil;
46

    
47
import Jama.Matrix;
48

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

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

    
129
        /**
130
         * Obtiene el resultado del proceso.
131
         * @return
132
         */
133
        public Object getResult() {
134
                return resultData;
135
        }
136
        
137
        /**
138
         *  Proceso
139
         **/
140
        public void process() {
141
                if(minGPC > 0) {
142
                        // Obtencion  polinomio de transformacion en x
143
                        calculatePolinomialCoefX();
144
                        // Obtencion del polinomio de transformaci?n en y
145
                        calculatePolinomialCoefY();
146
                        // calculo de los resultados
147
                        calculateRMSerror();
148
                        // Se almacenan los resultados en dataResult
149
                        resultData.setGpcs(gpcs);
150
                        resultData.setPixelToMapCoefX(pixelToMapCoefX);
151
                        resultData.setPixelToMapCoefY(pixelToMapCoefY);
152
                        resultData.setMapToPixelCoefX(mapToPixelCoefX);
153
                        resultData.setMapToPixelCoefY(mapToPixelCoefY);
154
                        resultData.setRmsXTotal(rmsXTotal);
155
                        resultData.setRmsYTotal(rmsYTotal);
156
                        resultData.setRmsTotal(rmsTotal);
157
                        resultData.setPolynomialOrden(orden);
158
                        
159
                        if(externalActions!=null)
160
                                externalActions.end(resultData);
161
                        return;
162
                }
163
                resultData = null;
164
        }
165

    
166

    
167
    /**
168
     *  Calculo de los coeficientes del polinimio aproximador.
169
     *  @return array con los coeficientes para las x. 
170
     * 
171
     * */
172
        public void calculatePolinomialCoefX(){
173
                
174
                double matrixDx[][]= new double [minGPC][minGPC]; 
175
                double matrixDx2[][]= new double [minGPC][minGPC];
176
                double result[]= new double[minGPC];
177
                double result2[]= new double[minGPC];                
178
                int k=-1;
179
                // Obtencion de la primera fila de la matriz
180
                for (int filas=0; filas<minGPC;filas++)
181
                {        k=-1;                        
182
                for (int i=0; i<=orden; i++)
183
                        for(int j=0; j<=i; j++){
184
                                k++;
185
                                for(int v=0; v<gpcs.length;v++){
186
                                        matrixDx[filas][k]+=(Math.pow(gpcs[v].pixelPoint.getX(),i-j)* Math.pow(gpcs[v].pixelPoint.getX(),exp[filas][0]))
187
                                                        * (Math.pow(gpcs[v].pixelPoint.getY(),j)* Math.pow(gpcs[v].pixelPoint.getY(),exp[filas][1]));
188
                                
189
                                        matrixDx2[filas][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]));        
191
                                }
192
                                // Para la fila 0 se guardan los exponentes
193
                                if(filas==0){
194
                                        exp[k][0]=i-j;
195
                                        exp[k][1]=j;
196

    
197
                                        // Se calcula el resultado de !!!!!
198
                                        for(int v=0; v<gpcs.length;v++){
199
                                                result[k]+=(Math.pow(gpcs[v].pixelPoint.getX(),i-j)* Math.pow(gpcs[v].pixelPoint.getX(),exp[filas][0]))
200
                                                * (Math.pow(gpcs[v].pixelPoint.getY(),j)* Math.pow(gpcs[v].pixelPoint.getY(),exp[filas][1]))*gpcs[v].mapPoint.getX();
201
                                        
202
                                                result2[k]+=(Math.pow(gpcs[v].mapPoint.getX(),i-j)* Math.pow(gpcs[v].mapPoint.getX(),exp[filas][0]))
203
                                                * (Math.pow(gpcs[v].mapPoint.getY(),j)* Math.pow(gpcs[v].mapPoint.getY(),exp[filas][1]))*gpcs[v].pixelPoint.getX();        
204
                                        }        
205
                                }
206
                        }
207
                }
208
                Matrix matrixResult= new Matrix(matrixDx);
209
                Matrix matrixResult2= new Matrix(matrixDx2);
210
                pixelToMapCoefX=solveSistem(matrixResult,result);        
211
                mapToPixelCoefX=solveSistem(matrixResult2,result2);
212
        }
213
        
214
        
215
        // TO DO: Ver la manera de unificar con setDxGeneral(Parametrizar un metodo general)..... Estudiar optimizaciones!!! 
216
        // Cambios necesarios para el caolculo de coeficientes para coordenadas y
217
         /**
218
     *  Calculo de los coeficientes del polinimio aproximador.
219
     *  @return array con los coeficientes para las x. 
220
     * 
221
     * */
222
        public void calculatePolinomialCoefY(){
223
                double matrixDy[][]= new double [minGPC][minGPC]; 
224
                double matrixDy2[][]= new double [minGPC][minGPC]; 
225
                double result[]= new double[minGPC];
226
                double result2[]= new double[minGPC];
227
                int k=-1;
228
                // Obtencion de la primera fila de la matriz
229
                for (int filas=0; filas<minGPC;filas++)
230
                {        k=-1;                        
231
                for (int i=0; i<=orden; i++)
232
                        for(int j=0; j<=i; j++){
233
                                k++;
234
                                for(int v=0; v<gpcs.length;v++){
235
                                        matrixDy[filas][k]+=(Math.pow(gpcs[v].pixelPoint.getX(),i-j)* Math.pow(gpcs[v].pixelPoint.getX(),exp[filas][0]))
236
                                                        * (Math.pow(gpcs[v].pixelPoint.getY(),j)* Math.pow(gpcs[v].pixelPoint.getY(),exp[filas][1]));        
237
                                        matrixDy2[filas][k]+=(Math.pow(gpcs[v].mapPoint.getX(),i-j)* Math.pow(gpcs[v].mapPoint.getX(),exp[filas][0]))
238
                                        * (Math.pow(gpcs[v].mapPoint.getY(),j)* Math.pow(gpcs[v].mapPoint.getY(),exp[filas][1]));        
239
                
240
                                
241
                                }
242
                                // Para la fila 0 se guardan los exponentes
243
                                if(filas==0){
244
                                        exp[k][0]=i-j;
245
                                        exp[k][1]=j;
246

    
247
                                        // Se calcula el resultado de !!!!!
248
                                        for(int v=0; v<gpcs.length;v++){
249
                                                result[k]+=(Math.pow(gpcs[v].pixelPoint.getX(),i-j)* Math.pow(gpcs[v].pixelPoint.getX(),exp[filas][0]))
250
                                                                * (Math.pow(gpcs[v].pixelPoint.getY(),j)* Math.pow(gpcs[v].pixelPoint.getY(),exp[filas][1]))*gpcs[v].mapPoint.getY();        
251
                                
252
                                                result2[k]+=(Math.pow(gpcs[v].mapPoint.getX(),i-j)* Math.pow(gpcs[v].mapPoint.getX(),exp[filas][0]))
253
                                                                * (Math.pow(gpcs[v].mapPoint.getY(),j)* Math.pow(gpcs[v].mapPoint.getY(),exp[filas][1]))*gpcs[v].pixelPoint.getY();
254
                                        }        
255
                                }
256
                        }
257
                }
258
                Matrix matrixResult= new Matrix(matrixDy);
259
                Matrix matrixResult2= new Matrix(matrixDy2);
260
                pixelToMapCoefY=solveSistem(matrixResult,result);        
261
                mapToPixelCoefY=  solveSistem(matrixResult2,result2);
262
        }
263
        
264
        
265

    
266
        /**
267
         * @return array con la solucion al sistema de ecuadiones.
268
         * */
269
        public double[] solveSistem(Matrix matrix, double columResult[]){
270
                double xCoef []= new double[minGPC];
271
                double [][]a= new double[columResult.length][1]; 
272
                for (int i=0; i<columResult.length;i++)
273
                        a[i][0]=columResult[i];
274
                Matrix c= matrix.solve(new Matrix(a));
275
                for (int i=0; i<columResult.length;i++)
276
                        xCoef[i]=c.get(i,0);
277
                return xCoef;
278
        }
279
        
280
        
281
        /**
282
         * @return vector con los RMS 
283
         * */
284
        public void calculateRMSerror() {
285
                
286
                int numgpcs= gpcs.length;
287
                double rmsxTotal=0;
288
                double rmsyTotal=0;
289
                rmsTotal=0;
290
                
291
                for(int im_point = 0; im_point < numgpcs; im_point++) {
292
        
293
                        double tmp[]= getCoordMap(gpcs[im_point].pixelPoint.getX(),gpcs[im_point].pixelPoint.getY());
294
                        double tmp2[]= getCoordPixel(tmp[0],tmp[1]);
295
                        
296
                        gpcs[im_point].setEvaluateX(tmp2[0]);
297
                        gpcs[im_point].setEvaluateY(tmp2[1]);
298
                        
299
                        gpcs[im_point].setErrorX(Math.pow(gpcs[im_point].getEvaluateX() - gpcs[im_point].pixelPoint.getX(), 2));
300
                        rmsxTotal += gpcs[im_point].getErrorX();
301
                        gpcs[im_point].setErrorY(Math.pow(gpcs[im_point].getEvaluateY() - gpcs[im_point].pixelPoint.getY(), 2));
302
                        rmsyTotal += gpcs[im_point].getErrorY();
303
                        gpcs[im_point].setRms(Math.sqrt(gpcs[im_point].getErrorX() + gpcs[im_point].getErrorY()));
304
                        rmsTotal += gpcs[im_point].getRms();
305
                }
306
                
307
                this.rmsTotal = rmsTotal / numgpcs; 
308
                this.rmsXTotal = rmsxTotal / numgpcs;
309
                this.rmsYTotal = rmsyTotal / numgpcs;
310
                
311
                System.out.print("Map X\t\t");
312
                System.out.print("Map Y\t\t");
313
                System.out.print("Pix X\t\t");
314
                System.out.print("Pix Y\t\t");
315
                System.out.print("PredicX\t\t\t\t");
316
                System.out.print("PredicY\t\t\t\t");
317
                System.out.print("ErrorX\t\t\t\t");
318
                System.out.print("ErrorY\t\t\t\t");
319
                System.out.print("RMS");
320
                // Escribir resultados
321
                for(int i=0; i<numgpcs;i++)
322
                        {
323
                                System.out.print("\n");
324
                                System.out.print((new Double(gpcs[i].mapPoint.getX()).toString()+"\t\t"));
325
                                System.out.print((new Double(gpcs[i].mapPoint.getY()).toString()+"\t\t"));
326
                                System.out.print((new Double(gpcs[i].pixelPoint.getX()).toString()+"\t\t"));
327
                                System.out.print((new Double(gpcs[i].pixelPoint.getY()).toString()+"\t\t"));
328
                                System.out.print((new Double(gpcs[i].getEvaluateX()).toString()+"\t\t"));
329
                                System.out.print((new Double(gpcs[i].getEvaluateY()).toString()+"\t\t"));
330
                                System.out.print((new Double(gpcs[i].getErrorX()).toString()+"\t\t"));
331
                                System.out.print((new Double(gpcs[i].getErrorY()).toString()+"\t\t"));
332
                                System.out.print((new Double(gpcs[i].getRms()).toString()+"\t\t"));
333
                                
334
                        }        
335
                System.out.println(new Double (rmsTotal).toString());
336
        }
337
                
338
        /**
339
         *  @return error total para la coordenada X
340
         * */
341
        public double getRMSx(){
342
                return rmsXTotal;        
343
        }
344
        
345
        
346
        /**
347
         *  @return error total para la coordenada y
348
         * */
349
        public double getRMSy() {
350
                return rmsYTotal;        
351
        }
352
        
353
        /**
354
         *  @return error total
355
         * */
356
        public double getRMSTotal() {
357
                return rmsTotal;        
358
        }
359
        
360
        /*
361
         * (non-Javadoc)
362
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
363
         */
364
        public String getTitle() {
365
                return RasterToolsUtil.getText(this, "transformacion");
366
        }
367

    
368
        /*
369
         * (non-Javadoc)
370
         * @see org.gvsig.raster.RasterProcess#getLog()
371
         */
372
        public String getLog() {
373
                return RasterToolsUtil.getText(this, "calculando_transformacion");
374
        }
375

    
376
        /*
377
         * (non-Javadoc)
378
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
379
         */
380
        public int getPercent() {
381
                return percent;
382
        }
383

    
384
        
385

    
386
        /**
387
         *  Funci?n que evalua el polinomio de transformaci?n para obtener las coordenadas
388
         *  reales de unas coordenadas pixeles que se pasan como parametros.
389
         * @param x coordenada x del punto
390
         * @param y coordenada y del punto
391
         * @return resultado de la evaluaci?n para x e y
392
         * */
393
        public double[] getCoordMap(double x, double y){
394
                setExpPolinomial();
395
                double eval[]= new double [2];        
396
                for(int i=0; i<pixelToMapCoefX.length;i++)
397
                {
398
                        eval[0]+=pixelToMapCoefX[i] * Math.pow(x, exp[i][0]) * Math.pow(y,exp[i][1]);
399
                        eval[1]+=pixelToMapCoefY[i] * Math.pow(x, exp[i][0]) * Math.pow(y, exp[i][1]);
400
                }        
401
                return eval;
402
        }
403

    
404
        
405
        /**
406
         *  Funci?n que evalua el polinomio de transformaci?n para obtener las coordenadas
407
         *  pixeles de unas coordenadas mapa en un proceso de transformacion.
408
         * @param x coordenada x del punto
409
         * @param y coordenada y del punto
410
         * @return resultado de la evaluaci?n para x e y
411
         * */
412
        public double[] getCoordPixel(double x, double y){
413
                setExpPolinomial();
414
                double eval[]= new double [2];        
415
                for(int i=0; i<pixelToMapCoefX.length;i++)
416
                {
417
                        eval[0]+=mapToPixelCoefX[i] * Math.pow(x, exp[i][0]) * Math.pow(y,exp[i][1]);
418
                        eval[1]+=mapToPixelCoefY[i] * Math.pow(x, exp[i][0]) * Math.pow(y, exp[i][1]);
419
                }        
420
                return eval;
421
        }
422

    
423
        
424
        private void setExpPolinomial(){
425
                if(exp==null)
426
                        {
427
                                int minGPC=(orden+1)*(orden+2)/2;
428
                                exp=new int[minGPC][2];
429
                                int k=-1;
430
                                for (int i=0; i<=orden; i++){
431
                                        for(int j=0; j<=i; j++){
432
                                                k++;
433
                                                exp[k][0]=i-j;
434
                                                exp[k][1]=j;
435
                                        }
436
                                }
437
                        }        
438
        }
439
        
440
}
441