Statistics
| Revision:

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

History | View | Annotate | Download (8.79 KB)

1 10939 nacho
/* 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 11076 nacho
 *
26 10939 nacho
 */
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 11080 nacho
                if (histogram != null){
131 10939 nacho
                        long[][] hist = new long[histogram.length][histogram[0].length];
132
                        for (int iBand = 0; iBand < hist.length; iBand++) {
133 11080 nacho
                                hist[iBand][0] = histogram[iBand][0];
134
                                for (int j = 1; j < hist[iBand].length; j++) {
135
                                        hist[iBand][j] = hist[iBand][j - 1] + histogram[iBand][j];
136 10939 nacho
                                }
137
                        }
138 11080 nacho
                        return hist;
139 10939 nacho
                }
140
                return null;
141
        }
142
143
        /**
144 11080 nacho
         * Devuelve el histograma logaritmico
145 10939 nacho
         * @return
146
         */
147
        public long[][] getLogaritmicHistogram() {
148 11080 nacho
                if (histogram != null) {
149
                        long[][] hist = new long[histogram.length][histogram[0].length];
150
                        long min = histogram[0][0];
151
                        for (int iBand = 0; iBand < histogram.length; iBand++)
152
                                for (int j = 1; j < histogram[iBand].length; j++)
153
                                        if (min > histogram[iBand][j]) min = histogram[iBand][j];
154
                        for (int iBand = 0; iBand < histogram.length; iBand++) {
155
                                for (int j = 0; j < histogram[iBand].length; j++)
156
                                        // Lo multiplico por 1000 para que no se pierdan datos al redondear
157
                                        hist[iBand][j] = (long) (1000.0 * java.lang.Math.log((double) (histogram[iBand][j] - min + 1)));
158
                        }
159
                        return hist;
160
                }
161
                return null;
162 10939 nacho
        }
163
164
        /**
165
         * N?mero de tipos de histograma definidos en esta clase.
166
         * @return entero con el n?mero de tipos definidos.
167
         */
168 11080 nacho
        public static int getHistogramTypesCount() {
169 10939 nacho
                return types.length;
170
        }
171
172
        /**
173
         * Obtiene un tipo de histograma a partir de su posici?n en el array
174
         * @param pos posici?n en el array del tipo a obtener
175
         * @return Tipo
176
         */
177 11080 nacho
        public static String getType(int pos) {
178 10939 nacho
                return types[pos];
179
        }
180
181 10943 nacho
        /**
182
         * Obtiene el histograma correspondiente al tipo pasado por par?metro. Los tipos
183
         * est?n definidos en esta misma clase de forma est?tica en la variable types.
184
         * @param type Tipo a devolver
185
         * @return Histograma
186
         */
187
        public long[][] getHistogramByType(String type) {
188
                if(type.equals(types[0]))
189
                        return getHistogram();
190
                if(type.equals(types[1]))
191
                        return getAccumulatedHistogram();
192
                if(type.equals(types[2]))
193
                        return getLogaritmicHistogram();
194
                return null;
195
        }
196 10973 nacho
197 11080 nacho
  /**
198
   * Calculo de estad?sticas a partir de un histograma. El resultado de la funci?n es un array
199
   * bidimensional donde el primer ?ndice inndica la estadistica y el segundo el n?mero de banda.
200
   *
201
   * <UL>
202
   * <LI>m?nimo</LI>
203
   * <LI>m?ximo</LI>
204
   * <LI>media</LI>
205
   * <LI>mediana</LI>
206
   * <LI>N?mero de pixels</LI>
207
   * </UL>
208
   * @param histogram
209
   * @param bandas solicitadas. Cada elemento del vector representa una banda. Si est? a true se calcula la
210
   * estadistica para esa banda y si est? a false no se calcular?.
211
   * @return
212
   */
213
  public long[][] getBasicStats(boolean[] bands) {
214
          if(histogram == null)
215
                  return null;
216
          return getBasicStats(0, histogram[0].length - 1, bands);
217
  }
