Statistics
| Revision:

svn-gvsig-desktop / tags / Root_v06 / libraries / libCq CMS for java.old / src / org / cresques / io / raster / SharpeningImageFilter.java @ 4811

History | View | Annotate | Download (13.8 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.cresques.io.raster;
25

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

    
32
import org.cresques.geo.ViewPortData;
33
import org.cresques.io.GeoRasterFile;
34
import org.cresques.px.PxRaster;
35

    
36

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

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

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

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

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

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

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

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

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

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

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

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

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

    
370
    }
371

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

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

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

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

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