svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libRaster / src / org / gvsig / raster / datastruct / Histogram.java @ 31829
History | View | Annotate | Download (16.1 KB)
1 | 12383 | 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.datastruct; |
||
20 | |||
21 | 27016 | csanchez | import org.slf4j.Logger; |
22 | import org.slf4j.LoggerFactory; |
||
23 | 20836 | bsanchez | import org.gvsig.raster.RasterLibrary; |
24 | 21543 | bsanchez | import org.gvsig.raster.dataset.IBuffer; |
25 | 12383 | nacho | /**
|
26 | * Representa un histograma.
|
||
27 | 21306 | bsanchez | *
|
28 | 12383 | nacho | * @version 27/03/2007
|
29 | * @author Nacho Brodin (nachobrodin@gmail.com)
|
||
30 | */
|
||
31 | public class Histogram { |
||
32 | /**
|
||
33 | * Variable que representa el histograma. La primera dimensi?n es el n?mero de
|
||
34 | * bandas y la segunda un array de clases. En el caso b?sico de un RGB una clase tendr? el
|
||
35 | * valor m?nimo igual al m?ximo.
|
||
36 | */
|
||
37 | 20836 | bsanchez | private HistogramClass[][] histogram = null; |
38 | |||
39 | private long[][] table = null; |
||
40 | 21306 | bsanchez | private double[] min = null; |
41 | private double[] max = null; |
||
42 | 20836 | bsanchez | private double noDataValue = RasterLibrary.defaultNoDataValue; |
43 | 21543 | bsanchez | private int dataType = IBuffer.TYPE_UNDEFINED; |
44 | 12383 | nacho | |
45 | 21306 | bsanchez | private int nClasses = 0; |
46 | |||
47 | 12383 | nacho | /**
|
48 | * Constructor
|
||
49 | 13932 | nacho | * @param nBands N?mero de bandas
|
50 | * @param nClasses N?mero de clases en que hacemos la divisi?n
|
||
51 | * @param min Valor m?nimo del histograma
|
||
52 | * @param max Valor m?ximo del histograma
|
||
53 | 12383 | nacho | */
|
54 | 21306 | bsanchez | public Histogram(int nBands, int nClasses, double[] min, double[] max) { |
55 | 21543 | bsanchez | if ((nBands != min.length) || (nBands != max.length)) {
|
56 | System.out.println("No tiene las mismas bandas"); |
||
57 | } |
||
58 | constructorHistogramImpl(min, max, nClasses); |
||
59 | } |
||
60 | |||
61 | private void constructorHistogramImpl(double[] min, double[] max, int nClasses) { |
||
62 | table = new long[min.length][nClasses]; |
||
63 | 21306 | bsanchez | for (int i = 0; i < table.length; i++) |
64 | 12383 | nacho | for (int j = 0; j < table[0].length; j++) |
65 | table[i][j] = 0;
|
||
66 | 22098 | bsanchez | this.min = (double[]) min.clone(); |
67 | this.max = (double[]) max.clone(); |
||
68 | 21306 | bsanchez | |
69 | this.nClasses = getNumValues();
|
||
70 | 12383 | nacho | } |
71 | 21543 | bsanchez | |
72 | /**
|
||
73 | * Constructor
|
||
74 | * @param nBands N?mero de bandas
|
||
75 | * @param nClasses N?mero de clases en que hacemos la divisi?n
|
||
76 | * @param min Valor m?nimo del histograma
|
||
77 | * @param max Valor m?ximo del histograma
|
||
78 | */
|
||
79 | public Histogram(int nBands, double[] min, double[] max, int dataType) { |
||
80 | int numberClasses;
|
||
81 | this.dataType = dataType;
|
||
82 | 22098 | bsanchez | this.min = (double[]) min.clone(); |
83 | this.max = (double[]) max.clone(); |
||
84 | 21543 | bsanchez | if (dataType == IBuffer.TYPE_BYTE) {
|
85 | numberClasses = RasterLibrary.defaultNumberOfColors; |
||
86 | boolean unsigned = false; |
||
87 | for (int i = 0; i < this.min.length; i++) |
||
88 | if (this.min[i] < 0) |
||
89 | unsigned = true;
|
||
90 | for (int i = 0; i < this.min.length; i++) { |
||
91 | if (unsigned) {
|
||
92 | this.min[i] = -128; |
||
93 | this.max[i] = 127; |
||
94 | } else {
|
||
95 | this.min[i] = 0; |
||
96 | this.max[i] = 255; |
||
97 | } |
||
98 | } |
||
99 | } else {
|
||
100 | numberClasses = RasterLibrary.defaultNumberOfClasses; |
||
101 | } |
||
102 | |||
103 | 21576 | bsanchez | constructorHistogramImpl(this.min, this.max, numberClasses); |
104 | 21543 | bsanchez | } |
105 | 12383 | nacho | |
106 | /**
|
||
107 | 13590 | nacho | * Realiza la uni?n entre el histograma actual y el pasado
|
108 | * por par?metro.
|
||
109 | * @param hist
|
||
110 | 21306 | bsanchez | * @deprecated Con los nuevos maximos y minimos por banda, habria que estudiar
|
111 | * la viabilidad de este metodo y si se comporta correctamente
|
||
112 | 13590 | nacho | */
|
113 | public boolean union(Histogram hist) { |
||
114 | 21306 | bsanchez | long[][] auxTable = hist.getTable(); |
115 | |||
116 | if (auxTable.length != table.length)
|
||
117 | 13590 | nacho | return false; |
118 | 21306 | bsanchez | |
119 | if (auxTable.length == 0) |
||
120 | return true; |
||
121 | |||
122 | if (auxTable[0].length != table[0].length) |
||
123 | return false; |
||
124 | |||
125 | for (int i = 0; i < table.length; i++) |
||
126 | for (int j = 0; j < table[i].length; j++) |
||
127 | table[i][j] += auxTable[i][j]; |
||
128 | |||
129 | 13590 | nacho | return true; |
130 | } |
||
131 | 21306 | bsanchez | |
132 | 13590 | nacho | /**
|
133 | 12383 | nacho | * Asigna la tabla
|
134 | * @param t
|
||
135 | */
|
||
136 | public void setTable(long[][] t) { |
||
137 | 21306 | bsanchez | table = new long[t.length][t[0].length]; |
138 | for (int i = 0; i < table.length; i++) |
||
139 | for (int j = 0; j < table[0].length; j++) |
||
140 | table[i][j] = t[i][j]; |
||
141 | |||
142 | this.nClasses = getNumValues();
|
||
143 | 12383 | nacho | } |
144 | 14437 | bsanchez | |
145 | /**
|
||
146 | * Devuelve el minimo valor del histograma
|
||
147 | * @return
|
||
148 | */
|
||
149 | 21306 | bsanchez | public double getMin(int band) { |
150 | return min[band];
|
||
151 | 14437 | bsanchez | } |
152 | |||
153 | /**
|
||
154 | * Devuelve el maximo valor del histograma
|
||
155 | * @return
|
||
156 | */
|
||
157 | 21306 | bsanchez | public double getMax(int band) { |
158 | return max[band];
|
||
159 | 14437 | bsanchez | } |
160 | 21306 | bsanchez | |
161 | 12383 | nacho | /**
|
162 | 21471 | bsanchez | * Devuelve los minimos valores del histograma
|
163 | * @return
|
||
164 | */
|
||
165 | public double[] getMinims() { |
||
166 | return min;
|
||
167 | } |
||
168 | |||
169 | /**
|
||
170 | * Devuelve los maximos valores del histograma
|
||
171 | * @return
|
||
172 | */
|
||
173 | public double[] getMaxims() { |
||
174 | return max;
|
||
175 | } |
||
176 | |||
177 | /**
|
||
178 | 21306 | bsanchez | * Devuelve si un histograma esta en un rango RGB aceptable
|
179 | * @return
|
||
180 | */
|
||
181 | public boolean isInRangeRGB() { |
||
182 | 21543 | bsanchez | if (dataType == IBuffer.TYPE_BYTE)
|
183 | return true; |
||
184 | 21306 | bsanchez | return true; |
185 | } |
||
186 | |||
187 | /**
|
||
188 | 12383 | nacho | * Obtiene el histograma sin modificar
|
189 | * @return array bidimensional donde el primer elemento es el valor del pixel
|
||
190 | * o rango y el segundo el n?mero de elementos que aparecen.
|
||
191 | */
|
||
192 | public HistogramClass[][] getHistogram() { |
||
193 | 21306 | bsanchez | if (nClasses == 0) |
194 | 12383 | nacho | return null; |
195 | |||
196 | histogram = new HistogramClass[table.length][nClasses];
|
||
197 | 19453 | nbrodin | |
198 | 12383 | nacho | for (int i = 0; i < table.length; i++) { |
199 | 21306 | bsanchez | for (int j = 0; j < table[i].length; j++) { |
200 | 21543 | bsanchez | HistogramClass hc = new HistogramClass( min[i] + ((j * (max[i] - min[i])) / (nClasses - 1)), |
201 | min[i] + (((j + 1) * (max[i] - min[i])) / (nClasses - 1))); |
||
202 | 12383 | nacho | hc.setValue(table[i][j]); |
203 | histogram[i][j] = hc; |
||
204 | } |
||
205 | } |
||
206 | return histogram;
|
||
207 | } |
||
208 | |||
209 | /**
|
||
210 | * Obtiene el n?mero de bandas del histograma
|
||
211 | * @return entero que representa el n?mero de bandas
|
||
212 | */
|
||
213 | public int getNumBands() { |
||
214 | if (table != null) |
||
215 | return table.length;
|
||
216 | return 0; |
||
217 | } |
||
218 | |||
219 | /**
|
||
220 | 21543 | bsanchez | * Obtiene el tipo de datos del histograma original
|
221 | * @return
|
||
222 | */
|
||
223 | public int getDataType() { |
||
224 | return dataType;
|
||
225 | } |
||
226 | |||
227 | /**
|
||
228 | 12383 | nacho | * Obtiene la longitud (n?mero de valores) de una banda determinada
|
229 | * @param band Banda o obtener la longitud
|
||
230 | * @return entero con la longitud de la banda
|
||
231 | * rangos de valores y DataclassList.
|
||
232 | */
|
||
233 | public int getBandLenght(int band) { |
||
234 | if (table != null) |
||
235 | return table[band].length;
|
||
236 | return 0; |
||
237 | } |
||
238 | |||
239 | /**
|
||
240 | * Obtiene el n?mero de valores o clases del histograma
|
||
241 | * @return entero que representa el n?mero de valores o clases del histograma
|
||
242 | */
|
||
243 | public int getNumValues() { |
||
244 | 21306 | bsanchez | if (table == null) |
245 | return 0; |
||
246 | |||
247 | if (table.length == 0) |
||
248 | return 0; |
||
249 | |||
250 | return table[0].length; |
||
251 | 12383 | nacho | } |
252 | |||
253 | /**
|
||
254 | * Asigna un histograma
|
||
255 | * @param hist histograma asignado
|
||
256 | */
|
||
257 | public void setHistogram(HistogramClass[][] hist){ |
||
258 | histogram = hist; |
||
259 | } |
||
260 | |||
261 | /**
|
||
262 | * Asigna un valor para una posici?n del histograma
|
||
263 | * @param band Valor del pixel o clase a asignar
|
||
264 | * @param px Valor del pixel
|
||
265 | * @param value Valor a asignar
|
||
266 | */
|
||
267 | public void setHistogramValue(int band, double px, long value) { |
||
268 | 21543 | bsanchez | int pos = (int) (((nClasses - 1) * (px - min[band])) / (max[band] - min[band])); |
269 | 21306 | bsanchez | if (pos < 0) |
270 | pos = 0;
|
||
271 | if (pos >= nClasses)
|
||
272 | pos = nClasses - 1;
|
||
273 | 12383 | nacho | table[band][pos] = value; |
274 | } |
||
275 | |||
276 | /**
|
||
277 | * Asigna un valor para una posici?n del histograma segun la posicion en las
|
||
278 | * clases
|
||
279 | * @param band Valor del pixel o clase a asignar
|
||
280 | * @param pos Posicion dentro de la clase. Ejemplo 0..63
|
||
281 | * @param value Valor a asignar
|
||
282 | */
|
||
283 | public void setHistogramValueByPos(int band, int pos, long value) { |
||
284 | 21306 | bsanchez | if (pos < 0) |
285 | pos = 0;
|
||
286 | if (pos >= nClasses)
|
||
287 | pos = nClasses - 1;
|
||
288 | 12383 | nacho | table[band][pos] = value; |
289 | } |
||
290 | |||
291 | /**
|
||
292 | * Obtiene un valor del histograma
|
||
293 | * @param band N?mero de banda del valor a recuperar
|
||
294 | * @param px Pixel o valor de la clase del valor a recuperar
|
||
295 | * @return valor
|
||
296 | */
|
||
297 | public double getHistogramValue(int band, double px) { |
||
298 | 21306 | bsanchez | if (histogram == null) |
299 | getHistogram(); |
||
300 | |||
301 | for (int i = 0; i < histogram[band].length; i++) |
||
302 | if (((HistogramClass) histogram[band][i]).isIn(px))
|
||
303 | return ((HistogramClass) histogram[band][i]).getValue();
|
||
304 | |||
305 | 12383 | nacho | return 0; |
306 | } |
||
307 | |||
308 | /**
|
||
309 | * Obtiene un valor del histograma segun la posicion dentro de las clases
|
||
310 | * @param band N?mero de banda del valor a recuperar
|
||
311 | * @param px Pixel o valor de la clase del valor a recuperar
|
||
312 | * @return valor
|
||
313 | */
|
||
314 | public double getHistogramValueByPos(int band, int pos) { |
||
315 | 21306 | bsanchez | if (pos < 0) |
316 | pos = 0;
|
||
317 | |||
318 | if (pos >= nClasses)
|
||
319 | 12383 | nacho | pos = nClasses - 1;
|
320 | 21306 | bsanchez | |
321 | 12383 | nacho | return table[band][pos];
|
322 | } |
||
323 | |||
324 | /**
|
||
325 | * Incrementa un valor de una posici?n del histograma
|
||
326 | * @param band N?mero de banda
|
||
327 | * @param px Pixel o valor de la clase
|
||
328 | */
|
||
329 | public void incrementPxValue(int band, double px) { |
||
330 | 19138 | bsanchez | if (Double.isNaN(px)) |
331 | return;
|
||
332 | |||
333 | 20836 | bsanchez | if (px == noDataValue)
|
334 | return;
|
||
335 | |||
336 | 21543 | bsanchez | int pos = (int) (((nClasses - 1) * (px - min[band])) / (max[band] - min[band])); |
337 | 13943 | nacho | |
338 | 21306 | bsanchez | if (pos < 0) |
339 | 12383 | nacho | pos = 0;
|
340 | 21306 | bsanchez | |
341 | if (pos >= nClasses)
|
||
342 | 12383 | nacho | pos = nClasses - 1;
|
343 | 21306 | bsanchez | |
344 | 12383 | nacho | table[band][pos]++; |
345 | } |
||
346 | |||
347 | /**
|
||
348 | 20836 | bsanchez | * Calculo de estad?sticas a partir de un histograma. El resultado de la funci?n es un array
|
349 | * bidimensional donde el primer ?ndice inndica la estadistica y el segundo el n?mero de banda.
|
||
350 | *
|
||
351 | * <UL>
|
||
352 | * <LI>m?nimo</LI>
|
||
353 | * <LI>m?ximo</LI>
|
||
354 | * <LI>media</LI>
|
||
355 | * <LI>mediana</LI>
|
||
356 | * <LI>N?mero de pixels</LI>
|
||
357 | * </UL>
|
||
358 | * @param histogram
|
||
359 | * @param bandas solicitadas. Cada elemento del vector representa una banda. Si est? a true se calcula la
|
||
360 | * estadistica para esa banda y si est? a false no se calcular?.
|
||
361 | * @return
|
||
362 | */
|
||
363 | public double[][] getBasicStats(boolean[] bands) { |
||
364 | if (histogram == null) |
||
365 | return null; |
||
366 | return getBasicStats(0, histogram[0].length - 1, bands); |
||
367 | } |
||
368 | 12383 | nacho | |
369 | 20836 | bsanchez | /**
|
370 | * Calculo de estad?sticas a partir de un histograma. El resultado de la funci?n es un array
|
||
371 | * bidimensional donde el primer ?ndice inndica la estadistica y el segundo el n?mero de banda.
|
||
372 | *
|
||
373 | * <UL>
|
||
374 | * <LI>m?nimo</LI>
|
||
375 | * <LI>m?ximo</LI>
|
||
376 | * <LI>media</LI>
|
||
377 | * <LI>mediana</LI>
|
||
378 | * <LI>N?mero de pixels</LI>
|
||
379 | * </UL>
|
||
380 | * @param histogram
|
||
381 | * @param beginPos Posici?n de inicio del histograma para contabilizar estadisticas
|
||
382 | * @param endPos Posici?n de fin del histograma para contabilizar estadisticas
|
||
383 | * @param bandas solicitadas. Cada elemento del vector representa una banda. Si est? a true se calcula la
|
||
384 | * estadistica para esa banda y si est? a false no se calcular?.
|
||
385 | * @return
|
||
386 | */
|
||
387 | public double[][] getBasicStats(double beginPos2, double endPos2, boolean[] bands) { |
||
388 | 13646 | bsanchez | if (histogram == null) |
389 | getHistogram(); |
||
390 | |||
391 | int beginPos = (int) ((beginPos2 * (nClasses - 1)) / 100.0); |
||
392 | int endPos = (int) ((endPos2 * (nClasses - 1)) / 100.0); |
||
393 | |||
394 | // Contamos el n?mero de bandas para las cuales se calcula la estad?stica
|
||
395 | int bandCount = 0; |
||
396 | for (int iBand = 0; iBand < bands.length; iBand++) |
||
397 | if (bands[iBand])
|
||
398 | bandCount++; |
||
399 | |||
400 | double[][] res = new double[5][]; |
||
401 | |||
402 | double[] min = new double[bandCount];// M?nimo |
||
403 | double[] max = new double[bandCount];// M?ximo |
||
404 | for (int iBand = 0; iBand < bandCount; iBand++) { |
||
405 | max[iBand] = Double.NEGATIVE_INFINITY;
|
||
406 | min[iBand] = Double.POSITIVE_INFINITY;
|
||
407 | } |
||
408 | double[] average = new double[bandCount]; // Valor de pixel medio (Media) |
||
409 | double[] middle = new double[bandCount]; // Mediana |
||
410 | double[] nPixelsBand = new double[bandCount];// N?mero de pixels por banda |
||
411 | |||
412 | int showBandCounter = 0; // Contador de bandas de las que hay calcular la |
||
413 | 20836 | bsanchez | // estadistica
|
414 | 13646 | bsanchez | for (int iBand = 0; iBand < histogram.length; iBand++) { |
415 | if (bands[iBand]) {
|
||
416 | for (int i = beginPos; i <= endPos; i++) { |
||
417 | // Calculo del m?nimo
|
||
418 | if (histogram[iBand][i].getValue() != 0 && histogram[iBand][i].getMin() < min[showBandCounter]) |
||
419 | min[showBandCounter] = histogram[iBand][i].getMin(); |
||
420 | |||
421 | // Calculo del m?ximo
|
||
422 | if (histogram[iBand][i].getValue() != 0 && histogram[iBand][i].getMax() > max[showBandCounter]) |
||
423 | 21543 | bsanchez | max[showBandCounter] = histogram[iBand][i].getMin(); |
424 | 13646 | bsanchez | |
425 | // Calculo del n?mero de pixeles
|
||
426 | nPixelsBand[showBandCounter] += histogram[iBand][i].getValue(); |
||
427 | |||
428 | average[showBandCounter] += histogram[iBand][i].getValue() * ((histogram[iBand][i].getMax() + histogram[iBand][i].getMin())/2);
|
||
429 | } |
||
430 | // Calculo de la media
|
||
431 | try {
|
||
432 | average[showBandCounter] /= nPixelsBand[showBandCounter]; |
||
433 | } catch (ArithmeticException exc) { |
||
434 | average[showBandCounter] = 0;
|
||
435 | } |
||
436 | |||
437 | // Calculo de mediana
|
||
438 | double stopPos = nPixelsBand[showBandCounter] / 2; |
||
439 | int aux = 0; |
||
440 | int i = beginPos;
|
||
441 | for (i = beginPos; aux <= stopPos; i++) {
|
||
442 | 14437 | bsanchez | if (i >= histogram[iBand].length)
|
443 | break;
|
||
444 | 13925 | nacho | try {
|
445 | aux += histogram[iBand][i].getValue(); |
||
446 | } catch (ArrayIndexOutOfBoundsException e) { |
||
447 | 27016 | csanchez | LoggerFactory.getLogger(getClass().getName()).debug("Acceso a un valor de histogram (Banda: " + iBand + " Posici?n: " + i + ") fuera de l?mites. (NBandas: " + histogram.length + " Valores:" + histogram[iBand].length + ")", e); |
448 | 13925 | nacho | } |
449 | 13646 | bsanchez | } |
450 | middle[showBandCounter] = (histogram[iBand][i - 1].getMax() + histogram[iBand][i - 1].getMin()) / 2; |
||
451 | |||
452 | showBandCounter++; |
||
453 | 12383 | nacho | } |
454 | 13646 | bsanchez | } |
455 | 20836 | bsanchez | |
456 | res[0] = min;
|
||
457 | res[1] = max;
|
||
458 | res[2] = average;
|
||
459 | res[3] = middle;
|
||
460 | res[4] = nPixelsBand;
|
||
461 | return res;
|
||
462 | } |
||
463 | |||
464 | /**
|
||
465 | * Obtiene la tabla de valores
|
||
466 | * @return
|
||
467 | */
|
||
468 | public long[][] getTable() { |
||
469 | return table;
|
||
470 | } |
||
471 | |||
472 | /**
|
||
473 | * Obtiene la tabla de valores normalizada. Divide todos los elementos por el n?mero de
|
||
474 | * pixeles total.
|
||
475 | * @return tabla de valores normalizada
|
||
476 | */
|
||
477 | public static double[][] convertToNormalizeHistogram(long[][] tableToConvert) { |
||
478 | long[] nValues = new long[tableToConvert.length]; |
||
479 | for (int i = 0; i < tableToConvert.length; i++) |
||
480 | for (int j = 0; j < tableToConvert[i].length; j++) |
||
481 | nValues[i] += tableToConvert[i][j]; |
||
482 | |||
483 | double[][] res = new double[tableToConvert.length][tableToConvert[0].length]; |
||
484 | for (int i = 0; i < tableToConvert.length; i++) |
||
485 | for (int j = 0; j < tableToConvert[i].length; j++) |
||
486 | res[i][j] = (double)((double)tableToConvert[i][j] / (double)nValues[i]); |
||
487 | 19453 | nbrodin | |
488 | 20836 | bsanchez | return res;
|
489 | } |
||
490 | |||
491 | /**
|
||
492 | * Obtiene la tabla de valores normalizada y acumulada. Divide todos los elementos por el n?mero de
|
||
493 | * pixeles total.
|
||
494 | * @return tabla de valores normalizada
|
||
495 | */
|
||
496 | public static double[][] convertTableToNormalizeAccumulate(long[][] tableToConvert) { |
||
497 | double[][] res = convertToNormalizeHistogram(tableToConvert); |
||
498 | for (int i = 0; i < tableToConvert.length; i++) |
||
499 | for (int j = 0; j < tableToConvert[i].length; j++) |
||
500 | if(j > 0) |
||
501 | res[i][j] += res[i][j - 1];
|
||
502 | 19453 | nbrodin | |
503 | 20836 | bsanchez | return res;
|
504 | } |
||
505 | |||
506 | /**
|
||
507 | * Obtiene el histograma de la imagen negativa.
|
||
508 | * @return long[][]
|
||
509 | */
|
||
510 | public long[][] getNegativeTable() { |
||
511 | long[][] tableNeg = new long[table.length][table[0].length]; |
||
512 | for (int i = 0; i < tableNeg.length; i++) |
||
513 | for (int j = 0; j < tableNeg[i].length; j++) |
||
514 | tableNeg[i][table[i].length - j - 1] = table[i][j];
|
||
515 | return tableNeg;
|
||
516 | } |
||
517 | 19453 | nbrodin | |
518 | 20836 | bsanchez | /**
|
519 | * Convierte un histograma al rango de valores de RGB, en pocas palabras
|
||
520 | * aplica una operacion 0xff a cada pixel para quitar los numeros negativos
|
||
521 | * y desplazarlos a su rango visual.
|
||
522 | * @param histogram
|
||
523 | */
|
||
524 | public static Histogram convertHistogramToRGB(Histogram histogram) { |
||
525 | 20454 | bsanchez | if (histogram == null) |
526 | 21306 | bsanchez | return null; |
527 | |||
528 | 21543 | bsanchez | if (histogram.dataType != IBuffer.TYPE_BYTE)
|
529 | 20836 | bsanchez | return histogram;
|
530 | 21306 | bsanchez | |
531 | double min = histogram.getMin(0); |
||
532 | double max = histogram.getMax(0); |
||
533 | 19453 | nbrodin | |
534 | 20836 | bsanchez | long table2[][] = histogram.getTable(); |
535 | 19453 | nbrodin | |
536 | 20836 | bsanchez | long newTable[][] = new long[table2.length][table2[0].length]; |
537 | 19453 | nbrodin | |
538 | 20836 | bsanchez | // Ponemos a cero todos los valores
|
539 | for (int i = 0; i < table2.length; i++) |
||
540 | for (int j = 0; j < table2[i].length; j++) |
||
541 | newTable[i][j] = 0;
|
||
542 | 19453 | nbrodin | |
543 | 20836 | bsanchez | // Sumamos en la posicion calculada nueva el valor correspondiente
|
544 | for (int i = 0; i < table2.length; i++) { |
||
545 | for (int j = 0; j < table2[i].length; j++) { |
||
546 | double val = ((j * (max - min)) / 255) + min; |
||
547 | int pos = ((int) val) & 0xff; |
||
548 | if (pos < 0) |
||
549 | pos = 0;
|
||
550 | 21543 | bsanchez | if (pos >= newTable[i].length)
|
551 | pos = newTable[i].length - 1;
|
||
552 | 19453 | nbrodin | |
553 | 20836 | bsanchez | newTable[i][pos] += table2[i][j]; |
554 | } |
||
555 | } |
||
556 | 19453 | nbrodin | |
557 | 21306 | bsanchez | double mins[] = new double[histogram.getNumBands()]; |
558 | double maxs[] = new double[histogram.getNumBands()]; |
||
559 | |||
560 | for (int i = 0; i < mins.length; i++) { |
||
561 | mins[i] = 0;
|
||
562 | maxs[i] = 255;
|
||
563 | } |
||
564 | 19453 | nbrodin | |
565 | 21543 | bsanchez | Histogram histogramNew = new Histogram(histogram.getNumBands(), mins, maxs, IBuffer.TYPE_BYTE);
|
566 | 21306 | bsanchez | |
567 | 20836 | bsanchez | histogramNew.setTable(newTable); |
568 | 19453 | nbrodin | |
569 | 20836 | bsanchez | return histogramNew;
|
570 | } |
||
571 | |||
572 | /**
|
||
573 | * @param noDataValue the noDataValue to set
|
||
574 | */
|
||
575 | public void setNoDataValue(double noDataValue) { |
||
576 | this.noDataValue = noDataValue;
|
||
577 | } |
||
578 | 12383 | nacho | } |