Statistics
| Revision:

root / branches / v10 / extensions / extRasterTools / src / org / gvsig / rasterTools / pansharpening / filter / PanSharpeningImageFilter.java @ 10238

History | View | Annotate | Download (13.9 KB)

1
/*
2
 * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
3
 *
4
 * Copyright (C) 2004-5.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 * cresques@gmail.com
23
 */
24
package org.gvsig.rasterTools.pansharpening.filter;
25

    
26
import java.awt.Graphics2D;
27
import java.awt.Image;
28
import java.awt.image.BufferedImage;
29
import java.awt.image.PixelGrabber;
30

    
31
import org.cresques.filter.ColorSpaceConversion;
32
import org.cresques.geo.ViewPortData;
33
import org.cresques.io.GeoRasterFile;
34
import org.cresques.io.data.RasterBuf;
35
import org.cresques.px.PxRaster;
36

    
37

    
38
/**
39
 * Filtro de sharpening que se aplica sobre la vista. Tiene como entradas el objeto Image
40
 * con las bandas del raster visualizadas en la Vista y la banda pancrom?tica. A partir de
41
 * estas entradas genera un Image de salida como la que hay pero de resoluci?n igual a la
42
 * de la pancrom?tica.  
43
 * @author Nacho Brodin (brodin_ign@gva.es)
44
 *
45
 */
