Statistics
| Revision:

root / trunk / libraries / libCq_CMS_praster / src / org / cresques / io / datastruct / Histogram.java @ 8026

History | View | Annotate | Download (19.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.datastruct;
25

    
26
import java.awt.geom.Point2D;
27
import java.awt.geom.Rectangle2D;
28
import java.awt.image.BufferedImage;
29
import java.io.File;
30
import java.io.FileInputStream;
31
import java.io.FileNotFoundException;
32
import java.io.IOException;
33
import java.io.Writer;
34

    
35
import org.cresques.io.data.Grid;
36
import org.cresques.io.data.RasterBuf;
37
import org.cresques.px.Extent;
38
import org.cresques.px.PxRaster;
39
import org.cresques.util.Utilities;
40
import org.kxml2.io.KXmlParser;
41
import org.xmlpull.v1.XmlPullParserException;
42

    
43

    
44
/**
45
 * Clase para la gesti?n de histogramas de un raster. Es la encargada del calculo de un histograma
46
 * total o parcial de un raster a partir de los datos de disco. Este calculo se hace leyendo los
47
 * datos por bloques para no cargarlo completamente en memoria. Adem?s tambi?n es la encargada de gestionar
48
 * salvar este histograma a .rmf. En caso de que solicite un histograma del raster completo este ir?
49
 * a buscarlo al fichero rmf asociado antes de calcularlo por si ya existise. Al realizar el calculo
50
 * del histograma de la imagen completa este ser? salvado en el fichero .rmf asociado al raster.
51
 * 
52
 * @author Nacho Brodin (brodin_ign@gva.es)
53
 */
54
public class Histogram extends Thread{
55
        
56
        /**
57
         * Tama?o del bloque de calculo de histograma. La lectura del raster se divide en partes
58
         * de BLOCK de altura para no cargar todo el raster en memoria de una vez.
59
         */
60
        private static final int                        BLOCK = 512;
61
        private Grid                                                 grid = null;
62

    
63
        /**
64
         * Flag que dice si el histograma a calcualar es el seleccionado en el area de interes
65
         * o el histograma completo.
66
         */ 
67
        private boolean                                         calcFullHistogram = true;
68
        /**
69
         * Histograma de la imagen completa
70
         */
71
        private int[][]                                                histogram = null;
72
        /**
73
         * Histograma acumulado de la imagen completa
74
         */
75
        private int[][]                                                accumulatedHistogram = null;
76
        /**
77
         * Variables que definen una ?rea de interes
78
         */
79
        private int                                                 xAOI, yAOI, widthAOI, heightAOI;
80
        /**
81
         * Porcentaje que lleva construido el histograma
82
         */
83
        private int                                                        percent = 0;
84
        /**
85
         * Variable que estar? a true si el histograma esta siendo leido desde fichero .rmf y false
86
         * si ha sido calculado. En este ?ltimo caso se salvar? a disco una vez termine de ser calculado
87
         */
88
        private boolean[]                                        isReadingFromRMF = null;
89
        /**
90
         * Renderizador para el calculo de histogramas a partir 
91
         * de la visualizaci?n.
92
         */
93
        private PxRaster                                        pxRaster = null;
94
        /**
95
         * Histograma de la vista
96
         */
97
        private int[][]                                                viewHistogram = null;
98
        /**
99
         * Bandas que solicita el cliente. Cada elemento del array es una banda, si est? a true se devuelve 
100
         * esa banda con histograma calculado y si est? a false se devolver? esa banda con el histograma a 0.
101
         * Este array solo es ten?do en cuenta para el histograma con fuente de datos reales y no para el de
102
         * la visualizaci?n.
103
         */
104
        private boolean[]                                        showBands = {true, true, true};
105
        /**
106
         * Writer para modificar o crear los archivos .rmf.
107
         */
108
        private Writer                                                writer = null;
109
        /**
110
         * Herramientas para la persistencia del histograma;
111
         */
112
        private HistogramPersistence                                tools = null;
113
        /**
114
         * Constructor 
115
         * @param grid
116
         */
117
        public Histogram(Grid grid){
118
                addGrid(grid);
119
        }
120
        
121
        /**
122
         * Sustituye el grid del histograma 
123
         * @param grid
124
         */
125
        public void addGrid(Grid grid){
126
                this.grid = grid;
127
                isReadingFromRMF = new boolean[grid.getBandCount()];
128
        }
129

    
130
        /**
131
         * Obtiene el grid asociado al histograma
132
         * @return Grid
133
         */
134
        public Grid getGrid() {
135
                return grid;
136
        }
137
        
138
        /**
139
         * Obtiene el renderizador asociado al histograma
140
         * @return PxRaster
141
         */
142
        public PxRaster getRenderizer() {
143
                return pxRaster;
144
        }
145
        
146
        /**
147
         * Asigna el renderizador para el calculo de histogramas a partir 
148
         * de la visualizaci?n.
149
         * @param pxR Renderizador.
150
         */
151
        public void addRenderizer(PxRaster pxR){
152
                this.pxRaster = pxR;
153
        }
154
        
155
        /**
156
         * Asigna un area de interes para el calculo de histograma
157
         * @param x Posici?n X del area de interes
158
         * @param y Posici?n Y del area de interes
159
         * @param w Ancho del ?rea de interes
160
         * @param h Alto del ?rea de interes
161
         */
162
        public void setAreaOfInterest(int x, int y, int w, int h){
163
                this.xAOI = x;
164
                this.yAOI = y;
165
                this.widthAOI = w;
166
                this.heightAOI = h;
167
        }
168
        
169
        /**
170
         * Obtiene el histograma de la imagen completa en caso de que este ya haya sido
171
         * calculado. Si histogram es null habr? que llamar a la funci?n calcFullHistogram para
172
         * calcularlo.
173
         * @return histograma de la imagen completa
174
         */
175
        public int[][] getFullHistogram(){
176
                return histogram;
177
        }
178
        
179
        /**
180
         * Obtiene el histograma acumulado de la imagen completa en caso de que este ya haya sido
181
         * calculado. Si histogram es null habr? que llamar a la funci?n calcFullAccumulatedHistogram para
182
         * calcularlo.
183
         * @return histograma acumulado de la imagen completa
184
         */
185
        public int[][] getFullAccumulatedHistogram(){
186
                histogram = null;
187
                histogram = readFullHistogramFromRMF();
188
                
189
                return accumulatedHistogram;
190
        }
191
        
192
        /**
193
         * Obtiene el histograma desde el fichero RMF si tiene
194
         * @return 
195
         */
196
        private int[][] readFullHistogramFromRMF(){
197
                String fName = null;
198
                String values = null;
199
                String[] vect = null;
200
                File fl = null;
201
                KXmlParser parser = new KXmlParser();
202
                int [][] hist = null;
203
                int index = 0;
204
                boolean end = false;
205
                boolean exists = false;
206
                
207
                hist = new int [grid.getGeoRasterMultiFile().getBandCount()][256];
208
                try{
209
                        for(int i = 0 ; i < grid.getGeoRasterMultiFile().getFileCount() ; i++){
210
                                fName = grid.getGeoRasterMultiFile().getFile(i).getName();
211
                                fl = new File(fName.substring(0, fName.lastIndexOf(".") + 1) + "rmf");
212
                                exists = false;
213
                                if (!fl.exists())
214
                                        return null;
215
                                else{
216
                                        parser.setInput(new FileInputStream(fl.getPath()), null);
217
                                        int tag = parser.next();
218
                                        parser.require(parser.START_TAG, null, "RasterMetaFile");
219
                                        tag = parser.next();
220
                                        end = false;
221
                                        while(!end){
222
                                                switch(tag){
223
                                                case KXmlParser.TEXT:
224
                                                        tag = parser.next();
225
                                                        break;
226
                                                case KXmlParser.START_TAG:
227
                                                        if (parser.getName().equals("Band")){
228
                                                                parser.require(KXmlParser.START_TAG, null, "Band");
229
                                                                parser.nextTag();
230
                                                                parser.require(KXmlParser.START_TAG, null, "Values");
231
                                                                values = parser.nextText();
232
                                                                parser.require(KXmlParser.END_TAG, null, "Values");
233
                                                                tag = parser.nextTag();
234
                                                                parser.require(KXmlParser.END_TAG, null, "Band");
235
                                                                
236
                                                                exists = true;
237
                                                                vect = new String[256];
238
                                                                vect = values.split(" ");
239
                                                                
240
                                                                for(int j = 0 ; j < 256 ; j++){
241
                                                                        if (showBands[index])
242
                                                                                hist[index][j] = Integer.valueOf(vect[j]).intValue();
243
                                                                        else
244
                                                                                hist[index][j] = 0;
245
                                                                }
246
                                                                        
247
                                                                index++;
248
                                                        }
249
                                                        tag = parser.next();
250
                                                        break;
251
                                                case KXmlParser.END_TAG:
252
                                                        if(parser.getName().equals("RasterMetaFile"))
253
                                                                end = true;
254
                                                        tag = parser.next();
255
                                                        break;
256
                                                        
257
                                                default: 
258
                                                        tag = parser.next();
259
                                                }
260
                                        }
261
                                        if (!exists)
262
                                                return null;
263
                                }
264
                        }
265
                }catch(XmlPullParserException e){
266
                        return null;
267
                }catch(FileNotFoundException ex){
268
                        return null;
269
                }catch(IOException exc){
270
                        return null;
271
                }
272
                
273
                return hist;
274
                
275
        }
276
        
277
        /**
278
         * Obtiene el histograma desde el fichero RMF si tiene y calcula a partir de
279
         * este el acumulado
280
         * @return 
281
         */
282
        public int[][] readFullAccumulatedHistogramFromRMF(){
283
                //TODO: implementar readFullAccumulatedHistogramFromRMF()
284
                this.readFullHistogramFromRMF();
285
                //.....
286
                return null;
287
        }
288
        
289
        /**
290
         * Escribe el histograma en el fichero RMF de disco asociado al raster. Esta escritura
291
         * solo se realiza si no se ha leido de RMF
292
         */
293
        public void writeFullHistogramToRMF() throws IOException{
294
                File rmfFile = null;
295
                String grfName = null;
296
                tools = new HistogramPersistence();
297
                int[][] grfHistogram = null;
298
                
299
                //Cuando solo existe un GeoRasterFile en el Grid
300
                if (grid.getGeoRasterMultiFile().getFileCount() == 1)
301
                        if (!isReadingFromRMF[0]){
302
                                grfName = grid.getGeoRasterMultiFile().getFile(0).getName();
303
                                int grfBands = grid.getGeoRasterMultiFile().getFile(0).getBandCount();
304
                                tools.makeRMFHistogram(histogram, grfName, grfBands);                                
305
                        }
306
                
307
                //Si el Grid contiene mas de un GeoRasterFile
308
                if (grid.getGeoRasterMultiFile().getFileCount() > 1){
309
                        for (int i = 0; i < grid.getGeoRasterMultiFile().getFileCount() ; i++){
310
                                int grfBands = grid.getGeoRasterMultiFile().getFile(i).getBandCount();
311
                                int grfCount = 0;
312
                                grfName = grid.getGeoRasterMultiFile().getFile(i).getName();
313
                                boolean isReading = false;
314
                                grfHistogram = new int[grfBands][256];
315
                                for (int j = 0 ; j < grid.getBandCount() ; j++){
316
                                        if (grid.getGeoRasterMultiFile().getBands().getBandStringList()[j].equals(grfName)){
317
                                                grfHistogram[grfCount] = histogram[j];
318
                                                grfCount++;
319
                                                //if(isReadingFromRMF[j])
320
                                                        //isReading = true;
321
                                                }
322
                                }
323
                                if (!isReading)
324
                                        tools.makeRMFHistogram(grfHistogram, grfName, grfBands);
325
                        }
326
                }
327
        }
328
        
329
        /**
330
         * Calcula el histograma de la imagen completa.
331
         */
332
        public synchronized void run(){
333
                while(true){
334
                        //Asignamos las bandas que van a dibujarse
335
                        int[] drawableBands = new int[grid.getBandCount()];
336
                        for(int i = 0; i < grid.getBandCount(); i++)
337
                                drawableBands[i] = i;
338
                        grid.clearDrawableBand();
339
                        grid.addDrawableBands(drawableBands);
340
                        
341
                        int heightArea = grid.getHeight();
342
                        int widthArea = grid.getWidth();
343
                        int poxInitX = 0;
344
                        int lastY = 0;
345
                        if(!calcFullHistogram){ //Calculo del histograma en el ?rea de interes
346
                                heightArea = heightAOI;
347
                                widthArea = widthAOI;
348
                                poxInitX = xAOI;
349
                                lastY = yAOI;
350
                        }
351
                        
352
                        //Calculamos bloques de tama?o BLOCK para no leer toda la imagen de golpe
353
                        int nBlocks = (int)(heightArea / BLOCK);
354
                        int lastBlock = heightArea - (nBlocks * BLOCK);
355
                        int incrPercent = (int)(100 / (nBlocks + 1));
356
        
357
                        switch(grid.getDataType()){
358
                        case RasterBuf.TYPE_BYTE: byteHistogram(poxInitX, lastY, widthArea, nBlocks, lastBlock, incrPercent); break;
359
                        case RasterBuf.TYPE_SHORT: shortHistogram(poxInitX, lastY, widthArea, nBlocks, lastBlock, incrPercent); break;
360
                        case RasterBuf.TYPE_INT: intHistogram(poxInitX, lastY, widthArea, nBlocks, lastBlock, incrPercent); break;
361
                        }
362
                        percent = 100;
363
                        
364
                        //Si hemos calculado el histograma de la imagen completa lo salvamos a disco
365
                        if(calcFullHistogram)
366
                                try{
367
                                        writeFullHistogramToRMF();
368
                                }catch(IOException ex){
369
                                        System.err.println("No se ha podido guardar el histograma");
370
                                }
371
                        grid.free();
372
                        this.suspend();
373
                }
374
        }
375

    
376
        /**
377
         * Calcula el histograma para tipo de datos byte
378
         * @param nBlocks N?mero de bloques 
379
         * @param lastBlock Tama?o del ?ltimo bloque
380
         * @param lastY posici?n Y donde empieza el primer bloque 
381
         */
382
        private void byteHistogram(int x, int lastY, int widthArea, int nBlocks, int lastBlock, int incrPercent){
383
                histogram = new int[grid.getBandCount()][Utilities.MAX_BYTE_BIT_VALUE + 1];
384
                for(int nBlock = 0; nBlock < nBlocks; nBlock++){
385
                        grid.setAreaOfInterest(x, lastY, widthArea, BLOCK);
386
                        RasterBuf raster = grid.getRasterBuf();
387
                        for(int iBand = 0; iBand < grid.getBandCount(); iBand ++)
388
                                for(int line = 0; line < BLOCK; line ++)
389
                                        for(int col = 0; col < widthArea; col ++)
390
                                                histogram[iBand][(raster.getElemByte(line, col, iBand) & 0xff)]++;
391
                        lastY += BLOCK;
392
                        percent += incrPercent;
393
                }
394
                grid.setAreaOfInterest(x, lastY, widthArea, lastBlock);
395
                RasterBuf raster = grid.getRasterBuf();
396
                for(int iBand = 0; iBand < grid.getBandCount(); iBand ++)
397
                        for(int line = 0; line < lastBlock; line ++)
398
                                for(int col = 0; col < widthArea; col ++)
399
                                        histogram[iBand][(raster.getElemByte(line, col, iBand) & 0xff)]++;        
400
                
401
                accumulateAllDataTypes(Utilities.MAX_BYTE_BIT_VALUE + 1);
402
        }
403
        
404
        /**
405
         * Calcula el histograma para tipo de datos short
406
         * @param nBlocks N?mero de bloques 
407
         * @param lastBlock Tama?o del ?ltimo bloque
408
         * @param lastY posici?n Y donde empieza el primer bloque 
409
         */
410
        private void shortHistogram(int x, int lastY, int widthArea, int nBlocks, int lastBlock, int incrPercent){
411
                histogram = new int[grid.getBandCount()][Utilities.MAX_SHORT_BIT_VALUE + 1];
412
                for(int nBlock = 0; nBlock < nBlocks; nBlock++){
413
                        grid.setAreaOfInterest(x, lastY, widthArea, BLOCK);
414
                        RasterBuf raster = grid.getRasterBuf();
415
                        for(int iBand = 0; iBand < grid.getBandCount(); iBand ++)
416
                                for(int line = 0; line < BLOCK; line ++)
417
                                        for(int col = 0; col < widthArea; col ++)
418
                                                histogram[iBand][(raster.getElemShort(line, col, iBand) & 0xffff)]++;
419
                        lastY += BLOCK;
420
                        percent += incrPercent;
421
                }
422
                grid.setAreaOfInterest(x, lastY, widthArea, lastBlock);
423
                RasterBuf raster = grid.getRasterBuf();
424
                for(int iBand = 0; iBand < grid.getBandCount(); iBand ++)
425
                        for(int line = 0; line < lastBlock; line ++)
426
                                for(int col = 0; col < widthArea; col ++)
427
                                        histogram[iBand][(raster.getElemShort(line, col, iBand) & 0xffff)]++;        
428
                
429
                accumulateAllDataTypes(Utilities.MAX_SHORT_BIT_VALUE + 1);
430
        }
431
        
432
        /**
433
         * Calcula el histograma para tipo de datos short
434
         * @param nBlocks N?mero de bloques 
435
         * @param lastBlock Tama?o del ?ltimo bloque
436
         * @param lastY posici?n Y donde empieza el primer bloque 
437
         */
438
        private void intHistogram(int x, int lastY, int widthArea, int nBlocks, int lastBlock, int incrPercent){
439
                histogram = new int[grid.getBandCount()][Utilities.MAX_SHORT_BIT_VALUE + 1];
440
                for(int nBlock = 0; nBlock < nBlocks; nBlock++){
441
                        grid.setAreaOfInterest(x, lastY, widthArea, BLOCK);
442
                        RasterBuf raster = grid.getRasterBuf();
443
                        for(int iBand = 0; iBand < grid.getBandCount(); iBand ++)
444
                                for(int line = 0; line < BLOCK; line ++)
445
                                        for(int col = 0; col < widthArea; col ++)
446
                                                histogram[iBand][(raster.getElemInt(line, col, iBand) & 0xffff)]++;
447
                        lastY += BLOCK;
448
                        percent += incrPercent;
449
                }
450
                grid.setAreaOfInterest(x, lastY, widthArea, lastBlock);
451
                RasterBuf raster = grid.getRasterBuf();
452
                for(int iBand = 0; iBand < grid.getBandCount(); iBand ++)
453
                        for(int line = 0; line < lastBlock; line ++)
454
                                for(int col = 0; col < widthArea; col ++)
455
                                        histogram[iBand][(raster.getElemInt(line, col, iBand) & 0xffff)]++;        
456
                
457
                accumulateAllDataTypes(Utilities.MAX_SHORT_BIT_VALUE + 1);
458
        }
459
        
460
        /**
461
         * Calcula el histograma acumulado a partir del normal ya calculado. Esta llamada es usada para
462
         * el histograma a partir de la fuente de datos. Adem?s de calcular el acumulado elimina las
463
         * bandas que no se han pedido
464
         * @param nValues N?mero de valores del histograma
465
         */
466
        private void accumulateAllDataTypes(int nValues){
467
                //Acumulado, adem?s eliminamos bandas que no se han pedido
468
                accumulatedHistogram = new int[grid.getBandCount()][nValues];
469
                for(int iBand = 0; iBand < accumulatedHistogram.length; iBand++){
470
                        if(showBands[iBand])
471
                                accumulatedHistogram[iBand][0] = histogram[iBand][0];
472
                        else
473
                                histogram[iBand][0] = 0;
474
                        for(int i = 1; i < accumulatedHistogram[iBand].length; i++){
475
                                if(showBands[iBand])
476
                                        accumulatedHistogram[iBand][i] = histogram[iBand][i] + accumulatedHistogram[iBand][i - 1];
477
                                else
478
                                        histogram[iBand][i] = 0;
479
                        }
480
                }
481
                
482
        }
483
        
484
        /**
485
         * Obtiene el porcentaje que lleva construido el histograma
486
         * @return porcentaje de construcci?n
487
         */
488
        public int getPercent() {
489
                return percent;
490
        }
491
        
492
        /**
493
         * calcula el histograma de la imagen completa. En caso de que exista un fichero RMF con 
494
         * el histograma calculado se leer? de all?.
495
         */
496
        public void calcFullHistogram(boolean[] bands){
497
                percent = 0;
498
                showBands = bands;
499
                calcFullHistogram = true;
500
                histogram = null;
501
                histogram = readFullHistogramFromRMF();
502
                if(histogram == null){
503
                        if(this.isAlive())
504
                                resume();
505
                        else
506
                                start();
507
                }else
508
                        percent = 100;
509
        }
510
        
511
        /**
512
         * calcula el histograma acumulado de la imagen completa. En caso de que exista un fichero RMF con 
513
         * el histograma calculado se leer? de all?.
514
         */
515
        public void calcFullAccumulatedHistogram(boolean[] bands){
516
                percent = 0;
517
                showBands = bands;
518
                calcFullHistogram = true;
519
                histogram = null;
520
                histogram = readFullAccumulatedHistogramFromRMF();
521
                if(histogram == null){
522
                        if(this.isAlive())
523
                                resume();
524
                        else
525
                                start();
526
                }else{
527
                        
528
                        percent = 100;
529
                }
530
        }
531
        
532
        /**
533
         * Calcula el histograma de la imagen correspondiente al ?rea de interes. Antes de llamar a esta funci?n 
534
         * hay que asignar el ?rea de interes
535
         */
536
        public void calcHistogramFromLimetedArea(boolean[] bands){
537
                percent = 0;
538
                showBands = bands;
539
                calcFullHistogram = false;
540
                if(this.isAlive())
541
                        resume();
542
                else
543
                        start();
544
        }
545
        
546
        /**
547
         * Calcula el histograma de la imagen correspondiente al ?rea de interes. Este ?rea de interes es
548
         * es obtenida del extent del renderizador. 
549
         */
550
        public boolean calcHistogramFromRenderizerLimetedArea(boolean[] bands){
551
                percent = 0;
552
                showBands = bands;
553
                calcFullHistogram = false;
554
                Extent fullExtent = pxRaster.getExtent();
555
                Extent wcArea = new Extent(pxRaster.getLastViewPort().getExtent());
556
                
557
                if(        wcArea.getMax().getX() < fullExtent.getMin().getX() ||
558
                                wcArea.getMin().getX() > fullExtent.getMax().getX() ||        
559
                                wcArea.getMax().getY() < fullExtent.getMin().getY() ||
560
                                wcArea.getMin().getY() > fullExtent.getMax().getY() ){
561
                        histogram = new int[grid.getBandCount()][Utilities.MAX_BYTE_BIT_VALUE + 1];
562
                        accumulatedHistogram = new int[grid.getBandCount()][Utilities.MAX_BYTE_BIT_VALUE + 1];
563
                        return false;
564
                }
565
                wcArea = Utilities.calculateAdjustedView(wcArea, fullExtent);
566
                
567
                Rectangle2D pxArea = Utilities.getPxRectFromMapRect(pxRaster.getFiles()[0].getExtent().toRectangle2D(), pxRaster.getFiles()[0].getWidth(), pxRaster.getFiles()[0].getHeight(), wcArea.toRectangle2D());
568
                setAreaOfInterest((int)pxArea.getMinX(), (int)pxArea.getMinY(), (int)Math.abs(pxArea.getMaxX() - pxArea.getMinX()), (int)Math.abs(pxArea.getMaxY() - pxArea.getMinY()));
569
                if(this.isAlive())
570
                        resume();
571
                else
572
                        start();
573
                return true;
574
        }
575
        
576
        /**
577
         * Calcula el histograma de la vista y solo con los datos de visualizaci?n
578
         * @return Histograma en forma de array bidimensional de enteros en el que el 
579
         * el primer indice es el n?mero de bandas y el segundo el histograma por banda
580
         */
581
        public int[][] calcHistogramFromView(boolean[] bands){
582
                viewHistogram = new int[3][256];
583
                if(pxRaster != null){
584
                        BufferedImage img = (BufferedImage)pxRaster.getGeoImage();
585
                        if(img !=null)
586
                                for(int col = 0; col < img.getHeight(); col++){
587
                                        for(int line = 0; line < img.getWidth(); line++){
588
                                                int px = ((BufferedImage) img).getRGB(line, col);
589
                                                int px3[] = {(px & 0xff0000) >> 16, (px & 0xff00) >> 8, (px & 0xff)};
590
                                                if(bands[0])
591
                                                        viewHistogram[0][px3[0]] ++;                  //Histograma para la banda R
592
                                                if(bands[1])
593
                                                        viewHistogram[1][px3[1]] ++;                  //Histograma para la banda G
594
                                                if(bands[2])
595
                                                        viewHistogram[2][px3[2]] ++;                  //Histograma para la banda B
596
                                        }
597
                                }
598
                }
599
                return viewHistogram;
600
        }
601
                
602
        /**
603
         * Calcula el histograma de la vista acumulado y solo con los datos de visualizaci?n
604
         * @return Histograma en forma de array bidimensional de enteros en el que el 
605
         * el primer indice es el n?mero de bandas y el segundo el histograma por banda
606
         */
607
        public int[][] calcAccumulatedHistogramFromView(boolean[] bands){
608
                viewHistogram = calcHistogramFromView(bands);
609
                for(int iBand = 0; iBand < viewHistogram.length; iBand++){
610
                        for(int i = 1; i < viewHistogram[iBand].length; i++){
611
                                viewHistogram[iBand][i] += viewHistogram[iBand][i - 1];
612
                        }
613
                }
614
                return viewHistogram;
615
        }
616
        
617
}