Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / util / Histogram.java @ 10980

History | View | Annotate | Download (8.36 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2007 IVER T.I. 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
package org.gvsig.raster.util;
20

    
21
/**
22
 * Representa un histograma.
23
 * @version 27/03/2007
24
 * @author Nacho Brodin (nachobrodin@gmail.com)
25
 *
26
 */
27
public class Histogram {
28
        private long[][] histogram = null;
29
        private static String[] types = {"normal", "accumulated", "logaritmic"};
30
        
31
        /**
32
         * Constructor
33
         */
34
        public Histogram() {
35
                histogram = new long[0][0];
36
        }
37
        
38
        /**
39
         * Constructor. Inicializa valores a cero
40
         * @param bands N?mero de bandas
41
         * @param pxs N?mero de valores o clases
42
         */
43
        public Histogram(int bands, int pxs) {
44
                histogram = new long[bands][pxs];
45
        }
46
        
47
        /**
48
         * Obtiene el histograma sin modificar
49
         * @return array bidimensional donde el primer elemento es el valor del pixel
50
         * o rango y el segundo el n?mero de elementos que aparecen.
51
         */
52
        public long[][] getHistogram() {
53
                return histogram;
54
        }
55
        
56
        /**
57
         * Obtiene el n?mero de bandas del histograma 
58
         * @return entero que representa el n?mero de bandas 
59
         */
60
        public int getNumBands() {
61
                if(histogram != null)
62
                        return histogram.length;
63
                return 0;
64
        }
65
        
66
        /**
67
         * Obtiene la longitud (n?mero de valores) de una banda determinada
68
         * @param band Banda o obtener la longitud
69
         * @return entero con la longitud de la banda
70
         */
71
        public int getBandLenght(int band) {
72
                if(histogram != null)
73
                        return histogram[band].length;
74
                return 0;
75
        }
76
        
77
        /**
78
         * Obtiene el n?mero de valores o clases del histograma
79
         * @return entero que representa el n?mero de valores o clases del histograma
80
         */
81
        public int getNumValues() {
82
                if(histogram != null)
83
                        return histogram[0].length;
84
                return 0;
85
        }
86
        
87
        /**
88
         * Asigna un histograma
89
         * @param hist histograma asignado
90
         */
91
        public void setHistogram(long[][] hist){
92
                histogram = hist;
93
        }
94
                
95
        /**
96
         * ASigna un valor para una posici?n del histograma
97
         * @param bands Valor del pixel o clase a asignar
98
         * @param px Valor del pixel
99
         * @param value Valor a asignar
100
         */
101
        public void setHistogramValue(int band, int px, long value) {
102
                if(histogram != null)
103
                        histogram[band][px] = value;
104
        }
105
        
106
        /**
107
         * Obtiene un valor del histograma
108
         * @param band N?mero de banda del valor a recuperar
109
         * @param px Pixel o valor de la clase del valor a recuperar
110
         * @return valor
111
         */
112
        public long getHistogramValue(int band, int px) {
113
                return histogram[band][px];
114
        }
115
        
116
        /**
117
         * Incrementa un valor de una posici?n del histograma
118
         * @param band N?mero de banda
119
         * @param px Pixel o valor de la clase
120
         */
121
        public void incrementPxValue(int band, int px) {
122
                histogram[band][px] ++;
123
        }
124
        
125
        /**
126
         * Devuelve el histograma acumulado
127
         * @return
128
         */
129
        public long[][] getAccumulatedHistogram() {
130
                if(histogram != null){
131
                        long[][] hist = new long[histogram.length][histogram[0].length];
132
                        for (int iBand = 0; iBand < hist.length; iBand++) {
133
                                for (int j = 0; j < hist[iBand].length; j++) {
134
                                        if(j == 0)
135
                                                hist[iBand][j] = histogram[iBand][j];
136
                                        else
137
                                                hist[iBand][j] += histogram[iBand][j - 1];         
138
                                }
139
                        }
140
                }
141
                return null;
142
        }
143
        
144
        /**
145
         * Devuelve el histograma acumulado
146
         * @return
147
         */
148
        public long[][] getLogaritmicHistogram() {
149
                //TODO: FUNCIONALIDAD: Falta el calculo del histograma logaritmico
150
                return histogram;
151
        }
152
        
153
        /**
154
         * N?mero de tipos de histograma definidos en esta clase.
155
         * @return entero con el n?mero de tipos definidos.
156
         */
157
        public static int getHistogramTypesCount(){
158
                return types.length;
159
        }
160
        
161
        /**
162
         * Obtiene un tipo de histograma a partir de su posici?n en el array
163
         * @param pos posici?n en el array del tipo a obtener
164
         * @return Tipo
165
         */
166
        public static String getType(int pos){
167
                return types[pos];
168
        }
169
        
170
        /**
171
         * Obtiene el histograma correspondiente al tipo pasado por par?metro. Los tipos
172
         * est?n definidos en esta misma clase de forma est?tica en la variable types.
173
         * @param type Tipo a devolver
174
         * @return Histograma
175
         */
176
        public long[][] getHistogramByType(String type) {
177
                if(type.equals(types[0]))
178
                        return getHistogram();
179
                if(type.equals(types[1]))
180
                        return getAccumulatedHistogram();
181
                if(type.equals(types[2]))
182
                        return getLogaritmicHistogram();
183
                return null;
184
        }
185
        
186
          /**
187
           * Calculo de estad?sticas a partir de un histograma. El resultado de la funci?n es un array
188
           * bidimensional donde el primer ?ndice inndica la estadistica y el segundo el n?mero de banda.
189
           * 
190
           * <UL>
191
           * <LI>m?nimo</LI>
192
           * <LI>m?ximo</LI>
193
           * <LI>media</LI>
194
           * <LI>mediana</LI>
195
           * <LI>N?mero de pixels</LI>
196
           * </UL>
197
           * @param histogram
198
           * @param bandas solicitadas. Cada elemento del vector representa una banda. Si est? a true se calcula la 
199
           * estadistica para esa banda y si est? a false no se calcular?.
200
           * @return
201
           */
202
          public long[][] getBasicStats(boolean[] bands){
203
                  if(histogram == null)
204
                          return null;
205
                  return getBasicStats(0, histogram[0].length - 1, bands);
206
          }
207
          /**
208
           * Calculo de estad?sticas a partir de un histograma. El resultado de la funci?n es un array
209
           * bidimensional donde el primer ?ndice inndica la estadistica y el segundo el n?mero de banda.
210
           * 
211
           * <UL>
212
           * <LI>m?nimo</LI>
213
           * <LI>m?ximo</LI>
214
           * <LI>media</LI>
215
           * <LI>mediana</LI>
216
           * <LI>N?mero de pixels</LI>
217
           * </UL>
218
           * @param histogram
219
           * @param beginPos Posici?n de inicio del histograma para contabilizar estadisticas
220
           * @param endPos Posici?n de fin del histograma para contabilizar estadisticas
221
           * @param bandas solicitadas. Cada elemento del vector representa una banda. Si est? a true se calcula la 
222
           * estadistica para esa banda y si est? a false no se calcular?.
223
           * @return
224
           */
225
          public long[][] getBasicStats(int beginPos, int endPos, boolean[] bands){
226
                  if(histogram == null)
227
                          return null;
228
                  
229
                  //Contamos el n?mero de bandas para las cuales se calcula la estad?stica
230
                  int bandCount = 0;
231
                  for(int iBand = 0; iBand < bands.length; iBand ++)
232
                          if(bands[iBand])
233
                                  bandCount ++;
234
                  
235
                  int values = 5;
236
                  long[][] res = new long[values][];
237
                  
238
                  long[] min = new long[bandCount];//M?nimo
239
                  long[] max = new long[bandCount];//M?ximo
240
                  for(int iBand = 0; iBand < bandCount; iBand ++){
241
                          max[iBand] = beginPos;
242
                          min[iBand] = endPos;
243
                  }
244
                  long[] average = new long[bandCount]; //Valor de pixel medio (Media)
245
                  long[] middle = new long[bandCount]; //Mediana
246
                  long[] nPixelsBand = new long[bandCount];//N?mero de pixels por banda
247
                                                      
248
                  int showBandCounter = 0;  //Contador de bandas de las que hay calcular la estadistica
249
                  for(int iBand = 0; iBand < histogram.length; iBand ++){
250
                          if(bands[iBand]){
251
                            int pixels = 0; //N?mero de valores por banda (entre 0 y 255)
252
                                for(int i = beginPos; i <= endPos; i ++){
253
                                        
254
                                        //Calculo del m?nimo
255
                                        if(histogram[iBand][i] != 0 && i < min[showBandCounter])
256
                                                min[showBandCounter] = i;
257
                                        
258
                                        //Calculo del m?ximo                                                                                
259
                                        if(histogram[iBand][i] != 0 && i > max[showBandCounter])
260
                                                max[showBandCounter] = i;
261
                                        
262
                                        //Calculo del n?mero de pixeles
263
                                        nPixelsBand[showBandCounter] += (long)histogram[iBand][i];
264
                                        
265
                                        if(histogram[iBand][i] != 0)
266
                                                pixels ++;
267
                                        
268
                                        average[showBandCounter] += histogram[iBand][i] * i;
269
                                }
270
                                //Calculo de la media
271
                                try{
272
                                        average[showBandCounter] /= nPixelsBand[showBandCounter];
273
                                }catch(ArithmeticException exc){
274
                                        average[showBandCounter] = 0;
275
                                }
276
                                
277
                                //Calculo de mediana
278
                                long middlePos = nPixelsBand[showBandCounter] >> 1;
279
                                int aux = 0;
280
                                int i = beginPos;
281
                                for(i = beginPos; aux < middlePos; i++)
282
                                        aux += histogram[iBand][i];
283
                                middle[showBandCounter] = i - 1;
284
                                
285
                                showBandCounter ++;
286
                          }
287
                  }
288
           
289
                  res[0] = min;
290
                  res[1] = max;
291
                  res[2] = average;
292
                  res[3] = middle;
293
                  res[4] = nPixelsBand;
294
                  return res;        
295
          }
296
}