Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGeoreferencing / src / org / gvsig / georeferencing / process / geotransform / GeoTransformProcess.java @ 18673

History | View | Annotate | Download (12.1 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.setRmsXTotal(rmsXTotal);
157
                        resultData.setRmsYTotal(rmsYTotal);
158
                        resultData.setRmsTotal(rmsTotal);
159
                        resultData.setPolynomialOrden(orden);
160
                        
161
                        if(externalActions!=null)
162
                                externalActions.end(resultData);
163
                        return;
164
                }
165
                resultData = null;
166
        }
167

    
168

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

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

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

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

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

    
386
        
387
}
388