46
public class PanSharpeningImageFilter extends PanSharpeningFilter {
47
        
48
        //Variable que dice para cada pixel de la imagen de entrada cuantos de salida hay.
49
        private int                         nOutputPixelsPerInputPixel;  
50
        //Vector con los desplazamientos de los pixeles de salida dentro del vector
51
        private int[]                         outKernel;
52
        //Kernel aplicado a la pancromatica 
53
        private Kernel                        kernel = null; 
54
        private PixelGrabber         pgAct = null, pgPrev = null, pgNext = null;
55
        int[]                                        bufferPrev = null, bufferAct = null, bufferNext = null;
56
        
57
    /**
58
     * Constructor
59
     *
60
     */
61
    public PanSharpeningImageFilter() {
62
        super();
63
    }
64

    
65
    /**
66
     *  Validamos que haya alguna otra banda adem?s de la pancrom?tica y que la pancrom?tica 
67
     *  sea de mayor resoluci?n que las dem?s.
68
     */
69
    private void checkInput(){
70
            exec = true;
71
        if(heightMultiespec >= heightPancr || widthMultiespec >= widthPancr || heightMultiespec == 0 || widthMultiespec == 0)
72
                        exec = false;
73
        for(int i=0;i<files.length;i++){
74
                if(i != posPancromatica){
75
                        if(files[i].getHeight() != heightMultiespec || files[i].getWidth() != widthMultiespec){
76
                                exec = false;
77
                                break;
78
                        }                   
79
                }
80
        }
81
    }
82
    
83
    /**
84
     * Carga los par?metros pasados al filtro en las variables de 
85
     * instancia que corresponde,
86
     */
87
    private void loadParam(){
88
            //Carga de parametros
89
            this.image = (Image) params.get("raster");
90
        posPancromatica = ((Integer) params.get("pancromatica")).intValue();
91
        files = (GeoRasterFile[]) params.get("files");
92
        bandOrder = (int[]) params.get("order");
93
        alpha = ((Integer) params.get("alpha")).intValue();
94
        method = (String) params.get("method");
95
        coef = ((Double) params.get("coef")).doubleValue();
96
        coefBrovey = ((Integer) params.get("coefBrovey")).intValue();
97
        
98
        //Asignamos el nombre de la banda pancrom?tica como par?metro para que cuando 
99
        //volvamos a abrir el dialogo pueda recuperarse y seleccionarse en el cuadro
100
        pancrName = files[posPancromatica].getName().substring(
101
                                        files[posPancromatica].getName().lastIndexOf("/")+1, 
102
                                        files[posPancromatica].getName().length());
103
        this.addParam("pancrName", pancrName);
104
       
105
        height = image.getHeight(null);
106
        width = image.getWidth(null);
107
        heightPancr = files[posPancromatica].getHeight();
108
        widthPancr = files[posPancromatica].getWidth();
109
        for(int i=0;i<files.length;i++){
110
                if(i != posPancromatica){
111
                        heightMultiespec = files[i].getHeight(); 
112
                        widthMultiespec = files[i].getWidth();
113
                }
114
        }
115
        
116
        relX = (int)widthPancr/widthMultiespec;
117
                relY = (int)heightPancr/heightMultiespec;
118
    }
119
    
120
    /* (non-Javadoc)
121
     * @see org.cresques.io.raster.IRasterFilter#pre()
122
     */
123
    public void pre() {
124
            
125
            loadParam();
126
            checkInput();
127
            
128
        //Creamos el buffer donde se pinta la pancromatica
129
        
130
            imagePancr = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
131
        Graphics2D graphicsPancr = (Graphics2D)imagePancr.getGraphics();
132
                PxRaster rasterPancr = new PxRaster(files[posPancromatica], null, files[posPancromatica].getView());
133
                                                
134
                rasterPancr.setBand(GeoRasterFile.RED_BAND, 0);
135
                rasterPancr.setBand(GeoRasterFile.GREEN_BAND, 1);
136
                rasterPancr.setBand(GeoRasterFile.BLUE_BAND, 2);
137
                
138
                ViewPortData vp = (ViewPortData)viewPortData.clone();
139
                vp.zoom(extent);
140
                rasterPancr.draw(graphicsPancr, vp);
141
                rasterPancr = null;
142
                
143
                //Creamos el buffer donde se pinta la imagen de entrada
144
                
145
                imageMultiespec = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
146
            Graphics2D graphicsMultiespec = (Graphics2D)imageMultiespec.getGraphics();
147
                PxRaster rasterMultiespec = null;
148
                boolean first = true;
149
                for(int i = 0;i<files.length;i++){        
150
                  if(first){
151
                        rasterMultiespec = new PxRaster(files[i], null, files[posPancromatica].getView());
152
                        first = false;
153
                  }else
154
                           rasterMultiespec.addFile(files[i].getName());
155
                }
156
                
157
                rasterMultiespec.setBand(GeoRasterFile.RED_BAND, bandOrder[0]);
158
                rasterMultiespec.setBand(GeoRasterFile.GREEN_BAND, bandOrder[1]);
159
                rasterMultiespec.setBand(GeoRasterFile.BLUE_BAND, bandOrder[2]);
160
                                                        
161
                rasterMultiespec.draw(graphicsMultiespec, vp);
162
                rasterMultiespec = null;
163
                
164
        super.pre();
165
    }
166

    
167
    /**
168
     * Aplica la operaci?n de refinamiento sobre el buffer Multiespectral que contiene 
169
     * el RGB que es pasado por par?metro utilizando la pancrom?tica.
170
     * @param bufferInput        Buffer rgb 
171
     * @param length                longitud del buffer de la pancromatica utilizado
172
     * @param iLine                        l?nea leida de la imagen multiespectral
173
     * @return                                buffer con el resultado de la operaci?n
174
     */
175
    private int[] processBrovey(int[] bufferInput, int iLine){            
176
            double[]                hsl;
177
            int[]                        rgb;            
178
            PixelGrabber         pg = null;
179
            
180
            //Longitud del buffer de salida
181
            int                         widthDst = width * relX;
182
            //Buffer de salida
183
            int[]                        bufferPancr = new int[width];
184

    
185
            pg = new PixelGrabber(imagePancr, 0, iLine, width, 1, bufferPancr , 0, width);
186

    
187
            
188
            try {
189
            pg.grabPixels();
190
        } catch (InterruptedException e) {
191
            e.printStackTrace();
192
        }
193
   
194
        for(int iElem=0; iElem<width; iElem++){
195
                    int r = ((bufferInput[iElem] >> 16) & 0xff);
196
                        int g = ((bufferInput[iElem] >> 8) & 0xff);
197
                        int b = (bufferInput[iElem] & 0xff);
198
                        byte i = (byte)((bufferPancr[iElem] >> 16) & 0xff);
199
                        double scale = (3.0*(i+coefBrovey))/(r+g+b+1.0);
200
                        r *= scale;g *= scale;b *= scale;                        
201
                        bufferPancr[iElem] = ((alpha << 24) & 0xff000000) | 
202
                                                                ((r << 16) & 0x00ff0000)| 
203
                                                                ((g << 8) & 0x0000ff00) | 
204
                                                                (b & 0x000000ff);
205
            }
206
            return bufferPancr;
207
            
208
    }
209
    
210
    /**
211
     * Aplica la operaci?n de refinamiento sobre el buffer Multiespectral que contiene 
212
     * el RGB que es pasado por par?metro utilizando la pancrom?tica.
213
     * @param bufferInput        Buffer rgb 
214
     * @param length                longitud del buffer de la pancromatica utilizado
215
     * @param iLine                        l?nea leida de la imagen multiespectral
216
     * @return                                buffer con el resultado de la operaci?n
217
     */
218
    private int[] processKernel(int[] bufferInput, int iLine){            
219
            int[]                        bufferDst = new int[width];
220
                        
221
            if(iLine != 0){
222
                    bufferPrev = bufferAct;
223
                    bufferAct = bufferNext;
224
            }else{
225
                    bufferPrev = null;
226
                    bufferAct = new int[width];
227
                    pgAct = new PixelGrabber(imagePancr, 0, iLine, width, 1, bufferAct , 0, width);
228
                    try {
229
                pgAct.grabPixels();
230
            } catch (InterruptedException e) {e.printStackTrace();}
231
            }
232
                        
233
            if(iLine != (height - 1)){
234
                    bufferNext = new int[width];
235
                    pgNext = new PixelGrabber(imagePancr, 0, iLine + 1, width, 1, bufferNext , 0, width);
236
                    try {
237
                pgNext.grabPixels();
238
            } catch (InterruptedException e) {e.printStackTrace();}
239
            }else
240
                    bufferNext = null;
241
                    
242

    
243
            for(int iElem=0; iElem<width; iElem++){
244
                    int a = ((bufferInput[iElem] >> 24) & 0xff);
245
                    int r = ((bufferInput[iElem] >> 16) & 0xff);
246
                        int g = ((bufferInput[iElem] >> 8) & 0xff);
247
                        int b = (bufferInput[iElem] & 0xff);
248

    
249
                        float[][] op = new float[3][3];
250
                        if(bufferPrev != null){
251
                                if(iElem != 0)op[0][0] = (bufferPrev[iElem - 1] & 0x000000ff);
252
                                op[0][1] = (bufferPrev[iElem] & 0x000000ff);
253
                                if(iElem != (width -1))op[0][2] = (bufferPrev[iElem + 1] & 0x000000ff);
254
                        }
255
                        if(iElem != 0)op[1][0] = (bufferAct[iElem - 1] & 0x000000ff);
256
                        op[1][1] = (bufferAct[iElem] & 0x000000ff);
257
                        if(iElem != (width -1))op[1][2] = (bufferAct[iElem + 1] & 0x000000ff);
258
                        if(bufferNext != null){
259
                                if(iElem != 0)op[2][0] = (bufferNext[iElem - 1] & 0x000000ff); 
260
                                op[2][1] = (bufferNext[iElem] & 0x000000ff);
261
                                if(iElem != (width -1))op[2][2] = (bufferNext[iElem + 1] & 0x000000ff);
262
                        }
263
                        Kernel operando = new Kernel(op);
264
                        double i = kernel.kernelOperation(operando) * 0.15;
265
                        r += i;
266
                        g += i;
267
                        b += i;
268
                        bufferDst[iElem] = ((a << 24) & 0xff000000) | 
269
                                                                ((r << 16) & 0x00ff0000)| 
270
                                                                ((g << 8) & 0x0000ff00) | 
271
                                                                (b & 0x000000ff);        
272
            }
273
            return bufferDst;
274
            
275
    }
276
    
277
    /**
278
     * Aplica la operaci?n de refinamiento sobre el buffer Multiespectral que contiene 
279
     * el RGB que es pasado por par?metro utilizando la pancrom?tica.
280
     * @param bufferInput        Buffer rgb 
281
     * @param length                longitud del buffer de la pancromatica utilizado
282
     * @param iLine                        l?nea leida de la imagen multiespectral
283
     * @return                                buffer con el resultado de la operaci?n
284
     */
285
    private int[] processIHS(int[] bufferInput, int iLine){            
286
            double[]                hsl;
287
            int[]                        rgb;
288
            PixelGrabber         pg = null;
289

    
290
            //Buffer de salida
291
            int[]                        bufferPancr = new int[width];
292

    
293
            pg = new PixelGrabber(imagePancr, 0, iLine, width, 1, bufferPancr , 0, width);
294

    
295
            try {
296
            pg.grabPixels();
297
        } catch (InterruptedException e) {
298
            e.printStackTrace();
299
        }
300

    
301
        int[] uvw , tmp = new int[3];
302
        double[] xyz;
303
            for(int iElem=0; iElem<width; iElem++){
304
                    xyz = ColorSpaceConversion.RGBtoHSL( (bufferInput[iElem] >> 16) & 0x000000ff,
305
                                                                                             (bufferInput[iElem] >> 8) & 0x000000ff,
306
                                                                                             bufferInput[iElem] & 0x000000ff);
307

    
308
                    xyz[2] = ((bufferPancr[iElem] & 0x000000ff)/255.0) + coef;
309
                    
310
                    tmp[0] = (int)(255.0 * xyz[0] / 360.0 + 0.5);
311
                        tmp[2] = (int) (xyz[2]*255. + 0.5);
312
                        tmp[1] = (int) (xyz[1]*255. + 0.5);
313
                        
314
                    uvw = ColorSpaceConversion.HSLtoRGB(tmp[ColorSpaceConversion.H],
315
                                                                                            tmp[ColorSpaceConversion.S],
316
                                                                                            tmp[ColorSpaceConversion.L]);
317
                    bufferPancr[iElem] = ((alpha << 24) & 0xff000000) |
318
                                                                ((uvw[0] << 16) & 0x00ff0000)|
319
                                                                ((uvw[1] << 8) & 0x0000ff00) |
320
                                                                (uvw[2] & 0x000000ff);
321
            }
322
            return bufferPancr;
323
            
324
    }
325
        
326
    /**
327
     * Aplica el filtro sobre el raster pasado pixel a pixel
328
     */
329
    public void execute() {
330
        pre();
331
        if (exec) {                    
332
                int[]                         pRGBArrayMultiesp = new int[width];
333
                int[]                         pRGBArrayPancr = null;
334
                PixelGrabber        pg = null;
335
                int                         widthDst = width * relX;
336
                
337
                //Para cada linea leemos los valores RGB del image. Aplicamos el algoritmo
338
                //y escribimos el resultado.
339
                
340
                if(method.equals("hsl")){
341
                        float[][]        k = {{-1F, -1F, -1F},{-1F, 8F, -1F},{-1F, -1F, -1F}};
342
                        kernel = new Kernel(k);
343
                        for(int iLine=0;iLine<height ;iLine++){
344
                                    pg = new PixelGrabber(imageMultiespec, 0, iLine, width, 1, pRGBArrayMultiesp, 0, width);
345
                                    try {
346
                                pg.grabPixels();
347
                            } catch (InterruptedException e) {e.printStackTrace();}    
348
                            pRGBArrayPancr = processIHS(pRGBArrayMultiesp, iLine);                            
349
                                    ((BufferedImage)imagePancr).setRGB(0, iLine, width, 1, pRGBArrayPancr, 0, width);
350
                            }
351
                }else{
352
                            for(int iLine=0;iLine<height ;iLine++){
353
                                    pg = new PixelGrabber(imageMultiespec, 0, iLine, width, 1, pRGBArrayMultiesp, 0, width);
354
                                    try {
355
                                pg.grabPixels();
356
                            } catch (InterruptedException e) {e.printStackTrace();}    
357
                            pRGBArrayPancr = processBrovey(pRGBArrayMultiesp, iLine);                            
358
                                    ((BufferedImage)imagePancr).setRGB(0, iLine, width, 1, pRGBArrayPancr, 0, width);
359
                            }
360
                }
361
        }
362
        
363
        post();
364
    }
365

    
366
    /* (non-Javadoc)
367
     * @see org.cresques.io.raster.IRasterFilter#process(int, int)
368
     */
369
    public void process(int x, int y) {
370

    
371
    }
372

    
373
    /* (non-Javadoc)
374
     * @see org.cresques.io.raster.IRasterFilter#getInRasterDataType()
375
     */
376
    public int getInRasterDataType() {
377
        return RasterBuf.TYPE_IMAGE;
378
    }
379

    
380
    /* (non-Javadoc)
381
     * @see org.cresques.io.raster.IRasterFilter#getOutRasterDataType()
382
     */
383
    public int getOutRasterDataType() {
384
        return RasterBuf.TYPE_IMAGE;
385
    }
386

    
387
    /* (non-Javadoc)
388
     * @see org.cresques.io.raster.IRasterFilter#getResult(java.lang.String)
389
     */
390
    public Object getResult(String name) {
391
        if (name.equals("raster")) {
392
            return (Object) this.imagePancr;
393
        } else {
394
            return null;
395
        }
396
    }
397

    
398
    /* (non-Javadoc)
399
     * @see org.cresques.io.raster.RasterFilter#processLine(int)
400
     */
401
    public void processLine(int y) {
402
    }
403

    
404
    /* (non-Javadoc)
405
     * @see org.cresques.io.raster.IRasterFilter#post()
406
     */
407
    public void post() {
408
    }
409
}
410