Statistics
| Revision:

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

History | View | Annotate | Download (8.79 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
public class Histogram {
27
        private long[][] histogram = null;
28
        private static String[] types = {"normal", "accumulated", "logaritmic"};
29
        
30
        /**
31
         * Constructor
32
         */
33
        public Histogram() {
34
                histogram = new long[0][0];
35
        }
36
        
37
        /**
38
         * Constructor. Inicializa valores a cero
39
         * @param bands N?mero de bandas
40
         * @param pxs N?mero de valores o clases
41
         */
42
        public Histogram(int bands, int pxs) {
43
                histogram = new long[bands][pxs];
44
        }
45
        
46
        /**
47
         * Obtiene el histograma sin modificar
48
         * @return array bidimensional donde el primer elemento es el valor del pixel
49
         * o rango y el segundo el n?mero de elementos que aparecen.
50
         */
51
        public long[][] getHistogram() {
52
                return histogram;
53
        }
54
        
55
        /**
56
         * Obtiene el n?mero de bandas del histograma 
57
         * @return entero que representa el n?mero de bandas 
58
         */
59
        public int getNumBands() {
60
                if(histogram != null)
61
                        return histogram.length;
62
                return 0;
63
        }
64
        
65
        /**
66
         * Obtiene la longitud (n?mero de valores) de una banda determinada
67
         * @param band Banda o obtener la longitud
68
         * @return entero con la longitud de la banda
69
         */
70
        public int getBandLenght(int band) {
71
                if(histogram != null)
72
                        return histogram[band].length;
73
                return 0;
74
        }
75
        
76
        /**
77
         * Obtiene el n?mero de valores o clases del histograma
78
         * @return entero que representa el n?mero de valores o clases del histograma
79
         */
80
        public int getNumValues() {
81
                if(histogram != null)
82
                        return histogram[0].length;
83
                return 0;
84
        }
85
        
86
        /**
87
         * Asigna un histograma
88
         * @param hist histograma asignado
89
         */
90
        public void setHistogram(long[][] hist){
91
                histogram = hist;
92
        }
93
                
94
        /**
95
         * ASigna un valor para una posici?n del histograma
96
         * @param bands Valor del pixel o clase a asignar
97
         * @param px Valor del pixel
98
         * @param value Valor a asignar
99
         */
100
        public void setHistogramValue(int band, int px, long value) {
101
                if(histogram != null)
102
                        histogram[band][px] = value;
103
        }
104
        
105
        /**
106
         * Obtiene un valor del histograma
107
         * @param band N?mero de banda del valor a recuperar
108
         * @param px Pixel o valor de la clase del valor a recuperar
109
         * @return valor
110
         */
111
        public long getHistogramValue(int band, int px) {
112
                return histogram[band][px];
113
        }
114
        
115
        /**
116
         * Incrementa un valor de una posici?n del histograma
117
         * @param band N?mero de banda
118
         * @param px Pixel o valor de la clase
119
         */
120
        public void incrementPxValue(int band, int px) {
121
                histogram[band][px] ++;
122
        }
123
        
124
        /**
125
         * Devuelve el histograma acumulado
126
         * @return
127
         */
128
        public long[][] getAccumulatedHistogram() {
129
                if (histogram != null){
130
                        long[][] hist = new long[histogram.length][histogram[0].length];
131
                        for (int iBand = 0; iBand < hist.length; iBand++) {
132
                                hist[iBand][0] = histogram[iBand][0];
133
                                for (int j = 1; j < hist[iBand].length; j++) {
134
                                        hist[iBand][j] = hist[iBand][j - 1] + histogram[iBand][j];
135
                                }
136
                        }
137
                        return hist;
138
                }
139
                return null;
140
        }
141
        
142
        /**
143
         * Devuelve el histograma logaritmico
144
         * @return
145
         */
146
        public long[][] getLogaritmicHistogram() {
147
                if (histogram != null) {
148
                        long[][] hist = new long[histogram.length][histogram[0].length];
149
                        long min = histogram[0][0];
150
                        for (int iBand = 0; iBand < histogram.length; iBand++)
151
                                for (int j = 1; j < histogram[iBand].length; j++)
152
                                        if (min > histogram[iBand][j]) min = histogram[iBand][j];
153
                        for (int iBand = 0; iBand < histogram.length; iBand++) {
154
                                for (int j = 0; j < histogram[iBand].length; j++)
155
                                        // Lo multiplico por 1000 para que no se pierdan datos al redondear
156
                                        hist[iBand][j] = (long) (1000.0 * java.lang.Math.log((double) (histogram[iBand][j] - min + 1)));
157
                        }
158
                        return hist;
159
                }
160
                return null;
161
        }
162
        
163
        /**
164
         * N?mero de tipos de histograma definidos en esta clase.
165
         * @return entero con el n?mero de tipos definidos.
166
         */
167
        public static int getHistogramTypesCount() {
168
                return types.length;
169
        }
170
        
171
        /**
172
         * Obtiene un tipo de histograma a partir de su posici?n en el array
173
         * @param pos posici?n en el array del tipo a obtener
174
         * @return Tipo
175
         */
176
        public static String getType(int pos) {
177
                return types[pos];
178
        }
179
        
180
        /**
181
         * Obtiene el histograma correspondiente al tipo pasado por par?metro. Los tipos
182
         * est?n definidos en esta misma clase de forma est?tica en la variable types.
183
         * @param type Tipo a devolver
184
         * @return Histograma
185
         */
186
        public long[][] getHistogramByType(String type) {
187
                if(type.equals(types[0]))
188
                        return getHistogram();
189
                if(type.equals(types[1]))
190
                        return getAccumulatedHistogram();
191
                if(type.equals(types[2]))
192
                        return getLogaritmicHistogram();
193
                return null;
194
        }
195
        
196
  /**
197
   * Calculo de estad?sticas a partir de un histograma. El resultado de la funci?n es un array
198
   * bidimensional donde el primer ?ndice inndica la estadistica y el segundo el n?mero de banda.
199
   * 
200
   * <UL>
201
   * <LI>m?nimo</LI>
202
   * <LI>m?ximo</LI>
203
   * <LI>media</LI>
204
   * <LI>mediana</LI>
205
   * <LI>N?mero de pixels</LI>
206
   * </UL>
207
   * @param histogram
208
   * @param bandas solicitadas. Cada elemento del vector representa una banda. Si est? a true se calcula la 
209
   * estadistica para esa banda y si est? a false no se calcular?.
210
   * @return
211
   */
212
  public long[][] getBasicStats(boolean[] bands) {
213
          if(histogram == null)
214
                  return null;
215
          return getBasicStats(0, histogram[0].length - 1, bands);
216
  }
217

    
218
  /**
219
   * Calculo de estad?sticas a partir de un histograma. El resultado de la funci?n es un array
220
   * bidimensional donde el primer ?ndice inndica la estadistica y el segundo el n?mero de banda.
221
   * 
222
   * <UL>
223
   * <LI>m?nimo</LI>
224
   * <LI>m?ximo</LI>
225
   * <LI>media</LI>
226
   * <LI>mediana</LI>
227
   * <LI>N?mero de pixels</LI>
228
   * </UL>
229
   * @param histogram
230
   * @param beginPos Posici?n de inicio del histograma para contabilizar estadisticas
231
   * @param endPos Posici?n de fin del histograma para contabilizar estadisticas
232
   * @param bandas solicitadas. Cada elemento del vector representa una banda. Si est? a true se calcula la 
233
   * estadistica para esa banda y si est? a false no se calcular?.
234
   * @return
235
   */
236
  public long[][] getBasicStats(int beginPos, int endPos, boolean[] bands){
237
          if(histogram == null)
238
                  return null;
239
          
240
          //Contamos el n?mero de bandas para las cuales se calcula la estad?stica
241
          int bandCount = 0;
242
          for(int iBand = 0; iBand < bands.length; iBand ++)
243
                  if(bands[iBand])
244
                          bandCount ++;
245
          
246
          int values = 5;
247
          long[][] res = new long[values][];
248
          
249
          long[] min = new long[bandCount];//M?nimo
250
          long[] max = new long[bandCount];//M?ximo
251
          for(int iBand = 0; iBand < bandCount; iBand ++){
252
                  max[iBand] = beginPos;
253
                  min[iBand] = endPos;
254
          }
255
          long[] average = new long[bandCount]; //Valor de pixel medio (Media)
256
          long[] middle = new long[bandCount]; //Mediana
257
          long[] nPixelsBand = new long[bandCount];//N?mero de pixels por banda
258
                                              
259
          int showBandCounter = 0;  //Contador de bandas de las que hay calcular la estadistica
260
          for(int iBand = 0; iBand < histogram.length; iBand ++){
261
                  if(bands[iBand]){
262
                    int pixels = 0; //N?mero de valores por banda (entre 0 y 255)
263
                        for(int i = beginPos; i <= endPos; i ++){
264
                                
265
                                //Calculo del m?nimo
266
                                if(histogram[iBand][i] != 0 && i < min[showBandCounter])
267
                                        min[showBandCounter] = i;
268
                                
269
                                //Calculo del m?ximo                                                                                
270
                                if(histogram[iBand][i] != 0 && i > max[showBandCounter])
271
                                        max[showBandCounter] = i;
272
                                
273
                                //Calculo del n?mero de pixeles
274
                                nPixelsBand[showBandCounter] += (long)histogram[iBand][i];
275
                                
276
                                if(histogram[iBand][i] != 0)
277
                                        pixels ++;
278
                                
279
                                average[showBandCounter] += histogram[iBand][i] * i;
280
                        }
281
                        //Calculo de la media
282
                        try{
283
                                average[showBandCounter] /= nPixelsBand[showBandCounter];
284
                        }catch(ArithmeticException exc){
285
                                average[showBandCounter] = 0;
286
                        }
287
                        
288
                        //Calculo de mediana
289
                        long middlePos = nPixelsBand[showBandCounter] >> 1;
290
                        int aux = 0;
291
                        int i = beginPos;
292
                        for(i = beginPos; aux < middlePos; i++)
293
                                aux += histogram[iBand][i];
294
                        middle[showBandCounter] = i - 1;
295
                        
296
                        showBandCounter ++;
297
                  }
298
          }
299
   
300
          res[0] = min;
301
          res[1] = max;
302
          res[2] = average;
303
          res[3] = middle;
304
          res[4] = nPixelsBand;
305
          return res;        
306
  }
307
}