Revision 11185

View differences:

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