218
219
  /**
220
   * Calculo de estad?sticas a partir de un histograma. El resultado de la funci?n es un array
221
   * bidimensional donde el primer ?ndice inndica la estadistica y el segundo el n?mero de banda.
222
   *
223
   * <UL>
224
   * <LI>m?nimo</LI>
225
   * <LI>m?ximo</LI>
226
   * <LI>media</LI>
227
   * <LI>mediana</LI>
228
   * <LI>N?mero de pixels</LI>
229
   * </UL>
230
   * @param histogram
231
   * @param beginPos Posici?n de inicio del histograma para contabilizar estadisticas
232
   * @param endPos Posici?n de fin del histograma para contabilizar estadisticas
233
   * @param bandas solicitadas. Cada elemento del vector representa una banda. Si est? a true se calcula la
234
   * estadistica para esa banda y si est? a false no se calcular?.
235
   * @return
236
   */
237
  public long[][] getBasicStats(int beginPos, int endPos, boolean[] bands){
238
          if(histogram == null)
239
                  return null;
240
241
          //Contamos el n?mero de bandas para las cuales se calcula la estad?stica
242
          int bandCount = 0;
243
          for(int iBand = 0; iBand < bands.length; iBand ++)
244
                  if(bands[iBand])
245
                          bandCount ++;
246
247
          int values = 5;
248
          long[][] res = new long[values][];
249
250
          long[] min = new long[bandCount];//M?nimo
251
          long[] max = new long[bandCount];//M?ximo
252
          for(int iBand = 0; iBand < bandCount; iBand ++){
253
                  max[iBand] = beginPos;
254
                  min[iBand] = endPos;
255
          }
256
          long[] average = new long[bandCount]; //Valor de pixel medio (Media)
257
          long[] middle = new long[bandCount]; //Mediana
258
          long[] nPixelsBand = new long[bandCount];//N?mero de pixels por banda
259
260
          int showBandCounter = 0;  //Contador de bandas de las que hay calcular la estadistica
261
          for(int iBand = 0; iBand < histogram.length; iBand ++){
262
                  if(bands[iBand]){
263
                    int pixels = 0; //N?mero de valores por banda (entre 0 y 255)
264
                        for(int i = beginPos; i <= endPos; i ++){
265 10973 nacho
266 11080 nacho
                                //Calculo del m?nimo
267
                                if(histogram[iBand][i] != 0 && i < min[showBandCounter])
268
                                        min[showBandCounter] = i;
269 10973 nacho
270 11080 nacho
                                //Calculo del m?ximo
271
                                if(histogram[iBand][i] != 0 && i > max[showBandCounter])
272
                                        max[showBandCounter] = i;
273
274
                                //Calculo del n?mero de pixeles
275
                                nPixelsBand[showBandCounter] += (long)histogram[iBand][i];
276
277
                                if(histogram[iBand][i] != 0)
278
                                        pixels ++;
279
280
                                average[showBandCounter] += histogram[iBand][i] * i;
281
                        }
282
                        //Calculo de la media
283
                        try{
284
                                average[showBandCounter] /= nPixelsBand[showBandCounter];
285
                        }catch(ArithmeticException exc){
286
                                average[showBandCounter] = 0;
287
                        }
288
289
                        //Calculo de mediana
290
                        long middlePos = nPixelsBand[showBandCounter] >> 1;
291
                        int aux = 0;
292
                        int i = beginPos;
293
                        for(i = beginPos; aux < middlePos; i++)
294
                                aux += histogram[iBand][i];
295
                        middle[showBandCounter] = i - 1;
296
297
                        showBandCounter ++;
298
                  }
299
          }
300
301
          res[0] = min;
302
          res[1] = max;
303
          res[2] = average;
304
          res[3] = middle;
305
          res[4] = nPixelsBand;
306
          return res;
307
  }
308
}