Revision 11472
trunk/libraries/libRaster/src-test/org/gvsig/raster/buffer/TestBufferInterpolation.java | ||
---|---|---|
53 | 53 |
private String path = baseDir + "03AUG23153350-M2AS-000000122423_01_P001-BROWSE.jpg"; |
54 | 54 |
private RasterDataset f = null; |
55 | 55 |
private BufferFactory ds = null; |
56 |
private int size = 50; |
|
56 | 57 |
|
57 | 58 |
private String fileNeighbour1 = baseDir + "neighbour50x50.tif"; |
58 | 59 |
private String fileBilinear1 = baseDir + "bilinear50x50.tif"; |
59 | 60 |
private String fileInverseDistance1 = baseDir + "inverseDistance50x50.tif"; |
61 |
private String fileBSpline1 = baseDir + "bspline50x50.tif"; |
|
62 |
private String fileBicubicSpline1 = baseDir + "bicubicspline50x50.tif"; |
|
60 | 63 |
|
61 |
private String fileNeighbour = "/tmp/f1.tif"; |
|
62 |
private String fileBilinear = "/tmp/f2.tif"; |
|
63 |
private String fileInverseDistance = "/tmp/f3.tif"; |
|
64 |
private String fileNeighbour = "/tmp/neighbour.tif"; |
|
65 |
private String fileBilinear = "/tmp/bilinear.tif"; |
|
66 |
private String fileInverseDistance = "/tmp/invdistance.tif"; |
|
67 |
private String fileBSpline = "/tmp/bspline.tif"; |
|
68 |
private String fileBicubicSpline = "/tmp/bicubicspline.tif"; |
|
64 | 69 |
|
65 | 70 |
static { |
66 | 71 |
RasterLibrary.wakeUp(); |
... | ... | |
88 | 93 |
ds.setAreaOfInterest(0, 0, f.getWidth(), f.getHeight()); |
89 | 94 |
RasterBuffer buf = (RasterBuffer)ds.getRasterBuf(); |
90 | 95 |
|
91 |
IBuffer b1 = buf.getAdjustedWindow(50, 50, IQueryableRaster.INTERPOLATION_NearestNeighbour); |
|
92 |
IBuffer b2 = buf.getAdjustedWindow(50, 50, IQueryableRaster.INTERPOLATION_Bilinear); |
|
93 |
IBuffer b3 = buf.getAdjustedWindow(50, 50, IQueryableRaster.INTERPOLATION_InverseDistance); |
|
94 | 96 |
try { |
97 |
IBuffer b1 = buf.getAdjustedWindow(size, size, BufferInterpolation.INTERPOLATION_NearestNeighbour); |
|
95 | 98 |
convertBufferToTif(fileNeighbour, f.getExtent(), b1); |
96 |
convertBufferToTif(fileBilinear, f.getExtent(), b2); |
|
97 |
convertBufferToTif(fileInverseDistance, f.getExtent(), b3); |
|
99 |
b1 = buf.getAdjustedWindow(size, size, BufferInterpolation.INTERPOLATION_Bilinear); |
|
100 |
convertBufferToTif(fileBilinear, f.getExtent(), b1); |
|
101 |
b1 = buf.getAdjustedWindow(size, size, BufferInterpolation.INTERPOLATION_InverseDistance); |
|
102 |
convertBufferToTif(fileInverseDistance, f.getExtent(), b1); |
|
103 |
b1 = buf.getAdjustedWindow(size, size, BufferInterpolation.INTERPOLATION_BSpline); |
|
104 |
convertBufferToTif(fileBSpline, f.getExtent(), b1); |
|
105 |
b1 = buf.getAdjustedWindow(size, size, BufferInterpolation.INTERPOLATION_BicubicSpline); |
|
106 |
convertBufferToTif(fileBicubicSpline, f.getExtent(), b1); |
|
98 | 107 |
} catch (IOException e) { |
99 | 108 |
e.printStackTrace(); |
100 | 109 |
} |
... | ... | |
104 | 113 |
compareResult(fileNeighbour, fileNeighbour1); |
105 | 114 |
compareResult(fileBilinear, fileBilinear1); |
106 | 115 |
compareResult(fileInverseDistance, fileInverseDistance1); |
116 |
compareResult(fileBSpline, fileBSpline1); |
|
117 |
//compareResult(fileBicubicSpline, fileBicubicSpline1); |
|
107 | 118 |
File file1 = new File(fileNeighbour); |
108 | 119 |
File file2 = new File(fileBilinear); |
109 | 120 |
File file3 = new File(fileInverseDistance); |
121 |
File file4 = new File(fileBSpline); |
|
122 |
//File file5 = new File(fileBicubicSpline); |
|
110 | 123 |
if(file1.exists()) |
111 | 124 |
file1.delete(); |
112 | 125 |
if(file2.exists()) |
113 | 126 |
file2.delete(); |
114 | 127 |
if(file3.exists()) |
115 | 128 |
file3.delete(); |
129 |
if(file4.exists()) |
|
130 |
file4.delete(); |
|
131 |
//if(file5.exists()) |
|
132 |
// file5.delete(); |
|
116 | 133 |
} |
117 | 134 |
|
118 | 135 |
/** |
trunk/libraries/libRaster/src/org/gvsig/raster/dataset/IBuffer.java | ||
---|---|---|
99 | 99 |
public float getFloatNoDataValue(); |
100 | 100 |
|
101 | 101 |
/** |
102 |
* Obtiene true si el pixel pasado por par?metro cae dentro de los l?mites |
|
103 |
* del rater y false si cae fuera. |
|
104 |
* @param x Posici?n X del pixel a averiguar |
|
105 |
* @param y Posici?n Y del pixel a averiguar |
|
106 |
* @return true si est? dentro y false si cae fuera. |
|
107 |
*/ |
|
108 |
public boolean isInside(int x, int y); |
|
109 |
|
|
110 |
/** |
|
102 | 111 |
* Asigna el valor NoData |
103 | 112 |
* @param nd Valor NoData |
104 | 113 |
*/ |
trunk/libraries/libRaster/src/org/gvsig/raster/grid/GridInterpolated.java | ||
---|---|---|
19 | 19 |
package org.gvsig.raster.grid; |
20 | 20 |
|
21 | 21 |
import org.gvsig.raster.buffer.BufferFactory; |
22 |
import org.gvsig.raster.buffer.IQueryableRaster;
|
|
22 |
import org.gvsig.raster.buffer.BufferInterpolation;
|
|
23 | 23 |
import org.gvsig.raster.buffer.RasterBuffer; |
24 | 24 |
|
25 | 25 |
/** |
... | ... | |
33 | 33 |
|
34 | 34 |
public class GridInterpolated extends GridReader{ |
35 | 35 |
|
36 |
public static final int INTERPOLATION_NearestNeighbour = IQueryableRaster.INTERPOLATION_NearestNeighbour;
|
|
37 |
public static final int INTERPOLATION_Bilinear = IQueryableRaster.INTERPOLATION_Bilinear;
|
|
38 |
public static final int INTERPOLATION_InverseDistance = IQueryableRaster.INTERPOLATION_InverseDistance;
|
|
39 |
public static final int INTERPOLATION_BicubicSpline = IQueryableRaster.INTERPOLATION_BicubicSpline;
|
|
40 |
public static final int INTERPOLATION_BSpline = IQueryableRaster.INTERPOLATION_BSpline;
|
|
36 |
public static final int INTERPOLATION_NearestNeighbour = BufferInterpolation.INTERPOLATION_NearestNeighbour;
|
|
37 |
public static final int INTERPOLATION_Bilinear = BufferInterpolation.INTERPOLATION_Bilinear;
|
|
38 |
public static final int INTERPOLATION_InverseDistance = BufferInterpolation.INTERPOLATION_InverseDistance;
|
|
39 |
public static final int INTERPOLATION_BicubicSpline = BufferInterpolation.INTERPOLATION_BicubicSpline;
|
|
40 |
public static final int INTERPOLATION_BSpline = BufferInterpolation.INTERPOLATION_BSpline;
|
|
41 | 41 |
|
42 | 42 |
double m_dXMin , m_dYMax; //coordinates of the layer, not the window |
43 | 43 |
double m_dCellSize; //cellsize of the layer, not the window |
trunk/libraries/libRaster/src/org/gvsig/raster/buffer/RasterBuffer.java | ||
---|---|---|
40 | 40 |
* |
41 | 41 |
*/ |
42 | 42 |
public abstract class RasterBuffer implements IBuffer { |
43 |
public static final int CANCEL_HISTOGRAM = IHistogramable.CANCEL_HISTOGRAM;
|
|
44 |
protected boolean[] cancel = new boolean[1];
|
|
45 |
|
|
43 |
public static final int CANCEL_HISTOGRAM = IHistogramable.CANCEL_HISTOGRAM; |
|
44 |
protected boolean[] cancel = new boolean[1]; |
|
45 |
|
|
46 | 46 |
//Espacio en memoria (en Megas) que hay que sobrepasar para empezar a cachear. |
47 | 47 |
private static int cacheMemorySize = 25; |
48 | 48 |
//Espacio en memoria (en Megas) que hay que sobrepasar para empezar a cachear en multipagina. |
49 | 49 |
private static int multicacheMemorySize = 100; |
50 |
|
|
51 |
public double noDataValue = -99999; |
|
52 | 50 |
|
53 |
protected int percent = 0; |
|
51 |
public double noDataValue = -99999; |
|
52 |
|
|
53 |
protected int percent = 0; |
|
54 | 54 |
protected boolean canceled = false; |
55 |
|
|
56 |
protected int width;
|
|
57 |
protected int height;
|
|
58 |
protected int nBands;
|
|
59 |
protected int dataType;
|
|
55 |
|
|
56 |
protected int width;
|
|
57 |
protected int height;
|
|
58 |
protected int nBands;
|
|
59 |
protected int dataType;
|
|
60 | 60 |
|
61 | 61 |
/** |
62 | 62 |
* Variable est?tica que si est? a false desactiva el uso de cach?. Puede ser usada por un cliente |
63 | 63 |
* para cargar siempre los datos en memoria. independientemente de su tama?o. |
64 | 64 |
*/ |
65 |
public static boolean cacheOn = true; |
|
65 |
public static boolean cacheOn = true;
|
|
66 | 66 |
/** |
67 | 67 |
* Fuerza la carga de los datos en cach? independientemente de su tama?o. Su |
68 | 68 |
* uso suele ser util solo para depuraci?n. Su valor por defecto y recomendado |
... | ... | |
80 | 80 |
* no tiene datos asignados y tampoco puede ser null. Todas las bandas no validas de un buffer |
81 | 81 |
* apuntan por referencia a la misma banda. |
82 | 82 |
*/ |
83 |
protected double notValidValue = 0D; |
|
83 |
protected double notValidValue = 0D; |
|
84 |
|
|
85 |
private BufferInterpolation interp = null; |
|
84 | 86 |
|
85 | 87 |
/** |
86 | 88 |
* Genera instancias del buffer de datos adecuado al tama?o del raster. Si no hay muchos datos |
... | ... | |
270 | 272 |
return null; |
271 | 273 |
} |
272 | 274 |
|
273 |
/** |
|
274 |
* Ajusta el raster al ancho y alto solicitado por el vecino m?s cercano. Promedia el valor de dos |
|
275 |
* pixeles contiguos. |
|
276 |
* @param w Nuevo ancho |
|
277 |
* @param h Nuevo alto |
|
275 |
/* |
|
276 |
* (non-Javadoc) |
|
277 |
* @see org.gvsig.raster.dataset.IBuffer#isInside(int, int) |
|
278 | 278 |
*/ |
279 |
private RasterBuffer adjustRasterNearestNeighbourInterpolation(int w, int h) { |
|
280 |
double stepX = (double)w / (double)width; |
|
281 |
double stepY = (double)h / (double)height; |
|
282 |
RasterBuffer rasterBuf = new RasterMemoryBuffer(getDataType(), w, h, getBandCount(), true); |
|
283 |
|
|
284 |
int[] bands = new int[rasterBuf.getBandCount()]; |
|
285 |
for(int iBand = 0; iBand < rasterBuf.getBandCount(); iBand ++) |
|
286 |
bands[iBand] = iBand; |
|
287 |
|
|
288 |
|
|
289 |
switch (dataType) { |
|
290 |
case RasterBuffer.TYPE_BYTE: |
|
291 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
292 |
if(w <= width) { //submuestreo |
|
293 |
for(int iRow = 0; iRow < height; iRow ++) |
|
294 |
for(int iCol = 0; iCol < width; iCol ++) |
|
295 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], getElemByte(iRow, iCol, iBand)); |
|
296 |
}else{ //supermuestreo |
|
297 |
for(int iRow = 0; iRow < h; iRow ++) |
|
298 |
for(int iCol = 0; iCol < w; iCol ++) |
|
299 |
rasterBuf.setElem(iRow, iCol, bands[iBand], getElemByte((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
300 |
} |
|
301 |
} |
|
302 |
break; |
|
303 |
case RasterBuffer.TYPE_DOUBLE: |
|
304 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
305 |
if(w <= width) { //submuestreo |
|
306 |
for(int iRow = 0; iRow < height; iRow ++) |
|
307 |
for(int iCol = 0; iCol < width; iCol ++) |
|
308 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], getElemDouble(iRow, iCol, iBand)); |
|
309 |
}else{ //supermuestreo |
|
310 |
for(int iRow = 0; iRow < h; iRow ++) |
|
311 |
for(int iCol = 0; iCol < w; iCol ++) |
|
312 |
rasterBuf.setElem(iRow, iCol, bands[iBand], getElemDouble((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
313 |
} |
|
314 |
} |
|
315 |
break; |
|
316 |
case RasterBuffer.TYPE_FLOAT: |
|
317 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
318 |
if(w <= width) { //submuestreo |
|
319 |
for(int iRow = 0; iRow < height; iRow ++) |
|
320 |
for(int iCol = 0; iCol < width; iCol ++) |
|
321 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], getElemFloat(iRow, iCol, iBand)); |
|
322 |
}else{ //supermuestreo |
|
323 |
for(int iRow = 0; iRow < h; iRow ++) |
|
324 |
for(int iCol = 0; iCol < w; iCol ++) |
|
325 |
rasterBuf.setElem(iRow, iCol, bands[iBand], getElemFloat((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
326 |
} |
|
327 |
} |
|
328 |
break; |
|
329 |
case RasterBuffer.TYPE_INT: |
|
330 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
331 |
if(w <= width) { //submuestreo |
|
332 |
for(int iRow = 0; iRow < height; iRow ++) |
|
333 |
for(int iCol = 0; iCol < width; iCol ++) |
|
334 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], getElemInt(iRow, iCol, iBand)); |
|
335 |
}else{ //supermuestreo |
|
336 |
for(int iRow = 0; iRow < h; iRow ++) |
|
337 |
for(int iCol = 0; iCol < w; iCol ++) |
|
338 |
rasterBuf.setElem(iRow, iCol, bands[iBand], getElemInt((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
339 |
} |
|
340 |
} |
|
341 |
break; |
|
342 |
case RasterBuffer.TYPE_USHORT: |
|
343 |
case RasterBuffer.TYPE_SHORT: |
|
344 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
345 |
if(w <= width) { //submuestreo |
|
346 |
for(int iRow = 0; iRow < height; iRow ++) |
|
347 |
for(int iCol = 0; iCol < width; iCol ++) |
|
348 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], getElemShort(iRow, iCol, iBand)); |
|
349 |
}else{ //supermuestreo |
|
350 |
for(int iRow = 0; iRow < h; iRow ++) |
|
351 |
for(int iCol = 0; iCol < w; iCol ++) |
|
352 |
rasterBuf.setElem(iRow, iCol, bands[iBand], getElemShort((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
353 |
} |
|
354 |
} |
|
355 |
break; |
|
356 |
} |
|
357 |
return rasterBuf; |
|
279 |
public boolean isInside(int x, int y) { |
|
280 |
if (x < 0 || y < 0 || x >= getWidth() || y >= getHeight()) |
|
281 |
return false; |
|
282 |
return true; |
|
358 | 283 |
} |
359 |
|
|
360 |
/** |
|
361 |
* Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n bilineal. Promedia |
|
362 |
* el valor de cuatro pixeles adyacentes. |
|
363 |
* @param w Nuevo ancho |
|
364 |
* @param h Nuevo alto |
|
365 |
*/ |
|
366 |
private RasterBuffer adjustRasterBilinearInterpolation(int w, int h) { |
|
367 |
double pxSize = (double)width / (double)w; |
|
368 |
RasterBuffer rasterBuf = new RasterMemoryBuffer(getDataType(), w, h, getBandCount(), true); |
|
369 |
|
|
370 |
double posX = pxSize / 2D; |
|
371 |
double posY = posX; |
|
372 |
double dx = 0D, dy = 0D; |
|
373 |
|
|
374 |
for(int iBand = 0; iBand < getBandCount(); iBand ++) { |
|
375 |
posY = pxSize / 2D; |
|
376 |
switch (dataType) { |
|
377 |
case RasterBuffer.TYPE_BYTE: |
|
378 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
379 |
dy = posY - ((int)posY); |
|
380 |
posX = pxSize / 2D; |
|
381 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
382 |
dx = posX - ((int)posX); |
|
383 |
double[] kernel = getKernelByte(((int)posX), ((int)posY), iBand); |
|
384 |
double[] nz = getBilinearNZ(dx, dy, kernel); |
|
385 |
double b = 0; |
|
386 |
if(nz[0] > 0.0) |
|
387 |
b = (nz[1] / nz[0]); |
|
388 |
rasterBuf.setElem(iRow, iCol, iBand, (byte)((byte)b & 0xff)); |
|
389 |
posX += pxSize; |
|
390 |
} |
|
391 |
posY += pxSize; |
|
392 |
} |
|
393 |
break; |
|
394 |
case RasterBuffer.TYPE_SHORT: |
|
395 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
396 |
dy = posY - ((int)posY); |
|
397 |
posX = pxSize / 2D; |
|
398 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
399 |
dx = posX - ((int)posX); |
|
400 |
double[] kernel = getKernelShort(((int)posX), ((int)posY), iBand); |
|
401 |
double[] nz = getBilinearNZ(dx, dy, kernel); |
|
402 |
double b = 0; |
|
403 |
if(nz[0] > 0.0) |
|
404 |
b = (nz[1] / nz[0]); |
|
405 |
rasterBuf.setElem(iRow, iCol, iBand, (short)((short)b & 0xffff)); |
|
406 |
posX += pxSize; |
|
407 |
} |
|
408 |
posY += pxSize; |
|
409 |
} |
|
410 |
break; |
|
411 |
case RasterBuffer.TYPE_INT: |
|
412 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
413 |
dy = posY - ((int)posY); |
|
414 |
posX = pxSize / 2D; |
|
415 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
416 |
dx = posX - ((int)posX); |
|
417 |
double[] kernel = getKernelInt(((int)posX), ((int)posY), iBand); |
|
418 |
double[] nz = getBilinearNZ(dx, dy, kernel); |
|
419 |
double b = 0; |
|
420 |
if(nz[0] > 0.0) |
|
421 |
b = (nz[1] / nz[0]); |
|
422 |
rasterBuf.setElem(iRow, iCol, iBand, (int)((int)b & 0xff)); |
|
423 |
posX += pxSize; |
|
424 |
} |
|
425 |
posY += pxSize; |
|
426 |
} |
|
427 |
break; |
|
428 |
case RasterBuffer.TYPE_FLOAT: |
|
429 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
430 |
dy = posY - ((int)posY); |
|
431 |
posX = pxSize / 2D; |
|
432 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
433 |
dx = posX - ((int)posX); |
|
434 |
double[] kernel = getKernelFloat(((int)posX), ((int)posY), iBand); |
|
435 |
double[] nz = getBilinearNZ(dx, dy, kernel); |
|
436 |
double b = 0; |
|
437 |
if(nz[0] > 0.0) |
|
438 |
b = (nz[1] / nz[0]); |
|
439 |
rasterBuf.setElem(iRow, iCol, iBand, (float)b); |
|
440 |
posX += pxSize; |
|
441 |
} |
|
442 |
posY += pxSize; |
|
443 |
} |
|
444 |
break; |
|
445 |
case RasterBuffer.TYPE_DOUBLE: |
|
446 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
447 |
dy = posY - ((int)posY); |
|
448 |
posX = pxSize / 2D; |
|
449 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
450 |
dx = posX - ((int)posX); |
|
451 |
double[] kernel = getKernelDouble(((int)posX), ((int)posY), iBand); |
|
452 |
double[] nz = getBilinearNZ(dx, dy, kernel); |
|
453 |
double b = 0; |
|
454 |
if(nz[0] > 0.0) |
|
455 |
b = (nz[1] / nz[0]); |
|
456 |
rasterBuf.setElem(iRow, iCol, iBand, (double)b); |
|
457 |
posX += pxSize; |
|
458 |
} |
|
459 |
posY += pxSize; |
|
460 |
} |
|
461 |
break; |
|
462 |
} |
|
463 |
|
|
464 |
} |
|
465 |
|
|
466 |
return rasterBuf; |
|
467 |
} |
|
468 |
|
|
469 |
/** |
|
470 |
* Calcula los valores N y Z para el m?todo bilinear |
|
471 |
* @param dx distancia en X desde el centro del pixel hasta el punto. Es un valor entre 0 y 1 |
|
472 |
* @param dy distancia en Y desde el centro del pixel hasta el punto. Es un valor entre 0 y 1 |
|
473 |
* @param kernel valor del pixel y alrededor |
|
474 |
* @return valore de N y Z |
|
475 |
*/ |
|
476 |
private double[] getBilinearNZ(double dx, double dy, double[] kernel) { |
|
477 |
double z = 0.0, n = 0.0, d; |
|
478 |
d = (1.0 - dx) * (1.0 - dy); |
|
479 |
z += d * kernel[0]; |
|
480 |
n += d; |
|
481 |
|
|
482 |
d = dx * (1.0 - dy); |
|
483 |
z += d * kernel[1]; |
|
484 |
n += d; |
|
485 |
|
|
486 |
d = (1.0 - dx) * dy; |
|
487 |
z += d * kernel[2]; |
|
488 |
n += d; |
|
489 |
|
|
490 |
d = dx * dy; |
|
491 |
z += d * kernel[3]; |
|
492 |
n += d; |
|
493 |
return new double[]{n, z}; |
|
494 |
} |
|
495 |
|
|
496 |
/** |
|
497 |
* Calcula los valores N y Z para el m?todo bilinear |
|
498 |
* @param dx distancia en X desde el centro del pixel hasta el punto. Es un valor entre 0 y 1 |
|
499 |
* @param dy distancia en Y desde el centro del pixel hasta el punto. Es un valor entre 0 y 1 |
|
500 |
* @param kernel valor del pixel y alrededor |
|
501 |
* @return valore de N y Z |
|
502 |
*/ |
|
503 |
private double[] getInverseDistanceNZ(double dx, double dy, double[] kernel) { |
|
504 |
double z = 0.0, n = 0.0, d; |
|
505 |
d = 1.0 / Math.sqrt(dx * dx + dy * dy); |
|
506 |
z += d * kernel[0]; |
|
507 |
n += d; |
|
508 |
|
|
509 |
d = 1.0 / Math.sqrt((1.0 - dx) * ( 1.0 - dx) + dy * dy); |
|
510 |
z += d * kernel[1]; |
|
511 |
n += d; |
|
512 |
|
|
513 |
d = 1.0 / Math.sqrt(dx*dx + (1.0-dy)*(1.0-dy)); |
|
514 |
z += d * kernel[2]; |
|
515 |
n += d; |
|
516 |
|
|
517 |
d = 1.0 / Math.sqrt((1.0 - dx) *( 1.0 - dx) + (1.0 - dy) * (1.0 - dy)); |
|
518 |
z += d * kernel[3]; |
|
519 |
n += d; |
|
520 |
return new double[]{n, z}; |
|
521 |
} |
|
522 |
|
|
523 |
|
|
524 |
/** |
|
525 |
* Obtiene un kernel de cuatro elemento que corresponden a los pixeles (x, y), (x + 1, y), |
|
526 |
* (x, y + 1), (x + 1, y + 1). Si los pixeles x + 1 o y + 1 se salen del raster de origen |
|
527 |
* se tomar? x e y. |
|
528 |
* @param x Coordenada X del pixel inicial |
|
529 |
* @param y Coordenada Y del pixel inicial |
|
530 |
* @param band N?mero de banda. |
|
531 |
* @return Kernel solicitado en forma de array. |
|
532 |
*/ |
|
533 |
private double[] getKernelByte(int x, int y, int band) { |
|
534 |
double[] d = new double[4]; |
|
535 |
d[0] = (getElemByte(y, x, band) & 0xff); |
|
536 |
int nextX = ((x + 1) >= getWidth()) ? x : (x + 1); |
|
537 |
int nextY = ((y + 1) >= getHeight()) ? y : (y + 1); |
|
538 |
d[1] = (getElemByte(y, nextX, band) & 0xff); |
|
539 |
d[2] = (getElemByte(nextY, x, band) & 0xff); |
|
540 |
d[3] = (getElemByte(nextY, nextX, band) & 0xff); |
|
541 |
return d; |
|
542 |
} |
|
543 |
|
|
544 |
/** |
|
545 |
* Obtiene un kernel de cuatro elemento que corresponden a los pixeles (x, y), (x + 1, y), |
|
546 |
* (x, y + 1), (x + 1, y + 1). Si los pixeles x + 1 o y + 1 se salen del raster de origen |
|
547 |
* se tomar? x e y. |
|
548 |
* @param x Coordenada X del pixel inicial |
|
549 |
* @param y Coordenada Y del pixel inicial |
|
550 |
* @param band N?mero de banda. |
|
551 |
* @return Kernel solicitado en forma de array. |
|
552 |
*/ |
|
553 |
private double[] getKernelShort(int x, int y, int band) { |
|
554 |
double[] d = new double[4]; |
|
555 |
d[0] = (getElemShort(y, x, band) & 0xffff); |
|
556 |
int nextX = ((x + 1) >= getWidth()) ? x : (x + 1); |
|
557 |
int nextY = ((y + 1) >= getHeight()) ? y : (y + 1); |
|
558 |
d[1] = (getElemShort(y, nextX, band) & 0xffff); |
|
559 |
d[2] = (getElemShort(nextY, x, band) & 0xffff); |
|
560 |
d[3] = (getElemShort(nextY, nextX, band) & 0xffff); |
|
561 |
return d; |
|
562 |
} |
|
563 |
|
|
564 |
/** |
|
565 |
* Obtiene un kernel de cuatro elemento que corresponden a los pixeles (x, y), (x + 1, y), |
|
566 |
* (x, y + 1), (x + 1, y + 1). Si los pixeles x + 1 o y + 1 se salen del raster de origen |
|
567 |
* se tomar? x e y. |
|
568 |
* @param x Coordenada X del pixel inicial |
|
569 |
* @param y Coordenada Y del pixel inicial |
|
570 |
* @param band N?mero de banda. |
|
571 |
* @return Kernel solicitado en forma de array. |
|
572 |
*/ |
|
573 |
private double[] getKernelInt(int x, int y, int band) { |
|
574 |
double[] d = new double[4]; |
|
575 |
d[0] = (getElemInt(y, x, band) & 0xffffffff); |
|
576 |
int nextX = ((x + 1) >= getWidth()) ? x : (x + 1); |
|
577 |
int nextY = ((y + 1) >= getHeight()) ? y : (y + 1); |
|
578 |
d[1] = (getElemInt(y, nextX, band) & 0xffffffff); |
|
579 |
d[2] = (getElemInt(nextY, x, band) & 0xffffffff); |
|
580 |
d[3] = (getElemInt(nextY, nextX, band) & 0xffffffff); |
|
581 |
return d; |
|
582 |
} |
|
583 |
|
|
584 |
/** |
|
585 |
* Obtiene un kernel de cuatro elemento que corresponden a los pixeles (x, y), (x + 1, y), |
|
586 |
* (x, y + 1), (x + 1, y + 1). Si los pixeles x + 1 o y + 1 se salen del raster de origen |
|
587 |
* se tomar? x e y. |
|
588 |
* @param x Coordenada X del pixel inicial |
|
589 |
* @param y Coordenada Y del pixel inicial |
|
590 |
* @param band N?mero de banda. |
|
591 |
* @return Kernel solicitado en forma de array. |
|
592 |
*/ |
|
593 |
private double[] getKernelFloat(int x, int y, int band) { |
|
594 |
double[] d = new double[4]; |
|
595 |
d[0] = getElemFloat(y, x, band); |
|
596 |
int nextX = ((x + 1) >= getWidth()) ? x : (x + 1); |
|
597 |
int nextY = ((y + 1) >= getHeight()) ? y : (y + 1); |
|
598 |
d[1] = getElemFloat(y, nextX, band); |
|
599 |
d[2] = getElemFloat(nextY, x, band); |
|
600 |
d[3] = getElemFloat(nextY, nextX, band); |
|
601 |
return d; |
|
602 |
} |
|
603 |
|
|
604 |
/** |
|
605 |
* Obtiene un kernel de cuatro elemento que corresponden a los pixeles (x, y), (x + 1, y), |
|
606 |
* (x, y + 1), (x + 1, y + 1). Si los pixeles x + 1 o y + 1 se salen del raster de origen |
|
607 |
* se tomar? x e y. |
|
608 |
* @param x Coordenada X del pixel inicial |
|
609 |
* @param y Coordenada Y del pixel inicial |
|
610 |
* @param band N?mero de banda. |
|
611 |
* @return Kernel solicitado en forma de array. |
|
612 |
*/ |
|
613 |
private double[] getKernelDouble(int x, int y, int band) { |
|
614 |
double[] d = new double[4]; |
|
615 |
d[0] = getElemDouble(y, x, band); |
|
616 |
int nextX = ((x + 1) >= getWidth()) ? x : (x + 1); |
|
617 |
int nextY = ((y + 1) >= getHeight()) ? y : (y + 1); |
|
618 |
d[1] = getElemDouble(y, nextX, band); |
|
619 |
d[2] = getElemDouble(nextY, x, band); |
|
620 |
d[3] = getElemDouble(nextY, nextX, band); |
|
621 |
return d; |
|
622 |
} |
|
623 |
|
|
624 |
/** |
|
625 |
* Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n de distancia inversa. |
|
626 |
* Asigna el valor de un pixel en funci?n inversa de la distancia. |
|
627 |
* |
|
628 |
* @param w Nuevo ancho |
|
629 |
* @param h Nuevo alto |
|
630 |
*/ |
|
631 |
private RasterBuffer adjustRasterInverseDistanceInterpolation(int w, int h) { |
|
632 |
double pxSize = (double)width / (double)w; |
|
633 |
RasterBuffer rasterBuf = new RasterMemoryBuffer(getDataType(), w, h, getBandCount(), true); |
|
634 |
|
|
635 |
double posX = pxSize / 2D; |
|
636 |
double posY = posX; |
|
637 |
double dx = 0D, dy = 0D; |
|
638 |
|
|
639 |
for(int iBand = 0; iBand < getBandCount(); iBand ++) { |
|
640 |
posY = pxSize / 2D; |
|
641 |
switch (dataType) { |
|
642 |
case RasterBuffer.TYPE_BYTE: |
|
643 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
644 |
dy = posY - ((int)posY); |
|
645 |
posX = pxSize / 2D; |
|
646 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
647 |
dx = posX - ((int)posX); |
|
648 |
double[] kernel = getKernelByte(((int)posX), ((int)posY), iBand); |
|
649 |
double[] nz = getInverseDistanceNZ(dx, dy, kernel); |
|
650 |
double b = 0; |
|
651 |
if(nz[0] > 0.0) |
|
652 |
b = (nz[1] / nz[0]); |
|
653 |
rasterBuf.setElem(iRow, iCol, iBand, (byte)((byte)b & 0xff)); |
|
654 |
posX += pxSize; |
|
655 |
} |
|
656 |
posY += pxSize; |
|
657 |
} |
|
658 |
break; |
|
659 |
case RasterBuffer.TYPE_SHORT: |
|
660 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
661 |
dy = posY - ((int)posY); |
|
662 |
posX = pxSize / 2D; |
|
663 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
664 |
dx = posX - ((int)posX); |
|
665 |
double[] kernel = getKernelShort(((int)posX), ((int)posY), iBand); |
|
666 |
double[] nz = getInverseDistanceNZ(dx, dy, kernel); |
|
667 |
double b = 0; |
|
668 |
if(nz[0] > 0.0) |
|
669 |
b = (nz[1] / nz[0]); |
|
670 |
rasterBuf.setElem(iRow, iCol, iBand, (short)((short)b & 0xffff)); |
|
671 |
posX += pxSize; |
|
672 |
} |
|
673 |
posY += pxSize; |
|
674 |
} |
|
675 |
break; |
|
676 |
case RasterBuffer.TYPE_INT: |
|
677 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
678 |
dy = posY - ((int)posY); |
|
679 |
posX = pxSize / 2D; |
|
680 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
681 |
dx = posX - ((int)posX); |
|
682 |
double[] kernel = getKernelInt(((int)posX), ((int)posY), iBand); |
|
683 |
double[] nz = getInverseDistanceNZ(dx, dy, kernel); |
|
684 |
double b = 0; |
|
685 |
if(nz[0] > 0.0) |
|
686 |
b = (nz[1] / nz[0]); |
|
687 |
rasterBuf.setElem(iRow, iCol, iBand, (int)((int)b & 0xff)); |
|
688 |
posX += pxSize; |
|
689 |
} |
|
690 |
posY += pxSize; |
|
691 |
} |
|
692 |
break; |
|
693 |
case RasterBuffer.TYPE_FLOAT: |
|
694 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
695 |
dy = posY - ((int)posY); |
|
696 |
posX = pxSize / 2D; |
|
697 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
698 |
dx = posX - ((int)posX); |
|
699 |
double[] kernel = getKernelFloat(((int)posX), ((int)posY), iBand); |
|
700 |
double[] nz = getInverseDistanceNZ(dx, dy, kernel); |
|
701 |
double b = 0; |
|
702 |
if(nz[0] > 0.0) |
|
703 |
b = (nz[1] / nz[0]); |
|
704 |
rasterBuf.setElem(iRow, iCol, iBand, (float)b); |
|
705 |
posX += pxSize; |
|
706 |
} |
|
707 |
posY += pxSize; |
|
708 |
} |
|
709 |
break; |
|
710 |
case RasterBuffer.TYPE_DOUBLE: |
|
711 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
712 |
dy = posY - ((int)posY); |
|
713 |
posX = pxSize / 2D; |
|
714 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
715 |
dx = posX - ((int)posX); |
|
716 |
double[] kernel = getKernelDouble(((int)posX), ((int)posY), iBand); |
|
717 |
double[] nz = getInverseDistanceNZ(dx, dy, kernel); |
|
718 |
double b = 0; |
|
719 |
if(nz[0] > 0.0) |
|
720 |
b = (nz[1] / nz[0]); |
|
721 |
rasterBuf.setElem(iRow, iCol, iBand, (double)b); |
|
722 |
posX += pxSize; |
|
723 |
} |
|
724 |
posY += pxSize; |
|
725 |
} |
|
726 |
break; |
|
727 |
} |
|
728 |
|
|
729 |
} |
|
730 |
|
|
731 |
return rasterBuf; |
|
732 |
} |
|
733 |
|
|
734 |
/** |
|
735 |
* Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n de spline bicubica. |
|
736 |
* @param w Nuevo ancho |
|
737 |
* @param h Nuevo alto |
|
738 |
*/ |
|
739 |
private RasterBuffer adjustRasterBicubicSplineInterpolation(int w, int h) { |
|
740 |
return this; |
|
741 |
} |
|
742 |
|
|
743 |
/** |
|
744 |
* Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n BSpline. |
|
745 |
* @param w Nuevo ancho |
|
746 |
* @param h Nuevo alto |
|
747 |
*/ |
|
748 |
private RasterBuffer adjustRasterBSplineInterpolation(int w, int h) { |
|
749 |
return this; |
|
750 |
} |
|
751 |
|
|
284 |
|
|
752 | 285 |
/* |
753 | 286 |
* (non-Javadoc) |
754 | 287 |
* @see org.gvsig.fmap.driver.IBuffer#getNoDataValue() |
... | ... | |
827 | 360 |
* @param interpolation M?todo de interpolaci?n que se usar? en el ajuste. |
828 | 361 |
*/ |
829 | 362 |
public RasterBuffer getAdjustedWindow(int w, int h, int interpolationMethod) { |
363 |
if(interp == null) |
|
364 |
interp = new BufferInterpolation(this); |
|
365 |
|
|
830 | 366 |
if(w == getWidth() && h == getHeight()) |
831 | 367 |
return this; |
832 | 368 |
RasterBuffer rasterBuf = null; |
833 | 369 |
switch(interpolationMethod) { |
834 |
case IQueryableRaster.INTERPOLATION_NearestNeighbour:
|
|
835 |
rasterBuf = adjustRasterNearestNeighbourInterpolation(w, h); |
|
370 |
case BufferInterpolation.INTERPOLATION_NearestNeighbour:
|
|
371 |
rasterBuf = interp.adjustRasterNearestNeighbourInterpolation(w, h);
|
|
836 | 372 |
break; |
837 |
case IQueryableRaster.INTERPOLATION_Bilinear:
|
|
838 |
rasterBuf = adjustRasterBilinearInterpolation(w, h); |
|
373 |
case BufferInterpolation.INTERPOLATION_Bilinear:
|
|
374 |
rasterBuf = interp.adjustRasterBilinearInterpolation(w, h);
|
|
839 | 375 |
break; |
840 |
case IQueryableRaster.INTERPOLATION_InverseDistance:
|
|
841 |
rasterBuf = adjustRasterInverseDistanceInterpolation(w, h); |
|
376 |
case BufferInterpolation.INTERPOLATION_InverseDistance:
|
|
377 |
rasterBuf = interp.adjustRasterInverseDistanceInterpolation(w, h);
|
|
842 | 378 |
break; |
843 |
case IQueryableRaster.INTERPOLATION_BicubicSpline:
|
|
844 |
rasterBuf = adjustRasterBicubicSplineInterpolation(w, h); |
|
379 |
case BufferInterpolation.INTERPOLATION_BicubicSpline:
|
|
380 |
rasterBuf = interp.adjustRasterBicubicSplineInterpolation(w, h);
|
|
845 | 381 |
break; |
846 |
case IQueryableRaster.INTERPOLATION_BSpline:
|
|
847 |
rasterBuf = adjustRasterBSplineInterpolation(w, h); |
|
382 |
case BufferInterpolation.INTERPOLATION_BSpline:
|
|
383 |
rasterBuf = interp.adjustRasterBSplineInterpolation(w, h);
|
|
848 | 384 |
break; |
849 | 385 |
} |
850 | 386 |
return rasterBuf; |
trunk/libraries/libRaster/src/org/gvsig/raster/buffer/BufferInterpolation.java | ||
---|---|---|
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.buffer; |
|
20 |
|
|
21 |
import org.gvsig.raster.dataset.IBuffer; |
|
22 |
|
|
23 |
/** |
|
24 |
* Clase que contiene la funcionalidad para poder interpolar un buffer de datos |
|
25 |
* por distintos m?todos. |
|
26 |
* |
|
27 |
* @version 07/05/2007 |
|
28 |
* @author Nacho Brodin (nachobrodin@gmail.com) |
|
29 |
* |
|
30 |
*/ |
|
31 |
public class BufferInterpolation { |
|
32 |
public final static int INTERPOLATION_Undefined = 0; |
|
33 |
public final static int INTERPOLATION_NearestNeighbour = 1; |
|
34 |
public final static int INTERPOLATION_Bilinear = 2; |
|
35 |
public final static int INTERPOLATION_InverseDistance = 3; |
|
36 |
public final static int INTERPOLATION_BicubicSpline = 4; |
|
37 |
public final static int INTERPOLATION_BSpline = 5; |
|
38 |
|
|
39 |
private RasterBuffer buffer = null; |
|
40 |
|
|
41 |
/** |
|
42 |
* Constructor. Asigna un RasterBuffer. |
|
43 |
* @param buf |
|
44 |
*/ |
|
45 |
public BufferInterpolation(RasterBuffer buf) { |
|
46 |
this.buffer = buf; |
|
47 |
} |
|
48 |
|
|
49 |
/** |
|
50 |
* Ajusta el raster al ancho y alto solicitado por el vecino m?s cercano. Promedia el valor de dos |
|
51 |
* pixeles contiguos. |
|
52 |
* @param w Nuevo ancho |
|
53 |
* @param h Nuevo alto |
|
54 |
*/ |
|
55 |
public RasterBuffer adjustRasterNearestNeighbourInterpolation(int w, int h) { |
|
56 |
double stepX = (double)w / (double)buffer.width; |
|
57 |
double stepY = (double)h / (double)buffer.height; |
|
58 |
RasterBuffer rasterBuf = new RasterMemoryBuffer(buffer.getDataType(), w, h, buffer.getBandCount(), true); |
|
59 |
|
|
60 |
int[] bands = new int[rasterBuf.getBandCount()]; |
|
61 |
for(int iBand = 0; iBand < rasterBuf.getBandCount(); iBand ++) |
|
62 |
bands[iBand] = iBand; |
|
63 |
|
|
64 |
|
|
65 |
switch (buffer.dataType) { |
|
66 |
case RasterBuffer.TYPE_BYTE: |
|
67 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
68 |
if(w <= buffer.width) { //submuestreo |
|
69 |
for(int iRow = 0; iRow < buffer.height; iRow ++) |
|
70 |
for(int iCol = 0; iCol < buffer.width; iCol ++) |
|
71 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], buffer.getElemByte(iRow, iCol, iBand)); |
|
72 |
}else{ //supermuestreo |
|
73 |
for(int iRow = 0; iRow < h; iRow ++) |
|
74 |
for(int iCol = 0; iCol < w; iCol ++) |
|
75 |
rasterBuf.setElem(iRow, iCol, bands[iBand], buffer.getElemByte((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
76 |
} |
|
77 |
} |
|
78 |
break; |
|
79 |
case RasterBuffer.TYPE_DOUBLE: |
|
80 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
81 |
if(w <= buffer.width) { //submuestreo |
|
82 |
for(int iRow = 0; iRow < buffer.height; iRow ++) |
|
83 |
for(int iCol = 0; iCol < buffer.width; iCol ++) |
|
84 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], buffer.getElemDouble(iRow, iCol, iBand)); |
|
85 |
}else{ //supermuestreo |
|
86 |
for(int iRow = 0; iRow < h; iRow ++) |
|
87 |
for(int iCol = 0; iCol < w; iCol ++) |
|
88 |
rasterBuf.setElem(iRow, iCol, bands[iBand], buffer.getElemDouble((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
89 |
} |
|
90 |
} |
|
91 |
break; |
|
92 |
case RasterBuffer.TYPE_FLOAT: |
|
93 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
94 |
if(w <= buffer.width) { //submuestreo |
|
95 |
for(int iRow = 0; iRow < buffer.height; iRow ++) |
|
96 |
for(int iCol = 0; iCol < buffer.width; iCol ++) |
|
97 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], buffer.getElemFloat(iRow, iCol, iBand)); |
|
98 |
}else{ //supermuestreo |
|
99 |
for(int iRow = 0; iRow < h; iRow ++) |
|
100 |
for(int iCol = 0; iCol < w; iCol ++) |
|
101 |
rasterBuf.setElem(iRow, iCol, bands[iBand], buffer.getElemFloat((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
102 |
} |
|
103 |
} |
|
104 |
break; |
|
105 |
case RasterBuffer.TYPE_INT: |
|
106 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
107 |
if(w <= buffer.width) { //submuestreo |
|
108 |
for(int iRow = 0; iRow < buffer.height; iRow ++) |
|
109 |
for(int iCol = 0; iCol < buffer.width; iCol ++) |
|
110 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], buffer.getElemInt(iRow, iCol, iBand)); |
|
111 |
}else{ //supermuestreo |
|
112 |
for(int iRow = 0; iRow < h; iRow ++) |
|
113 |
for(int iCol = 0; iCol < w; iCol ++) |
|
114 |
rasterBuf.setElem(iRow, iCol, bands[iBand], buffer.getElemInt((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
115 |
} |
|
116 |
} |
|
117 |
break; |
|
118 |
case RasterBuffer.TYPE_USHORT: |
|
119 |
case RasterBuffer.TYPE_SHORT: |
|
120 |
for(int iBand = 0; iBand < bands.length; iBand ++) { |
|
121 |
if(w <= buffer.width) { //submuestreo |
|
122 |
for(int iRow = 0; iRow < buffer.height; iRow ++) |
|
123 |
for(int iCol = 0; iCol < buffer.width; iCol ++) |
|
124 |
rasterBuf.setElem((int)(iRow * stepY), (int)(iCol * stepX), bands[iBand], buffer.getElemShort(iRow, iCol, iBand)); |
|
125 |
}else{ //supermuestreo |
|
126 |
for(int iRow = 0; iRow < h; iRow ++) |
|
127 |
for(int iCol = 0; iCol < w; iCol ++) |
|
128 |
rasterBuf.setElem(iRow, iCol, bands[iBand], buffer.getElemShort((int)(iRow / stepY), (int)(iCol / stepX), iBand)); |
|
129 |
} |
|
130 |
} |
|
131 |
break; |
|
132 |
} |
|
133 |
return rasterBuf; |
|
134 |
} |
|
135 |
|
|
136 |
/** |
|
137 |
* Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n bilineal. Promedia |
|
138 |
* el valor de cuatro pixeles adyacentes. |
|
139 |
* <P> |
|
140 |
* Para cada pixel del raster A:(x, y) obtiene el B:(x + 1, y), C:(x, y + 1), D:(x + 1, y + 1) |
|
141 |
* Para cada valor del kernel se calcula un valor 'd' que es un peso dependiendo de su posici?n. |
|
142 |
* Este peso depende de la posici?n del pixel destino dentro del origen. La posici?n del pixel destino |
|
143 |
* en el origen es un valor decimal que puede ir de 0 a 1. Si est? muy pegado a la esquina superior |
|
144 |
* izquierda estar? cercano a 0 y si est? muy pegado a la esquina inferior derecha estar? cercano a 1. |
|
145 |
* Este valor est? representado por 'dx' y 'dy'. |
|
146 |
* </P> |
|
147 |
* <P> |
|
148 |
* Los pesos aplicados son a |
|
149 |
* <UL> |
|
150 |
* <LI>A (1-dx) * (1-dy)</LI> |
|
151 |
* <LI>B dx * (1-dy)</LI> |
|
152 |
* <LI>C (1-dx) * dy</LI> |
|
153 |
* <LI>D dx * dy</LI> |
|
154 |
* </UL> |
|
155 |
* La variable 'z' contiene el valor acumulado de cada peso por el valor del pixel. |
|
156 |
* La variable 'n' contiene el valor acumulado de los pesos de los cuatro pixeles. |
|
157 |
* El valor final del pixel ser? 'z/n', es decir un promedio del valor de los cuatro teniendo |
|
158 |
* en cuenta el peso de cada uno. |
|
159 |
* </P> |
|
160 |
* @param w Nuevo ancho del buffer de salida |
|
161 |
* @param h Nuevo alto del buffer de salida |
|
162 |
*/ |
|
163 |
public RasterBuffer adjustRasterBilinearInterpolation(int w, int h) { |
|
164 |
double pxSize = (double)buffer.width / (double)w; |
|
165 |
RasterBuffer rasterBuf = new RasterMemoryBuffer(buffer.getDataType(), w, h, buffer.getBandCount(), true); |
|
166 |
|
|
167 |
double posX = pxSize / 2D; |
|
168 |
double posY = posX; |
|
169 |
double dx = 0D, dy = 0D; |
|
170 |
|
|
171 |
for(int iBand = 0; iBand < buffer.getBandCount(); iBand ++) { |
|
172 |
posY = pxSize / 2D; |
|
173 |
switch (buffer.dataType) { |
|
174 |
case RasterBuffer.TYPE_BYTE: |
|
175 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
176 |
dy = posY - ((int)posY); |
|
177 |
posX = pxSize / 2D; |
|
178 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
179 |
dx = posX - ((int)posX); |
|
180 |
double[] kernel = getKernelByte(((int)posX), ((int)posY), iBand); |
|
181 |
rasterBuf.setElem(iRow, iCol, iBand, (byte)((byte)getBilinearValue(dx, dy, kernel) & 0xff)); |
|
182 |
posX += pxSize; |
|
183 |
} |
|
184 |
posY += pxSize; |
|
185 |
} |
|
186 |
break; |
|
187 |
case RasterBuffer.TYPE_SHORT: |
|
188 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
189 |
dy = posY - ((int)posY); |
|
190 |
posX = pxSize / 2D; |
|
191 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
192 |
dx = posX - ((int)posX); |
|
193 |
double[] kernel = getKernelShort(((int)posX), ((int)posY), iBand); |
|
194 |
rasterBuf.setElem(iRow, iCol, iBand, (short)((short)getBilinearValue(dx, dy, kernel) & 0xffff)); |
|
195 |
posX += pxSize; |
|
196 |
} |
|
197 |
posY += pxSize; |
|
198 |
} |
|
199 |
break; |
|
200 |
case RasterBuffer.TYPE_INT: |
|
201 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
202 |
dy = posY - ((int)posY); |
|
203 |
posX = pxSize / 2D; |
|
204 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
205 |
dx = posX - ((int)posX); |
|
206 |
double[] kernel = getKernelInt(((int)posX), ((int)posY), iBand); |
|
207 |
rasterBuf.setElem(iRow, iCol, iBand, (int)((int)getBilinearValue(dx, dy, kernel) & 0xff)); |
|
208 |
posX += pxSize; |
|
209 |
} |
|
210 |
posY += pxSize; |
|
211 |
} |
|
212 |
break; |
|
213 |
case RasterBuffer.TYPE_FLOAT: |
|
214 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
215 |
dy = posY - ((int)posY); |
|
216 |
posX = pxSize / 2D; |
|
217 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
218 |
dx = posX - ((int)posX); |
|
219 |
double[] kernel = getKernelInt(((int)posX), ((int)posY), iBand); |
|
220 |
rasterBuf.setElem(iRow, iCol, iBand, (float)getBilinearValue(dx, dy, kernel)); |
|
221 |
posX += pxSize; |
|
222 |
} |
|
223 |
posY += pxSize; |
|
224 |
} |
|
225 |
break; |
|
226 |
case RasterBuffer.TYPE_DOUBLE: |
|
227 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
228 |
dy = posY - ((int)posY); |
|
229 |
posX = pxSize / 2D; |
|
230 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
231 |
dx = posX - ((int)posX); |
|
232 |
double[] kernel = getKernelInt(((int)posX), ((int)posY), iBand); |
|
233 |
rasterBuf.setElem(iRow, iCol, iBand, (double)getBilinearValue(dx, dy, kernel)); |
|
234 |
posX += pxSize; |
|
235 |
} |
|
236 |
posY += pxSize; |
|
237 |
} |
|
238 |
break; |
|
239 |
} |
|
240 |
|
|
241 |
} |
|
242 |
|
|
243 |
return rasterBuf; |
|
244 |
} |
|
245 |
|
|
246 |
/** |
|
247 |
* Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n de distancia inversa. |
|
248 |
* Asigna el valor de un pixel en funci?n inversa de la distancia. |
|
249 |
* <P> |
|
250 |
* Para cada pixel del raster A:(x, y) obtiene el B:(x + 1, y), C:(x, y + 1), D:(x + 1, y + 1) |
|
251 |
* Para cada valor del kernel se calcula un valor 'd' que es un peso dependiendo de su posici?n. |
|
252 |
* Este peso ser? dependiente de la posici?n del pixel destino dentro del origen. La posici?n del pixel destino |
|
253 |
* en el origen es un valor decimal que puede ir de 0 a 1. Si est? muy pegado a la esquina superior |
|
254 |
* izquierda estar? cercano a 0 y si est? muy pegado a la esquina inferior derecha estar? cercano a 1. |
|
255 |
* Este valor est? representado por 'dx' y 'dy'. En este caso, y a diferencia del m?todo |
|
256 |
* bilinear el peso vendr? representado por la inversa de la distancia entre la posici?n |
|
257 |
* dentro del pixel y el origen del mismo. |
|
258 |
* </P> |
|
259 |
* <P> |
|
260 |
* Los pesos aplicados son a |
|
261 |
* <UL> |
|
262 |
* <LI>A 1 / sqrt((1-dx) * (1-dy))</LI> |
|
263 |
* <LI>B 1 / sqrt(dx * (1-dy))</LI> |
|
264 |
* <LI>C 1 / sqrt((1-dx) * dy)</LI> |
|
265 |
* <LI>D 1 / sqrt(dx * dy)</LI> |
|
266 |
* </UL> |
|
267 |
* La variable 'z' contiene el valor acumulado de cada peso por el valor del pixel. |
|
268 |
* La variable 'n' contiene el valor acumulado de los pesos de los cuatro pixeles. |
|
269 |
* El valor final del pixel ser? 'z/n', es decir un promedio del valor de los cuatro teniendo |
|
270 |
* en cuenta el peso de cada uno. |
|
271 |
* </P> |
|
272 |
* @param w Nuevo ancho del buffer de salida |
|
273 |
* @param h Nuevo alto del buffer de salida |
|
274 |
*/ |
|
275 |
public RasterBuffer adjustRasterInverseDistanceInterpolation(int w, int h) { |
|
276 |
double pxSize = (double)buffer.width / (double)w; |
|
277 |
RasterBuffer rasterBuf = new RasterMemoryBuffer(buffer.getDataType(), w, h, buffer.getBandCount(), true); |
|
278 |
|
|
279 |
double posX = pxSize / 2D; |
|
280 |
double posY = posX; |
|
281 |
double dx = 0D, dy = 0D; |
|
282 |
|
|
283 |
for(int iBand = 0; iBand < buffer.getBandCount(); iBand ++) { |
|
284 |
posY = pxSize / 2D; |
|
285 |
switch (buffer.dataType) { |
|
286 |
case RasterBuffer.TYPE_BYTE: |
|
287 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
288 |
dy = posY - ((int)posY); |
|
289 |
posX = pxSize / 2D; |
|
290 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
291 |
dx = posX - ((int)posX); |
|
292 |
double[] kernel = getKernelByte(((int)posX), ((int)posY), iBand); |
|
293 |
rasterBuf.setElem(iRow, iCol, iBand, (byte)((byte)getInverseDistanceValue(dx, dy, kernel) & 0xff)); |
|
294 |
posX += pxSize; |
|
295 |
} |
|
296 |
posY += pxSize; |
|
297 |
} |
|
298 |
break; |
|
299 |
case RasterBuffer.TYPE_SHORT: |
|
300 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
301 |
dy = posY - ((int)posY); |
|
302 |
posX = pxSize / 2D; |
|
303 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
304 |
dx = posX - ((int)posX); |
|
305 |
double[] kernel = getKernelShort(((int)posX), ((int)posY), iBand); |
|
306 |
rasterBuf.setElem(iRow, iCol, iBand, (short)((short)getInverseDistanceValue(dx, dy, kernel) & 0xffff)); |
|
307 |
posX += pxSize; |
|
308 |
} |
|
309 |
posY += pxSize; |
|
310 |
} |
|
311 |
break; |
|
312 |
case RasterBuffer.TYPE_INT: |
|
313 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
314 |
dy = posY - ((int)posY); |
|
315 |
posX = pxSize / 2D; |
|
316 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
317 |
dx = posX - ((int)posX); |
|
318 |
double[] kernel = getKernelInt(((int)posX), ((int)posY), iBand); |
|
319 |
rasterBuf.setElem(iRow, iCol, iBand, (int)((int)getInverseDistanceValue(dx, dy, kernel) & 0xff)); |
|
320 |
posX += pxSize; |
|
321 |
} |
|
322 |
posY += pxSize; |
|
323 |
} |
|
324 |
break; |
|
325 |
case RasterBuffer.TYPE_FLOAT: |
|
326 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
327 |
dy = posY - ((int)posY); |
|
328 |
posX = pxSize / 2D; |
|
329 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
330 |
dx = posX - ((int)posX); |
|
331 |
double[] kernel = getKernelFloat(((int)posX), ((int)posY), iBand); |
|
332 |
rasterBuf.setElem(iRow, iCol, iBand, (float)getInverseDistanceValue(dx, dy, kernel)); |
|
333 |
posX += pxSize; |
|
334 |
} |
|
335 |
posY += pxSize; |
|
336 |
} |
|
337 |
break; |
|
338 |
case RasterBuffer.TYPE_DOUBLE: |
|
339 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
340 |
dy = posY - ((int)posY); |
|
341 |
posX = pxSize / 2D; |
|
342 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
343 |
dx = posX - ((int)posX); |
|
344 |
double[] kernel = getKernelDouble(((int)posX), ((int)posY), iBand); |
|
345 |
rasterBuf.setElem(iRow, iCol, iBand, (double)getInverseDistanceValue(dx, dy, kernel)); |
|
346 |
posX += pxSize; |
|
347 |
} |
|
348 |
posY += pxSize; |
|
349 |
} |
|
350 |
break; |
|
351 |
} |
|
352 |
|
|
353 |
} |
|
354 |
|
|
355 |
return rasterBuf; |
|
356 |
} |
|
357 |
|
|
358 |
/** |
|
359 |
* Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n BSpline. Promedia |
|
360 |
* el valor de cuatro pixeles adyacentes. |
|
361 |
* @param w Nuevo ancho |
|
362 |
* @param h Nuevo alto |
|
363 |
*/ |
|
364 |
public RasterBuffer adjustRasterBSplineInterpolation(int w, int h) { |
|
365 |
double pxSize = (double)buffer.width / (double)w; |
|
366 |
RasterBuffer rasterBuf = new RasterMemoryBuffer(buffer.getDataType(), w, h, buffer.getBandCount(), true); |
|
367 |
|
|
368 |
double posX = pxSize / 2D; |
|
369 |
double posY = posX; |
|
370 |
double dx = 0D, dy = 0D; |
|
371 |
|
|
372 |
for(int iBand = 0; iBand < buffer.getBandCount(); iBand ++) { |
|
373 |
posY = pxSize / 2D; |
|
374 |
switch (buffer.dataType) { |
|
375 |
case RasterBuffer.TYPE_BYTE: |
|
376 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
377 |
dy = posY - ((int)posY); |
|
378 |
posX = pxSize / 2D; |
|
379 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
380 |
dx = posX - ((int)posX); |
|
381 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
382 |
if(kernel == null) { |
|
383 |
double[] k = getKernelByte(((int)posX), ((int)posY), iBand); |
|
384 |
rasterBuf.setElem(iRow, iCol, iBand, (byte)((byte)getBilinearValue(dx, dy, k) & 0xff)); |
|
385 |
} else |
|
386 |
rasterBuf.setElem(iRow, iCol, iBand, (byte)((byte)getBSplineValue(dx, dy, kernel) & 0xff)); |
|
387 |
posX += pxSize; |
|
388 |
} |
|
389 |
posY += pxSize; |
|
390 |
} |
|
391 |
break; |
|
392 |
case RasterBuffer.TYPE_SHORT: |
|
393 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
394 |
dy = posY - ((int)posY); |
|
395 |
posX = pxSize / 2D; |
|
396 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
397 |
dx = posX - ((int)posX); |
|
398 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
399 |
if(kernel == null) { |
|
400 |
double[] k = getKernelShort(((int)posX), ((int)posY), iBand); |
|
401 |
rasterBuf.setElem(iRow, iCol, iBand, (short)((short)getBilinearValue(dx, dy, k) & 0xffff)); |
|
402 |
} else |
|
403 |
rasterBuf.setElem(iRow, iCol, iBand, (short)((short)getBSplineValue(dx, dy, kernel) & 0xffff)); |
|
404 |
posX += pxSize; |
|
405 |
} |
|
406 |
posY += pxSize; |
|
407 |
} |
|
408 |
break; |
|
409 |
case RasterBuffer.TYPE_INT: |
|
410 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
411 |
dy = posY - ((int)posY); |
|
412 |
posX = pxSize / 2D; |
|
413 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
414 |
dx = posX - ((int)posX); |
|
415 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
416 |
if(kernel == null) { |
|
417 |
double[] k = getKernelInt(((int)posX), ((int)posY), iBand); |
|
418 |
rasterBuf.setElem(iRow, iCol, iBand, (int)((int)getBilinearValue(dx, dy, k) & 0xffffffff)); |
|
419 |
} else |
|
420 |
rasterBuf.setElem(iRow, iCol, iBand, (int)((int)getBSplineValue(dx, dy, kernel) & 0xffffffff)); |
|
421 |
posX += pxSize; |
|
422 |
} |
|
423 |
posY += pxSize; |
|
424 |
} |
|
425 |
break; |
|
426 |
case RasterBuffer.TYPE_FLOAT: |
|
427 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
428 |
dy = posY - ((int)posY); |
|
429 |
posX = pxSize / 2D; |
|
430 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
431 |
dx = posX - ((int)posX); |
|
432 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
433 |
if(kernel == null) { |
|
434 |
double[] k = getKernelFloat(((int)posX), ((int)posY), iBand); |
|
435 |
rasterBuf.setElem(iRow, iCol, iBand, (float)getBilinearValue(dx, dy, k)); |
|
436 |
} else |
|
437 |
rasterBuf.setElem(iRow, iCol, iBand, (float)getBSplineValue(dx, dy, kernel)); |
|
438 |
posX += pxSize; |
|
439 |
} |
|
440 |
posY += pxSize; |
|
441 |
} |
|
442 |
break; |
|
443 |
case RasterBuffer.TYPE_DOUBLE: |
|
444 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
445 |
dy = posY - ((int)posY); |
|
446 |
posX = pxSize / 2D; |
|
447 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
448 |
dx = posX - ((int)posX); |
|
449 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
450 |
if(kernel == null) { |
|
451 |
double[] k = getKernelDouble(((int)posX), ((int)posY), iBand); |
|
452 |
rasterBuf.setElem(iRow, iCol, iBand, (double)getBilinearValue(dx, dy, k)); |
|
453 |
} else |
|
454 |
rasterBuf.setElem(iRow, iCol, iBand, (double)getBSplineValue(dx, dy, kernel)); |
|
455 |
posX += pxSize; |
|
456 |
} |
|
457 |
posY += pxSize; |
|
458 |
} |
|
459 |
break; |
|
460 |
} |
|
461 |
|
|
462 |
} |
|
463 |
|
|
464 |
return rasterBuf; |
|
465 |
} |
|
466 |
|
|
467 |
/** |
|
468 |
* Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n de spline bicubica. |
|
469 |
* @param w Nuevo ancho |
|
470 |
* @param h Nuevo alto |
|
471 |
*/ |
|
472 |
public RasterBuffer adjustRasterBicubicSplineInterpolation(int w, int h) { |
|
473 |
double pxSize = (double)buffer.width / (double)w; |
|
474 |
RasterBuffer rasterBuf = new RasterMemoryBuffer(buffer.getDataType(), w, h, buffer.getBandCount(), true); |
|
475 |
|
|
476 |
double posX = pxSize / 2D; |
|
477 |
double posY = posX; |
|
478 |
double dx = 0D, dy = 0D; |
|
479 |
|
|
480 |
for(int iBand = 0; iBand < buffer.getBandCount(); iBand ++) { |
|
481 |
posY = pxSize / 2D; |
|
482 |
switch (buffer.dataType) { |
|
483 |
case RasterBuffer.TYPE_BYTE: |
|
484 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
485 |
dy = posY - ((int)posY); |
|
486 |
posX = pxSize / 2D; |
|
487 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
488 |
dx = posX - ((int)posX); |
|
489 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
490 |
if(kernel == null) { |
|
491 |
double[] k = getKernelByte(((int)posX), ((int)posY), iBand); |
|
492 |
rasterBuf.setElem(iRow, iCol, iBand, (byte)((byte)getBilinearValue(dx, dy, k) & 0xff)); |
|
493 |
} else |
|
494 |
rasterBuf.setElem(iRow, iCol, iBand, (byte)((byte)getBicubicSplineValue(dx, dy, kernel) & 0xff)); |
|
495 |
posX += pxSize; |
|
496 |
} |
|
497 |
posY += pxSize; |
|
498 |
} |
|
499 |
break; |
|
500 |
case RasterBuffer.TYPE_SHORT: |
|
501 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
502 |
dy = posY - ((int)posY); |
|
503 |
posX = pxSize / 2D; |
|
504 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
505 |
dx = posX - ((int)posX); |
|
506 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
507 |
if(kernel == null) { |
|
508 |
double[] k = getKernelShort(((int)posX), ((int)posY), iBand); |
|
509 |
rasterBuf.setElem(iRow, iCol, iBand, (short)((short)getBilinearValue(dx, dy, k) & 0xffff)); |
|
510 |
} else |
|
511 |
rasterBuf.setElem(iRow, iCol, iBand, (short)((short)getBicubicSplineValue(dx, dy, kernel) & 0xffff)); |
|
512 |
posX += pxSize; |
|
513 |
} |
|
514 |
posY += pxSize; |
|
515 |
} |
|
516 |
break; |
|
517 |
case RasterBuffer.TYPE_INT: |
|
518 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
519 |
dy = posY - ((int)posY); |
|
520 |
posX = pxSize / 2D; |
|
521 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
522 |
dx = posX - ((int)posX); |
|
523 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
524 |
if(kernel == null) { |
|
525 |
double[] k = getKernelInt(((int)posX), ((int)posY), iBand); |
|
526 |
rasterBuf.setElem(iRow, iCol, iBand, (int)((int)getBilinearValue(dx, dy, k) & 0xffffffff)); |
|
527 |
} else |
|
528 |
rasterBuf.setElem(iRow, iCol, iBand, (int)((int)getBicubicSplineValue(dx, dy, kernel) & 0xffffffff)); |
|
529 |
posX += pxSize; |
|
530 |
} |
|
531 |
posY += pxSize; |
|
532 |
} |
|
533 |
break; |
|
534 |
case RasterBuffer.TYPE_FLOAT: |
|
535 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
536 |
dy = posY - ((int)posY); |
|
537 |
posX = pxSize / 2D; |
|
538 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
539 |
dx = posX - ((int)posX); |
|
540 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
541 |
if(kernel == null) { |
|
542 |
double[] k = getKernelFloat(((int)posX), ((int)posY), iBand); |
|
543 |
rasterBuf.setElem(iRow, iCol, iBand, (float)getBilinearValue(dx, dy, k)); |
|
544 |
} else |
|
545 |
rasterBuf.setElem(iRow, iCol, iBand, (float)getBicubicSplineValue(dx, dy, kernel)); |
|
546 |
posX += pxSize; |
|
547 |
} |
|
548 |
posY += pxSize; |
|
549 |
} |
|
550 |
break; |
|
551 |
case RasterBuffer.TYPE_DOUBLE: |
|
552 |
for(int iRow = 0; iRow < h; iRow ++) { |
|
553 |
dy = posY - ((int)posY); |
|
554 |
posX = pxSize / 2D; |
|
555 |
for(int iCol = 0; iCol < w; iCol ++) { |
|
556 |
dx = posX - ((int)posX); |
|
557 |
double[][] kernel = get4x4Submatrix(((int)posX), ((int)posY), iBand); |
|
558 |
if(kernel == null) { |
|
559 |
double[] k = getKernelDouble(((int)posX), ((int)posY), iBand); |
|
560 |
rasterBuf.setElem(iRow, iCol, iBand, (double)getBilinearValue(dx, dy, k)); |
|
561 |
} else |
|
562 |
rasterBuf.setElem(iRow, iCol, iBand, (double)getBicubicSplineValue(dx, dy, kernel)); |
|
563 |
posX += pxSize; |
|
564 |
} |
|
565 |
posY += pxSize; |
|
566 |
} |
|
567 |
break; |
|
568 |
} |
|
569 |
|
|
570 |
} |
|
571 |
|
|
572 |
return rasterBuf; |
|
573 |
} |
|
574 |
|
|
575 |
/** |
|
576 |
* |
|
577 |
* @param dx |
|
578 |
* @param dy |
|
579 |
* @param kernel |
|
580 |
* @return |
|
581 |
*/ |
|
582 |
private double getBicubicSplineValue(double dx, double dy, double[][] kernel) { |
|
583 |
int i; |
|
584 |
double a0, a2, a3, b1, b2, b3; |
|
585 |
double[] c = new double[4]; |
|
586 |
|
|
587 |
for(i = 0; i < 4; i++) { |
|
588 |
a0 = kernel[0][i] - kernel[1][i]; |
|
589 |
a2 = kernel[2][i] - kernel[1][i]; |
|
590 |
a3 = kernel[3][i] - kernel[1][i]; |
|
591 |
|
|
592 |
b1 = -a0 / 3.0 + a2 - a3 / 6.0; |
|
593 |
b2 = a0 / 2.0 + a2 / 2.0; |
|
594 |
b3 = -a0 / 6.0 - a2 / 2.0 + a3 / 6.0; |
|
595 |
|
|
596 |
c[i] = kernel[1][i] + b1 * dx + b2 * (dx * dx) + b3 * (dx * dx * dx); |
|
597 |
} |
|
598 |
|
|
599 |
a0 = c[0] - c[1]; |
|
600 |
a2 = c[2] - c[1]; |
|
601 |
a3 = c[3] - c[1]; |
|
602 |
|
|
603 |
b1 = -a0 / 3.0 + a2 - a3 / 6.0; |
|
604 |
b2 = a0 / 2.0 + a2 / 2.0; |
|
605 |
b3 = -a0 / 6.0 - a2 / 2.0 + a3 / 6.0; |
|
606 |
|
|
607 |
return( c[1] + b1 * dy + b2 * (dy * dy) + b3 * (dy * dy * dy) ); |
|
608 |
} |
|
609 |
|
|
610 |
/** |
|
611 |
* |
|
612 |
* @param dx |
|
613 |
* @param dy |
|
614 |
* @param kernel |
|
615 |
* @return |
|
616 |
*/ |
|
617 |
private double getBSplineValue(double dx, double dy, double[][] kernel) { |
|
618 |
int i = 0, ix = 0, iy = 0; |
|
619 |
double px = 0, py = 0, z = 0; |
|
620 |
double[] Rx = new double[4]; |
|
621 |
double[] Ry = new double[4]; |
|
622 |
|
|
623 |
for(i = 0, px = -1.0 - dx, py = -1.0 - dy; i < 4; i++, px++, py++){ |
|
624 |
Rx[i] = 0.0; |
|
625 |
Ry[i] = 0.0; |
|
626 |
|
|
627 |
if( (z = px + 2.0) > 0.0 ) |
|
628 |
Rx[i] += z * z * z; |
|
629 |
if( (z = px + 1.0) > 0.0 ) |
|
630 |
Rx[i] += -4.0 * z * z * z; |
|
631 |
if( (z = px + 0.0) > 0.0 ) |
|
632 |
Rx[i] += 6.0 * z * z * z; |
|
633 |
if( (z = px - 1.0) > 0.0 ) |
|
634 |
Rx[i] += -4.0 * z * z * z; |
|
635 |
if( (z = py + 2.0) > 0.0 ) |
|
636 |
Ry[i] += z * z * z; |
|
637 |
if( (z = py + 1.0) > 0.0 ) |
|
638 |
Ry[i] += -4.0 * z * z * z; |
|
639 |
if( (z = py + 0.0) > 0.0 ) |
|
640 |
Ry[i] += 6.0 * z * z * z; |
|
641 |
if( (z = py - 1.0) > 0.0 ) |
|
642 |
Ry[i] += -4.0 * z * z * z; |
|
643 |
|
|
644 |
Rx[i] /= 6.0; |
|
645 |
Ry[i] /= 6.0; |
|
646 |
} |
|
647 |
|
|
648 |
for(iy = 0, z = 0.0; iy < 4; iy++) { |
|
649 |
for(ix = 0; ix < 4; ix++) { |
|
650 |
z += kernel[ix][iy] * Rx[ix] * Ry[iy]; |
|
651 |
} |
|
652 |
} |
|
653 |
return z; |
|
654 |
} |
|
655 |
|
|
656 |
/** |
|
657 |
* Calcula los valores N y Z para el m?todo bilinear y obtiene el valor del pixel como |
|
658 |
* Z / N |
|
659 |
* @param dx distancia en X desde el centro del pixel hasta el punto. Es un valor entre 0 y 1 |
|
660 |
* @param dy distancia en Y desde el centro del pixel hasta el punto. Es un valor entre 0 y 1 |
|
661 |
* @param kernel valor del pixel y alrededor |
|
662 |
* @return valor del pixel |
|
663 |
*/ |
|
664 |
private double getBilinearValue(double dx, double dy, double[] kernel) { |
|
665 |
double z = 0.0, n = 0.0, d; |
|
666 |
d = (1.0 - dx) * (1.0 - dy); |
|
667 |
z += d * kernel[0]; |
|
668 |
n += d; |
|
669 |
|
|
670 |
d = dx * (1.0 - dy); |
|
671 |
z += d * kernel[1]; |
|
672 |
n += d; |
|
673 |
|
|
674 |
d = (1.0 - dx) * dy; |
|
675 |
z += d * kernel[2]; |
|
676 |
n += d; |
|
677 |
|
|
678 |
d = dx * dy; |
|
679 |
z += d * kernel[3]; |
|
680 |
n += d; |
|
681 |
|
|
682 |
double b = 0; |
|
683 |
if(n > 0.0) |
|
684 |
b = (z / n); |
|
685 |
return b; |
|
686 |
} |
|
687 |
|
|
688 |
/** |
|
689 |
* Calcula los valores N y Z para el m?todo de distancia inversa y calcula el valor del |
|
690 |
* pixel como Z / N. |
|
691 |
* @param dx distancia en X desde el centro del pixel hasta el punto. Es un valor entre 0 y 1 |
|
692 |
* @param dy distancia en Y desde el centro del pixel hasta el punto. Es un valor entre 0 y 1 |
|
693 |
* @param kernel valor del pixel y alrededor |
|
694 |
* @return valor del pixel |
|
695 |
*/ |
|
696 |
private double getInverseDistanceValue(double dx, double dy, double[] kernel) { |
|
697 |
double z = 0.0, n = 0.0, d; |
|
698 |
d = 1.0 / Math.sqrt(dx * dx + dy * dy); |
|
699 |
z += d * kernel[0]; |
|
700 |
n += d; |
|
701 |
|
|
702 |
d = 1.0 / Math.sqrt((1.0 - dx) * ( 1.0 - dx) + dy * dy); |
|
703 |
z += d * kernel[1]; |
|
704 |
n += d; |
|
705 |
|
|
706 |
d = 1.0 / Math.sqrt(dx*dx + (1.0-dy)*(1.0-dy)); |
|
707 |
z += d * kernel[2]; |
|
708 |
n += d; |
|
709 |
|
|
710 |
d = 1.0 / Math.sqrt((1.0 - dx) *( 1.0 - dx) + (1.0 - dy) * (1.0 - dy)); |
|
711 |
z += d * kernel[3]; |
|
712 |
n += d; |
|
713 |
|
|
714 |
double b = 0; |
|
715 |
if(n > 0.0) |
|
716 |
b = (z / n); |
|
717 |
return b; |
|
718 |
} |
|
719 |
|
|
720 |
/** |
|
721 |
* Obtiene un kernel de 4x4 elementos. Si alguno de los elementos se sale de la imagen |
|
722 |
* , por ejemplo en los bordes devuelve null. |
|
723 |
* @param x |
|
724 |
* @param y |
|
725 |
* @param band |
|
726 |
* @return |
|
727 |
*/ |
|
728 |
private double[][] get4x4Submatrix(int x, int y, int band) { |
|
729 |
int ix, iy, px, py; |
|
730 |
double[][] z_xy = new double[4][4]; |
|
731 |
|
|
732 |
for(iy = 0, py = y - 1; iy < 4; iy++, py++) { |
|
733 |
for(ix = 0, px = x - 1; ix < 4; ix++, px++) { |
|
734 |
if (!buffer.isInside(px, py)) |
|
735 |
return null; |
|
736 |
else { |
|
737 |
switch(buffer.getDataType()) { |
|
738 |
case IBuffer.TYPE_BYTE: z_xy[ix][iy] = (buffer.getElemByte(py, px, band) & 0xff); break; |
|
739 |
case IBuffer.TYPE_SHORT: z_xy[ix][iy] = (buffer.getElemShort(py, px, band) & 0xffff); break; |
|
740 |
case IBuffer.TYPE_INT: z_xy[ix][iy] = (buffer.getElemInt(py, px, band) & 0xffffffff); break; |
|
741 |
case IBuffer.TYPE_FLOAT: z_xy[ix][iy] = buffer.getElemFloat(py, px, band); break; |
|
742 |
case IBuffer.TYPE_DOUBLE: z_xy[ix][iy] = buffer.getElemDouble(py, px, band); break; |
|
743 |
} |
|
744 |
} |
|
745 |
} |
|
746 |
} |
|
747 |
return z_xy; |
|
748 |
} |
|
749 |
|
|
750 |
/** |
|
751 |
* Obtiene un kernel de cuatro elemento que corresponden a los pixeles (x, y), (x + 1, y), |
|
752 |
* (x, y + 1), (x + 1, y + 1). Si los pixeles x + 1 o y + 1 se salen del raster de origen |
|
753 |
* se tomar? x e y. |
|
754 |
* @param x Coordenada X del pixel inicial |
|
755 |
* @param y Coordenada Y del pixel inicial |
|
756 |
* @param band N?mero de banda. |
|
757 |
* @return Kernel solicitado en forma de array. |
|
758 |
*/ |
|
759 |
private double[] getKernelByte(int x, int y, int band) { |
|
760 |
double[] d = new double[4]; |
|
761 |
d[0] = (buffer.getElemByte(y, x, band) & 0xff); |
|
762 |
int nextX = ((x + 1) >= buffer.getWidth()) ? x : (x + 1); |
|
763 |
int nextY = ((y + 1) >= buffer.getHeight()) ? y : (y + 1); |
|
764 |
d[1] = (buffer.getElemByte(y, nextX, band) & 0xff); |
|
765 |
d[2] = (buffer.getElemByte(nextY, x, band) & 0xff); |
|
766 |
d[3] = (buffer.getElemByte(nextY, nextX, band) & 0xff); |
|
767 |
return d; |
|
768 |
} |
|
769 |
|
Also available in: Unified diff