Revision 11185
trunk/libraries/libRaster/src/org/gvsig/raster/util/Histogram.java | ||
---|---|---|
18 | 18 |
*/ |
19 | 19 |
package org.gvsig.raster.util; |
20 | 20 |
|
21 |
import java.util.ArrayList; |
|
22 |
import java.util.Arrays; |
|
23 |
import java.util.TreeMap; |
|
24 | 21 |
|
25 | 22 |
/** |
26 | 23 |
* Representa un histograma. |
... | ... | |
32 | 29 |
private HistogramClass[][] histogram = null; |
33 | 30 |
private int nClasses = 0; |
34 | 31 |
|
35 |
//[NBandas][valores de pixel] |
|
36 |
private ArrayList[] numPixels = null; |
|
37 |
private TreeMap[] table = null; |
|
32 |
private long[][] table = null; |
|
38 | 33 |
private static String[] types = {"normal", "accumulated", "logaritmic"}; |
34 |
private double min = Double.MAX_VALUE; |
|
35 |
private double max = Double.MIN_VALUE; |
|
39 | 36 |
|
40 | 37 |
/** |
41 | 38 |
* Constructor |
42 | 39 |
*/ |
43 |
public Histogram(int nBands, int nClasses) { |
|
44 |
numPixels = new ArrayList[nBands];
|
|
45 |
table = new TreeMap[nBands];
|
|
46 |
for (int i = 0; i < numPixels.length; i++) {
|
|
47 |
numPixels[i] = new ArrayList();
|
|
48 |
table[i] = new TreeMap();
|
|
49 |
}
|
|
40 |
public Histogram(int nBands, int nClasses, double min, double max) {
|
|
41 |
table = new long[nBands][nClasses];
|
|
42 |
for (int i=0; i < table.length; i++)
|
|
43 |
for (int j=0; j < table[0].length; j++)
|
|
44 |
table[i][j] = 0;
|
|
45 |
this.min = min;
|
|
46 |
this.max = max;
|
|
50 | 47 |
this.nClasses = nClasses; |
51 | 48 |
} |
52 | 49 |
|
... | ... | |
56 | 53 |
* o rango y el segundo el n?mero de elementos que aparecen. |
57 | 54 |
*/ |
58 | 55 |
public HistogramClass[][] getHistogram() { |
59 |
//Extraemos los long del ArrayList metiendolos en un array ordenado |
|
60 |
double[][] value = new double[numPixels.length][]; |
|
61 |
for (int i = 0; i < value.length; i++) { |
|
62 |
double[] aux = new double[numPixels[i].size()]; |
|
63 |
for (int j = 0; j < numPixels[i].size(); j++) |
|
64 |
aux[j] = ((Double)numPixels[i].get(j)).longValue(); |
|
65 |
Arrays.sort(aux); |
|
66 |
value[i] = aux; |
|
67 |
} |
|
68 |
|
|
69 |
//Minimo y m?ximo de las bandas |
|
70 |
double min = Double.MAX_VALUE, max = Double.MIN_VALUE; |
|
71 |
for (int i = 0; i < value.length; i++) { |
|
72 |
if(value[i][0] < min) |
|
73 |
min = value[i][0]; |
|
74 |
if(value[i][value[i].length - 1] > max) |
|
75 |
max = value[i][value[i].length - 1]; |
|
76 |
} |
|
77 |
|
|
78 |
if(nClasses <= 0) |
|
56 |
if (nClasses <= 0) |
|
79 | 57 |
return null; |
80 | 58 |
|
81 |
histogram = new HistogramClass[value.length][nClasses];
|
|
59 |
histogram = new HistogramClass[table.length][nClasses];
|
|
82 | 60 |
|
83 |
//Intervalo de las clases |
|
84 |
double interv = (max - min) / nClasses; |
|
85 |
|
|
86 |
for (int i = 0; i < value.length; i++) { |
|
87 |
double begin = min; |
|
88 |
int pos = 0; |
|
61 |
for (int i = 0; i < table.length; i++) { |
|
89 | 62 |
for (int j = 0; j < nClasses; j++) { |
90 |
HistogramClass hc = new HistogramClass(begin, begin + interv); |
|
91 |
begin += interv; |
|
92 |
for (int k = pos; k < value[i].length; k++) { |
|
93 |
if(value[i][k] >= hc.getMin() && value[i][k] < hc.getMax()) { |
|
94 |
Long nPxs = ((Long)table[i].get(new Double(value[i][k]))); |
|
95 |
hc.setNPixels(nPxs.longValue()); |
|
96 |
pos ++; |
|
97 |
} |
|
98 |
} |
|
63 |
HistogramClass hc = new HistogramClass(min + ((j*(max-min))/nClasses), min + (((j+1)*(max-min))/nClasses)); |
|
64 |
hc.setValue(table[i][j]); |
|
99 | 65 |
histogram[i][j] = hc; |
100 | 66 |
} |
101 |
|
|
102 | 67 |
} |
103 | 68 |
return histogram; |
104 | 69 |
} |
... | ... | |
108 | 73 |
* @return entero que representa el n?mero de bandas |
109 | 74 |
*/ |
110 | 75 |
public int getNumBands() { |
111 |
if(numPixels != null)
|
|
112 |
return numPixels.length;
|
|
76 |
if (table != null)
|
|
77 |
return table.length;
|
|
113 | 78 |
return 0; |
114 | 79 |
} |
115 | 80 |
|
... | ... | |
117 | 82 |
* Obtiene la longitud (n?mero de valores) de una banda determinada |
118 | 83 |
* @param band Banda o obtener la longitud |
119 | 84 |
* @return entero con la longitud de la banda |
85 |
* rangos de valores y DataclassList. |
|
120 | 86 |
*/ |
121 | 87 |
public int getBandLenght(int band) { |
122 |
if(numPixels != null)
|
|
123 |
return numPixels[band].size();
|
|
88 |
if (table != null)
|
|
89 |
return table[band].length;
|
|
124 | 90 |
return 0; |
125 | 91 |
} |
126 | 92 |
|
... | ... | |
147 | 113 |
* @param value Valor a asignar |
148 | 114 |
*/ |
149 | 115 |
public void setHistogramValue(int band, double px, long value) { |
150 |
if(table[band].get(new Double(px)) == null) |
|
151 |
numPixels[band].add(new Double(px)); |
|
152 |
table[band].put(new Double(px), new Long(value)); |
|
116 |
int pos = (int) ((nClasses * (px - min))/(max-min)); |
|
117 |
if (pos < 0) pos = 0; |
|
118 |
if (pos >= nClasses) pos = nClasses - 1; |
|
119 |
table[band][pos] = value; |
|
153 | 120 |
} |
154 | 121 |
|
155 | 122 |
/** |
123 |
* Asigna un valor para una posici?n del histograma segun la posicion en las |
|
124 |
* clases |
|
125 |
* @param band Valor del pixel o clase a asignar |
|
126 |
* @param pos Posicion dentro de la clase. Ejemplo 0..63 |
|
127 |
* @param value Valor a asignar |
|
128 |
*/ |
|
129 |
public void setHistogramValueByPos(int band, int pos, long value) { |
|
130 |
if (pos < 0) pos = 0; |
|
131 |
if (pos >= nClasses) pos = nClasses - 1; |
|
132 |
table[band][pos] = value; |
|
133 |
} |
|
134 |
|
|
135 |
/** |
|
156 | 136 |
* Obtiene un valor del histograma |
157 | 137 |
* @param band N?mero de banda del valor a recuperar |
158 | 138 |
* @param px Pixel o valor de la clase del valor a recuperar |
159 | 139 |
* @return valor |
160 | 140 |
*/ |
161 |
public long getHistogramValue(int band, double px) { |
|
162 |
if(histogram == null) |
|
163 |
getHistogram(); |
|
141 |
public double getHistogramValue(int band, double px) { |
|
142 |
if (histogram == null) getHistogram(); |
|
164 | 143 |
for (int i = 0; i < histogram[band].length; i++) { |
165 |
if(((HistogramClass)histogram[band][i]).isIn(px)) |
|
166 |
return ((HistogramClass)histogram[band][i]).getNPixels();
|
|
144 |
if (((HistogramClass)histogram[band][i]).isIn(px))
|
|
145 |
return ((HistogramClass)histogram[band][i]).getValue();
|
|
167 | 146 |
} |
168 | 147 |
return 0; |
169 | 148 |
} |
170 | 149 |
|
150 |
/** |
|
151 |
* Obtiene un valor del histograma segun la posicion dentro de las clases |
|
152 |
* @param band N?mero de banda del valor a recuperar |
|
153 |
* @param px Pixel o valor de la clase del valor a recuperar |
|
154 |
* @return valor |
|
155 |
*/ |
|
156 |
public double getHistogramValueByPos(int band, int pos) { |
|
157 |
if (pos < 0) pos = 0; |
|
158 |
if (pos >= nClasses) pos = nClasses - 1; |
|
159 |
return table[band][pos]; |
|
160 |
} |
|
171 | 161 |
|
172 | 162 |
/** |
173 | 163 |
* Incrementa un valor de una posici?n del histograma |
... | ... | |
175 | 165 |
* @param px Pixel o valor de la clase |
176 | 166 |
*/ |
177 | 167 |
public void incrementPxValue(int band, double px) { |
178 |
if(table[band].get(new Double(px)) == null) { |
|
179 |
numPixels[band].add(new Double(px)); |
|
180 |
table[band].put(new Double(px), new Long(1)); |
|
181 |
} else { |
|
182 |
Long v = ((Long)table[band].get(new Double(px))); |
|
183 |
table[band].put(new Double(px), new Long(v.longValue() + 1)); |
|
184 |
} |
|
168 |
int pos = (int) ((nClasses * (px - min))/(max-min)); |
|
169 |
if (pos < 0) pos = 0; |
|
170 |
if (pos >= nClasses) pos = nClasses - 1; |
|
171 |
table[band][pos]++; |
|
185 | 172 |
} |
186 | 173 |
|
187 | 174 |
/** |
... | ... | |
189 | 176 |
* @return |
190 | 177 |
*/ |
191 | 178 |
public HistogramClass[][] getAccumulatedHistogram() { |
192 |
/*if (histogram != null){
|
|
193 |
long[][] hist = new long[histogram.length][histogram[0].length];
|
|
179 |
if (histogram != null) {
|
|
180 |
HistogramClass[][] hist = new HistogramClass[histogram.length][histogram[0].length];
|
|
194 | 181 |
for (int iBand = 0; iBand < hist.length; iBand++) { |
195 |
hist[iBand][0] = histogram[iBand][0]; |
|
182 |
hist[iBand][0] = new HistogramClass(histogram[iBand][0].getMin(), histogram[iBand][0].getMax()); |
|
183 |
hist[iBand][0].setValue(histogram[iBand][0].getValue()); |
|
196 | 184 |
for (int j = 1; j < hist[iBand].length; j++) { |
197 |
hist[iBand][j] = hist[iBand][j - 1] + histogram[iBand][j]; |
|
185 |
hist[iBand][j] = new HistogramClass(histogram[iBand][j].getMin(), histogram[iBand][j].getMax()); |
|
186 |
hist[iBand][j].setValue(hist[iBand][j - 1].getValue() + histogram[iBand][j].getValue()); |
|
198 | 187 |
} |
199 | 188 |
} |
200 | 189 |
return hist; |
201 | 190 |
} |
202 |
return null;*/ |
|
203 |
return getHistogram(); |
|
191 |
return null; |
|
204 | 192 |
} |
205 | 193 |
|
206 | 194 |
/** |
... | ... | |
208 | 196 |
* @return |
209 | 197 |
*/ |
210 | 198 |
public HistogramClass[][] getLogaritmicHistogram() { |
211 |
/*if (histogram != null) { |
|
212 |
long[][] hist = new long[histogram.length][histogram[0].length]; |
|
213 |
long min = histogram[0][0]; |
|
214 |
for (int iBand = 0; iBand < histogram.length; iBand++) |
|
215 |
for (int j = 1; j < histogram[iBand].length; j++) |
|
216 |
if (min > histogram[iBand][j]) min = histogram[iBand][j]; |
|
199 |
if (histogram != null) { |
|
200 |
HistogramClass[][] hist = new HistogramClass[histogram.length][histogram[0].length]; |
|
201 |
double minim = Double.MAX_VALUE; |
|
217 | 202 |
for (int iBand = 0; iBand < histogram.length; iBand++) { |
218 |
for (int j = 0; j < histogram[iBand].length; j++) |
|
219 |
// Lo multiplico por 1000 para que no se pierdan datos al redondear |
|
220 |
hist[iBand][j] = (long) (1000.0 * java.lang.Math.log((double) (histogram[iBand][j] - min + 1))); |
|
203 |
for (int j = 0; j < histogram[iBand].length; j++) { |
|
204 |
if (minim > histogram[iBand][j].getValue()) |
|
205 |
minim = histogram[iBand][j].getValue(); |
|
206 |
} |
|
221 | 207 |
} |
208 |
for (int iBand = 0; iBand < histogram.length; iBand++) { |
|
209 |
for (int j = 0; j < histogram[iBand].length; j++) { |
|
210 |
hist[iBand][j] = new HistogramClass(histogram[iBand][j].getMin(), histogram[iBand][j].getMax()); |
|
211 |
hist[iBand][j].setValue(java.lang.Math.log(histogram[iBand][j].getValue() - minim + 1.0)); |
|
212 |
} |
|
213 |
} |
|
222 | 214 |
return hist; |
223 | 215 |
} |
224 |
return null;*/
|
|
225 |
return getHistogram(); |
|
216 |
return null; |
|
217 |
|
|
226 | 218 |
} |
227 | 219 |
|
228 | 220 |
/** |
... | ... | |
275 | 267 |
* @return |
276 | 268 |
*/ |
277 | 269 |
public long[][] getBasicStats(boolean[] bands) { |
278 |
if(histogram == null) |
|
270 |
if (histogram == null)
|
|
279 | 271 |
return null; |
280 | 272 |
return getBasicStats(0, histogram[0].length - 1, bands); |
281 | 273 |
} |
... | ... | |
298 | 290 |
* estadistica para esa banda y si est? a false no se calcular?. |
299 | 291 |
* @return |
300 | 292 |
*/ |
301 |
public long[][] getBasicStats(int beginPos, int endPos, boolean[] bands){ |
|
302 |
if(histogram == null) |
|
303 |
getHistogram(); |
|
293 |
public long[][] getBasicStats(int beginPos2, int endPos2, boolean[] bands){ |
|
294 |
if (histogram == null) getHistogram(); |
|
304 | 295 |
|
296 |
// Preparar las posiciones para los rangos de los HistogramClass |
|
297 |
int beginPos = (int) ((nClasses * (beginPos2 - min)) / (max - min)); |
|
298 |
if (beginPos < 0) beginPos = 0; |
|
299 |
if (beginPos >= nClasses) beginPos = nClasses - 1; |
|
300 |
int endPos = (int) ((nClasses * (endPos2 - min)) / (max - min)); |
|
301 |
if (endPos < 0) endPos = 0; |
|
302 |
if (endPos >= nClasses) endPos = nClasses - 1; |
|
303 |
|
|
305 | 304 |
//Contamos el n?mero de bandas para las cuales se calcula la estad?stica |
306 |
/*int bandCount = 0; |
|
307 |
for(int iBand = 0; iBand < bands.length; iBand ++) |
|
308 |
if(bands[iBand]) |
|
309 |
bandCount ++; |
|
305 |
int bandCount = 0; |
|
306 |
for (int iBand = 0; iBand < bands.length; iBand ++) |
|
307 |
if (bands[iBand]) bandCount ++; |
|
310 | 308 |
|
311 | 309 |
int values = 5; |
312 | 310 |
long[][] res = new long[values][]; |
313 | 311 |
|
314 | 312 |
long[] min = new long[bandCount];//M?nimo |
315 | 313 |
long[] max = new long[bandCount];//M?ximo |
316 |
for(int iBand = 0; iBand < bandCount; iBand ++){
|
|
314 |
for (int iBand = 0; iBand < bandCount; iBand ++) {
|
|
317 | 315 |
max[iBand] = beginPos; |
318 | 316 |
min[iBand] = endPos; |
319 | 317 |
} |
... | ... | |
322 | 320 |
long[] nPixelsBand = new long[bandCount];//N?mero de pixels por banda |
323 | 321 |
|
324 | 322 |
int showBandCounter = 0; //Contador de bandas de las que hay calcular la estadistica |
325 |
for(int iBand = 0; iBand < histogram.length; iBand ++){ |
|
323 |
for (int iBand = 0; iBand < histogram.length; iBand ++){
|
|
326 | 324 |
if(bands[iBand]){ |
327 | 325 |
int pixels = 0; //N?mero de valores por banda (entre 0 y 255) |
328 | 326 |
for(int i = beginPos; i <= endPos; i ++){ |
329 | 327 |
|
330 | 328 |
//Calculo del m?nimo |
331 |
if(histogram[iBand][i] != 0 && i < min[showBandCounter]) |
|
329 |
if(histogram[iBand][i].getValue() != 0 && i < min[showBandCounter])
|
|
332 | 330 |
min[showBandCounter] = i; |
333 | 331 |
|
334 | 332 |
//Calculo del m?ximo |
335 |
if(histogram[iBand][i] != 0 && i > max[showBandCounter]) |
|
333 |
if(histogram[iBand][i].getValue() != 0 && i > max[showBandCounter])
|
|
336 | 334 |
max[showBandCounter] = i; |
337 | 335 |
|
338 | 336 |
//Calculo del n?mero de pixeles |
339 |
nPixelsBand[showBandCounter] += (long)histogram[iBand][i]; |
|
337 |
nPixelsBand[showBandCounter] += (long)histogram[iBand][i].getValue();
|
|
340 | 338 |
|
341 |
if(histogram[iBand][i] != 0) |
|
339 |
if(histogram[iBand][i].getValue() != 0)
|
|
342 | 340 |
pixels ++; |
343 | 341 |
|
344 |
average[showBandCounter] += histogram[iBand][i] * i; |
|
342 |
average[showBandCounter] += histogram[iBand][i].getValue() * i;
|
|
345 | 343 |
} |
346 | 344 |
//Calculo de la media |
347 | 345 |
try{ |
... | ... | |
355 | 353 |
int aux = 0; |
356 | 354 |
int i = beginPos; |
357 | 355 |
for(i = beginPos; aux < middlePos; i++) |
358 |
aux += histogram[iBand][i]; |
|
356 |
aux += histogram[iBand][i].getValue();
|
|
359 | 357 |
middle[showBandCounter] = i - 1; |
360 | 358 |
|
361 | 359 |
showBandCounter ++; |
... | ... | |
367 | 365 |
res[2] = average; |
368 | 366 |
res[3] = middle; |
369 | 367 |
res[4] = nPixelsBand; |
370 |
return res; */ |
|
371 |
return null; |
|
368 |
return res; |
|
372 | 369 |
} |
373 | 370 |
} |
Also available in: Unified diff