Commit 61e720a6 authored by Andrey Filippov's avatar Andrey Filippov

debugging/testing interscene accumulation, before LOG

parent a6dac489
......@@ -233,18 +233,22 @@ public class EyesisCorrections {
public ImagePlus getJp4Tiff(
String path,
int [] woi_tops) {
return getJp4Tiff(path, false, woi_tops);
int [] woi_tops,
int [] camera_heights
) {
return getJp4Tiff(path, false, woi_tops, camera_heights);
}
public ImagePlus getJp4Tiff(
String path) {
return getJp4Tiff(path, false, null);
return getJp4Tiff(path, false, null, null);
}
public ImagePlus getJp4Tiff(
String path,
boolean ignore_alien, // open image even if it does not belong to the current camera
int [] woi_tops) {
int [] woi_tops,
int [] camera_heights
) {
// get source file channel
int src_channel = correctionsParameters.getChannelFromSourceTiff(path);
int sub_camera = src_channel - correctionsParameters.firstSubCamera;
......@@ -279,6 +283,9 @@ public class EyesisCorrections {
if (imp.getProperty("WOI_TOP") != null)
woi_tops[sensor_number] = Integer.parseInt((String) imp.getProperty("WOI_TOP"));
}
if ((camera_heights != null) && (sensor_number< camera_heights.length)) { // actually acquired height (not padded)
camera_heights[sensor_number] = imp.getHeight();
}
} else if (!ignore_alien) {
return null;
}
......
......@@ -703,6 +703,7 @@ private Panel panel1,
addButton("Inter Pairs", panelClt5, color_process);
addButton("Inter LMA", panelClt5, color_stop);
addButton("Inter Series", panelClt5, color_process);
addButton("Inter Accumulate", panelClt5, color_process);
plugInFrame.add(panelClt5);
}
......@@ -5125,6 +5126,14 @@ private Panel panel1,
interSeriesLMA();
return;
/* ======================================================================== */
} else if (label.equals("Inter Accumulate")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
CLT_PARAMETERS.batch_run = true;
intersceneAccumulate();
return;
/* ======================================================================== */
} else if (label.equals("Inter LMA")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
......@@ -5646,7 +5655,7 @@ private Panel panel1,
if (DEBUG_LEVEL > -2){
System.out.println("++++++++++++++ Running initSensorFiles for the main camera ++++++++++++++");
}
EYESIS_CORRECTIONS.initSensorFiles(
EYESIS_CORRECTIONS.initSensorFiles( // long
DEBUG_LEVEL+2,
false, // true,
true, // false,
......@@ -6716,6 +6725,73 @@ private Panel panel1,
return true;
}
public boolean intersceneAccumulate() {
long startTime=System.nanoTime();
// load needed sensor and kernels files
if (!prepareRigImages()) return false;
String configPath=getSaveCongigPath();
if (configPath.equals("ABORT")) return false;
setAllProperties(PROPERTIES); // batchRig may save properties with the model. Extrinsics will be updated, others should be set here
if (DEBUG_LEVEL > -2){
System.out.println("++++++++++++++ Testing Interscene processing ++++++++++++++");
}
if (CLT_PARAMETERS.useGPU()) { // only init GPU instances if it is used
if (GPU_TILE_PROCESSOR == null) {
try {
GPU_TILE_PROCESSOR = new GPUTileProcessor(CORRECTION_PARAMETERS.tile_processor_gpu);
} catch (Exception e) {
System.out.println("Failed to initialize GPU class");
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} //final int debugLevel);
}
if (CLT_PARAMETERS.useGPU(false) && (QUAD_CLT != null) && (GPU_QUAD == null)) { // if GPU main is needed
try {
GPU_QUAD = GPU_TILE_PROCESSOR.new GpuQuad(
QUAD_CLT,
4,
3);
} catch (Exception e) {
System.out.println("Failed to initialize GpuQuad class");
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} //final int debugLevel);
QUAD_CLT.setGPU(GPU_QUAD);
}
}
try {
TWO_QUAD_CLT.intersceneAccumulate(
QUAD_CLT, // QuadCLT quadCLT_main,
CLT_PARAMETERS, // EyesisCorrectionParameters.DCTParameters dct_parameters,
DEBAYER_PARAMETERS, //EyesisCorrectionParameters.DebayerParameters debayerParameters,
COLOR_PROC_PARAMETERS, //EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
CHANNEL_GAINS_PARAMETERS, //CorrectionColorProc.ColorGainsParameters channelGainParameters,
RGB_PARAMETERS, //EyesisCorrectionParameters.RGBParameters rgbParameters,
EQUIRECTANGULAR_PARAMETERS, // EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
PROPERTIES, // Properties properties,
THREADS_MAX, //final int threadsMax, // maximal number of threads to launch
UPDATE_STATUS, //final boolean updateStatus,
DEBUG_LEVEL);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //final int debugLevel);
if (configPath!=null) {
saveTimestampedProperties( // save config again
configPath, // full path or null
null, // use as default directory if path==null
true,
PROPERTIES);
}
System.out.println("batchRig(): Processing finished at "+
IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+" sec, --- Free memory="+
Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
return true;
}
......
......@@ -63,6 +63,7 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
......@@ -2718,19 +2719,33 @@ public class GPUTileProcessor {
* by the caller. They are calculated by recalculating from the reference scene after appropriate transformation (shift, rotation
* and ERS correction)
* @param pXpYD Array of per-tile pX, pY and disparity triplets (or nulls for undefined tiles).
* @param task_code Put this value (typically 512?) for each tile in task field.
* @param geometryCorrection GeometryCorrection instance for the camera.
* @param disparity_corr Disparity correction at infinity
* @param margin Skip tile if at least one channel tile center is closer to the image edge than this margin.
* @param valid_tiles Optional (if not null) should be initialized as boolean [tiles] - will contain valid tiles
* @param threadsMax Maximal number of threads to run concurrently.
* @return Array of TpTask instances (fully prepared) to be fed to the GPU
*/
public TpTask[] setInterTasks(
double [][] pXpYD, // per-tile array of pX,pY,disparity triplets (or nulls)
int task_code, // code to use for active tiles
final double [][] pXpYD, // per-tile array of pX,pY,disparity triplets (or nulls)
final GeometryCorrection geometryCorrection,
final double disparity_corr,
final int margin, // do not use tiles if their centers are closer to the edges
final boolean [] valid_tiles,
final int threadsMax) // maximal number of threads to launch
{
final int task_code = ((1 << NUM_PAIRS)-1) << TASK_CORR_BITS; // correlation only
final double min_px = margin;
final double max_px = img_width - 1 - margin;
final double [] min_py = new double[num_cams] ;
final double [] max_py = new double[num_cams] ;
for (int i = 0; i < num_cams; i++) {
min_py [i] = margin + geometryCorrection.getWOITops()[i];
max_py [i] = geometryCorrection.getWOITops()[i] + geometryCorrection.getCameraHeights()[i] - 1 - margin;
}
if (valid_tiles!=null) {
Arrays.fill(valid_tiles, false);
}
final int tilesX = img_width / DTT_SIZE;
final int tiles = pXpYD.length;
final Matrix [] corr_rots = geometryCorrection.getCorrVector().getRotMatrices(); // get array of per-sensor rotation matrices
......@@ -2738,33 +2753,23 @@ public class GPUTileProcessor {
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger aTiles = new AtomicInteger(0);
final int [] tile_indices = new int [tiles];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) if (pXpYD[nTile] != null) {
tile_indices[aTiles.getAndIncrement()] = nTile;
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
final TpTask[] tp_tasks = new TpTask[aTiles.get()];
final TpTask[] tp_tasks = new TpTask[tiles]; // aTiles.get()];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int indx = ai.getAndIncrement(); indx < tp_tasks.length; indx = ai.getAndIncrement()) {
int nTile = tile_indices[indx];
// for (int indx = ai.getAndIncrement(); indx < tp_tasks.length; indx = ai.getAndIncrement()) {
// int nTile = tile_indices[indx];
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) if (pXpYD[nTile] != null) {
TpTask tp_task = new TpTask();
int tileY = nTile / tilesX;
int tileX = nTile % tilesX;
tp_tasks[nTile].ty = tileY;
tp_tasks[nTile].tx = tileX;
tp_tasks[nTile].task = task_code;
tp_task.ty = tileY;
tp_task.tx = tileX;
tp_task.task = task_code;
double disparity = pXpYD[nTile][2] + disparity_corr;
tp_tasks[nTile].target_disparity = (float) disparity; // will it be used?
tp_task.target_disparity = (float) disparity; // will it be used?
double [][] disp_dist_main = new double[quad_main][]; // used to correct 3D correlations (not yet used here)
double [][] centersXY_main = geometryCorrection.getPortsCoordinatesAndDerivatives(
geometryCorrection, // GeometryCorrection gc_main,
......@@ -2776,17 +2781,32 @@ public class GPUTileProcessor {
pXpYD[nTile][0],
pXpYD[nTile][1],
disparity); // + disparity_corr);
tp_tasks[nTile].xy = new float [centersXY_main.length][2];
tp_task.xy = new float [centersXY_main.length][2];
boolean bad_margins = false;
for (int i = 0; i < centersXY_main.length; i++) {
tp_tasks[nTile].xy[i][0] = (float) centersXY_main[i][0];
tp_tasks[nTile].xy[i][1] = (float) centersXY_main[i][1];
if ( (centersXY_main[i][0] < min_px) || (centersXY_main[i][0] > max_px) ||
(centersXY_main[i][1] < min_py[i]) || (centersXY_main[i][1] > max_py[i])) {
bad_margins = true;
break;
}
tp_task.xy[i][0] = (float) centersXY_main[i][0];
tp_task.xy[i][1] = (float) centersXY_main[i][1];
}
if (bad_margins) {
continue;
}
tp_tasks[aTiles.getAndIncrement()] = tp_task;
if (valid_tiles!=null) {
valid_tiles[nTile] = true;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return tp_tasks;
final TpTask[] tp_tasks_out = new TpTask[aTiles.get()];
System.arraycopy(tp_tasks, 0, tp_tasks_out, 0, tp_tasks_out.length);
return tp_tasks_out;
}
......
......@@ -357,6 +357,7 @@ public class ErsCorrection extends GeometryCorrection {
for (String ts:scenes_poses.keySet()) {
scenes[i++] = ts;
}
Arrays.sort(scenes);
return scenes;
}
......@@ -678,6 +679,7 @@ public class ErsCorrection extends GeometryCorrection {
extrinsic_corr = gc.extrinsic_corr; // ;
rigOffset = gc.rigOffset; // = null;
woi_tops = gc.woi_tops; // = null; // used to calculate scanline timing
camera_heights = gc.camera_heights; // = null; // used to calculate scanline timing
if (deep) {
forward = clone1d(forward);
right = clone1d(right);
......@@ -692,6 +694,7 @@ public class ErsCorrection extends GeometryCorrection {
extrinsic_corr = extrinsic_corr.clone();
if (rigOffset!=null) rigOffset = rigOffset.clone();
woi_tops = clone1d(woi_tops);
camera_heights = clone1d(camera_heights);
}
resetScenes(); // no scenes yet
// generate initial ers velocity and roll
......
......@@ -111,6 +111,7 @@ public class GeometryCorrection {
public RigOffset rigOffset = null;
public int [] woi_tops = null; // used to calculate scanline timing
public int [] camera_heights = null; // actual acquired lines (from woi_tops)
public float [] toFloatArray() { // for GPU comparison
......@@ -155,6 +156,7 @@ public class GeometryCorrection {
(float) cameraRadius, // average distance from the "mass center" of the sensors to the sensors
(float) disparityRadius, //=150.0; // distance between cameras to normalize disparity units to. sqrt(2)*disparityRadius for quad
woi_tops[0],woi_tops[1],woi_tops[2],woi_tops[3]
// TODO: ADD camera_heights[0], camera_heights[1], camera_heights[2], camera_heights[3],
};
}
public static int arrayLength(int ncam) {
......@@ -199,12 +201,17 @@ public class GeometryCorrection {
cameraRadius, // average distance from the "mass center" of the sensors to the sensors
disparityRadius, //=150.0; // distance between cameras to normalize disparity units to. sqrt(2)*disparityRadius for quad
woi_tops[0],woi_tops[1],woi_tops[2],woi_tops[3]
// TODO: ADD camera_heights[0], camera_heights[1], camera_heights[2], camera_heights[3],
};
}
public int [] getWOITops() {// not used in lwir
return woi_tops;
}
public int [] getCameraHeights() {
return camera_heights;
}
public double [][] getPXY0(){
return this.pXY0;
......@@ -349,6 +356,7 @@ public class GeometryCorrection {
pXY0 = new double [numSensors][2];
rXY = new double [numSensors][2];
woi_tops = new int [numSensors];
camera_heights = new int [numSensors];
resetCorrVector();
}
......
......@@ -51,7 +51,7 @@ public class ImageDtt extends ImageDttCPU {
final int [][] tile_op, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
final float [][][][] fcorr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
final float [][][][] fcorr_combo_td, // [4][tilesY][tilesX][pair][4*64] TD of combo corrs: qud, cross, hor,vert
final float [][][][] fcorr_combo_td, // [4][tilesY][tilesX][4*64] TD of combo corrs: qud, cross, hor,vert
// each of the top elements may be null to skip particular combo type
final float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
final float [][][][] fpxpy, // [tilesY][tilesX][cams][2], tile {pX,pY}
......@@ -240,17 +240,18 @@ public class ImageDtt extends ImageDttCPU {
}
}
/*
DttRad2 dtt = new DttRad2(transform_size);
dtt.set_window(window_type);
final double [] lt_window = dtt.getWin2d(); // [256] - never used
final double [] lt_window2 = new double [lt_window.length]; // squared - never used
for (int i = 0; i < lt_window.length; i++) lt_window2[i] = lt_window[i] * lt_window[i];
if (globalDebugLevel > 1) {
ShowDoubleFloatArrays sdfa_instance = new ShowDoubleFloatArrays(); // just for debugging?
sdfa_instance.showArrays(lt_window, 2*transform_size, 2*transform_size, "lt_window");
}
*/
if (globalDebugLevel > 0) {
System.out.println("macro_mode="+macro_mode);
}
......@@ -429,7 +430,7 @@ public class ImageDtt extends ImageDttCPU {
gpuQuad.execCorr2D_TD(col_weights); // Get TD version of correlations (may be read out and saved)
final int [] corr_indices = gpuQuad.getCorrIndices();
if (fcorr_td != null) {
gpuQuad.getCorrTilesTd(fcorr_td); // generate time domain correlation pairs
gpuQuad.getCorrTilesTd(fcorr_td); // generate transform domain correlation pairs
}
gpuQuad.execCorr2D_normalize(
......@@ -444,7 +445,7 @@ public class ImageDtt extends ImageDttCPU {
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x0f); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
if ((fcorr_combo_td != null) && (fcorr_combo_td.length >= 0) && (fcorr_combo_td[0] != null)) {
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[0]); // generate time domain correlation pairs for quad ortho combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[0]); // generate transform domain correlation pairs for quad ortho combination
}
// normalize and convert to pixel domain
gpuQuad.execCorr2D_normalize(
......@@ -460,7 +461,7 @@ public class ImageDtt extends ImageDttCPU {
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x30); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
if ((fcorr_combo_td != null) && (fcorr_combo_td.length >= 1) && (fcorr_combo_td[1] != null)) {
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[1]); // generate time domain correlation pairs for cross diagonal combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[1]); // generate transform domain correlation pairs for cross diagonal combination
}
gpuQuad.execCorr2D_normalize(
true, // boolean combo, // normalize combo correlations (false - per-pair ones)
......@@ -474,7 +475,7 @@ public class ImageDtt extends ImageDttCPU {
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x03); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
if ((fcorr_combo_td != null) && (fcorr_combo_td.length >= 2) && (fcorr_combo_td[2] != null)) {
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[2]); // generate time domain correlation pairs for horizontal combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[2]); // generate transform domain correlation pairs for horizontal combination
}
gpuQuad.execCorr2D_normalize(
true, // boolean combo, // normalize combo correlations (false - per-pair ones)
......@@ -487,7 +488,7 @@ public class ImageDtt extends ImageDttCPU {
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x0c); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
if ((fcorr_combo_td != null) && (fcorr_combo_td.length >= 3) && (fcorr_combo_td[3] != null)) {
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[3]); // generate time domain correlation pairs for vertical combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[3]); // generate transform domain correlation pairs for vertical combination
}
gpuQuad.execCorr2D_normalize(
true, // boolean combo, // normalize combo correlations (false - per-pair ones)
......@@ -655,6 +656,125 @@ public class ImageDtt extends ImageDttCPU {
// return clt_data;
}
// calculate FD correlations for specified pXpYD array to use for interscene accumulation
public void quadCorrTD(
final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
final double [][] pXpYD, // per-tile array of pX,pY,disparity triplets (or nulls)
final float [][][][] fcorr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
final float [][][][] fcorr_combo_td, // [4][tilesY][tilesX][pair][4*64] TD of combo corrs: qud, cross, hor,vert
final GeometryCorrection geometryCorrection,
final double disparity_corr, // disparity offset at infinity
final int margin, // do not use tiles if their centers are closer to the edges
final double gpu_sigma_r, // 0.9, 1.1
final double gpu_sigma_b, // 0.9, 1.1
final double gpu_sigma_g, // 0.6, 0.7
final double gpu_sigma_m, // = 0.4; // 0.7;
final double gpu_sigma_rb_corr, // = 0.5; // apply LPF after accumulating R and B correlation before G, monochrome ? 1.0 :
final double gpu_sigma_corr, // = 0.9;gpu_sigma_corr_m
final double corr_red, // +used
final double corr_blue,// +used
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int numcol = isMonochrome()?1:3;
final double [] col_weights= new double [numcol]; // colors are RBG
if (isMonochrome()) {
col_weights[0] = 0;
// col_weights[2] = 1.0;// green color/mono
// col_weights[0] = 0;
// col_weights[1] = 0;
} else {
col_weights[2] = 1.0/(1.0 + corr_red + corr_blue); // green color
col_weights[0] = corr_red * col_weights[2];
col_weights[1] = corr_blue * col_weights[2];
}
// prepare tasks
final GPUTileProcessor.TpTask[] tp_tasks = gpuQuad.setInterTasks(
pXpYD, // final double [][] pXpYD, // per-tile array of pX,pY,disparity triplets (or nulls)
geometryCorrection, // final GeometryCorrection geometryCorrection,
disparity_corr, // final double disparity_corr,
margin, // final int margin, // do not use tiles if their centers are closer to the edges
null, // final boolean [] valid_tiles,
threadsMax); // final int threadsMax) // maximal number of threads to launch
//texture_tiles
final float [][] lpf_rgb = new float[][] {
floatGetCltLpfFd(gpu_sigma_r),
floatGetCltLpfFd(gpu_sigma_b),
floatGetCltLpfFd(gpu_sigma_g),
floatGetCltLpfFd(gpu_sigma_m)
};
gpuQuad.setLpfRbg( // constants memory - same for all cameras
lpf_rgb,
globalDebugLevel > -1);
final float [] lpf_flat = floatGetCltLpfFd(gpu_sigma_corr);
gpuQuad.setLpfCorr(// constants memory - same for all cameras
"lpf_corr", // String const_name, // "lpf_corr"
lpf_flat,
globalDebugLevel > -1);
final float [] lpf_rb_flat = floatGetCltLpfFd(gpu_sigma_rb_corr);
gpuQuad.setLpfCorr(// constants memory - same for all cameras
"lpf_rb_corr", // String const_name, // "lpf_corr"
lpf_rb_flat,
globalDebugLevel > -1);
gpuQuad.setTasks( // copy tp_tasks to the GPU memory
tp_tasks, // TpTask [] tile_tasks,
false, // use_aux); // boolean use_aux)
imgdtt_params.gpu_verify); // boolean verify
// used alternative method to prepare tasks, not centered in the tile centers
/// gpuQuad.execSetTilesOffsets(); // prepare tiles offsets in GPU memory
// Skipping if ((fdisp_dist != null) || (fpxpy != null)) {...
gpuQuad.execConvertDirect();
//Generate 2D phase correlations from the CLT representation
gpuQuad.execCorr2D_TD(col_weights); // Get TD version of correlations
final int [] corr_indices = gpuQuad.getCorrIndices();
if (fcorr_td != null) {
gpuQuad.getCorrTilesTd(fcorr_td); // generate transform domain correlation pairs
}
// Combine 4 ortho pairs
if (fcorr_combo_td != null) {
if ((fcorr_combo_td.length >= 0) && (fcorr_combo_td[0] != null)) {
gpuQuad.execCorr2D_combine( // calculate cross pairs
true, // boolean init_corr, // initialize output tiles (false - add to current)
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x0f); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[0]); // generate transform domain correlation pairs for quad ortho combination
}
// Combine 2 diagonal pairs
if ((fcorr_combo_td.length >= 1) && (fcorr_combo_td[1] != null)) {
gpuQuad.execCorr2D_combine( // calculate cross pairs
true, // boolean init_corr, // initialize output tiles (false - add to current)
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x30); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[1]); // generate transform domain correlation pairs for cross diagonal combination
}
// Combine 2 horizontal pairs
if ((fcorr_combo_td.length >= 2) && (fcorr_combo_td[2] != null)) {
gpuQuad.execCorr2D_combine( // calculate cross pairs
true, // boolean init_corr, // initialize output tiles (false - add to current)
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x03); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[2]); // generate transform domain correlation pairs for horizontal combination
}
// Combine 2 vertical pairs
if ((fcorr_combo_td.length >= 3) && (fcorr_combo_td[3] != null)) {
gpuQuad.execCorr2D_combine( // calculate cross pairs
true, // boolean init_corr, // initialize output tiles (false - add to current)
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x0c); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[3]); // generate transform domain correlation pairs for vertical combination
}
}
}
public GPUTileProcessor.TpTask[][] clt_aberrations_quad_corr_GPU_test(
final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
final int macro_scale, // to correlate tile data instead of the pixel data: 1 - pixels, 8 - tiles
......@@ -851,6 +971,7 @@ public class ImageDtt extends ImageDttCPU {
}
}
/*
DttRad2 dtt = new DttRad2(transform_size);
dtt.set_window(window_type);
final double [] lt_window = dtt.getWin2d(); // [256] - never used
......@@ -862,6 +983,7 @@ public class ImageDtt extends ImageDttCPU {
ShowDoubleFloatArrays sdfa_instance = new ShowDoubleFloatArrays(); // just for debugging?
sdfa_instance.showArrays(lt_window, 2*transform_size, 2*transform_size, "lt_window");
}
*/
if (globalDebugLevel > 0) {
System.out.println("macro_mode="+macro_mode);
}
......@@ -1068,7 +1190,7 @@ public class ImageDtt extends ImageDttCPU {
gpuQuad.execCorr2D_TD(col_weights); // Get TD version of correlations (may be read out and saved)
final int [] corr_indices = gpuQuad.getCorrIndices();
if (fcorr_td != null) {
gpuQuad.getCorrTilesTd(fcorr_td); // generate time domain correlation pairs
gpuQuad.getCorrTilesTd(fcorr_td); // generate transform domain correlation pairs
}
gpuQuad.execCorr2D_normalize(
......@@ -1083,7 +1205,7 @@ public class ImageDtt extends ImageDttCPU {
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x0f); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
if ((fcorr_combo_td != null) && (fcorr_combo_td.length >= 0) && (fcorr_combo_td[0] != null)) {
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[0]); // generate time domain correlation pairs for quad ortho combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[0]); // generate transform domain correlation pairs for quad ortho combination
}
// normalize and convert to pixel domain
gpuQuad.execCorr2D_normalize(
......@@ -1099,7 +1221,7 @@ public class ImageDtt extends ImageDttCPU {
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x30); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
if ((fcorr_combo_td != null) && (fcorr_combo_td.length >= 1) && (fcorr_combo_td[1] != null)) {
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[1]); // generate time domain correlation pairs for cross diagonal combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[1]); // generate transform domain correlation pairs for cross diagonal combination
}
gpuQuad.execCorr2D_normalize(
true, // boolean combo, // normalize combo correlations (false - per-pair ones)
......@@ -1113,7 +1235,7 @@ public class ImageDtt extends ImageDttCPU {
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x03); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
if ((fcorr_combo_td != null) && (fcorr_combo_td.length >= 2) && (fcorr_combo_td[2] != null)) {
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[2]); // generate time domain correlation pairs for horizontal combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[2]); // generate transform domain correlation pairs for horizontal combination
}
gpuQuad.execCorr2D_normalize(
true, // boolean combo, // normalize combo correlations (false - per-pair ones)
......@@ -1126,7 +1248,7 @@ public class ImageDtt extends ImageDttCPU {
GPUTileProcessor.NUM_PAIRS, // int num_pairs_in, // typically 6 - number of pairs per tile (tile task should have same number per each tile
0x0c); // int pairs_mask // selected pairs (0x3 - horizontal, 0xc - vertical, 0xf - quad, 0x30 - cross)
if ((fcorr_combo_td != null) && (fcorr_combo_td.length >= 3) && (fcorr_combo_td[3] != null)) {
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[3]); // generate time domain correlation pairs for vertical combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[3]); // generate transform domain correlation pairs for vertical combination
}
gpuQuad.execCorr2D_normalize(
true, // boolean combo, // normalize combo correlations (false - per-pair ones)
......@@ -1423,11 +1545,13 @@ public class ImageDtt extends ImageDttCPU {
}
}
/*
DttRad2 dtt = new DttRad2(transform_size);
dtt.set_window(window_type);
final double [] lt_window = dtt.getWin2d(); // [256] - never used
final double [] lt_window2 = new double [lt_window.length]; // squared - never used
for (int i = 0; i < lt_window.length; i++) lt_window2[i] = lt_window[i] * lt_window[i];
*/
/// final boolean use_main = geometryCorrection_main != null;
/// final int all_pairs = imgdtt_params.dbg_pair_mask; //TODO: use tile tasks
......@@ -1494,6 +1618,8 @@ public class ImageDtt extends ImageDttCPU {
}
final int num_tile_corr = nc0; // normally 6
final int num_tiles = corr_indices.length / num_tile_corr;
// Runtime.getRuntime().gc();
// System.out.println("--- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
for (int ithread = 0; ithread < threads.length; ithread++) {
......@@ -1521,6 +1647,9 @@ public class ImageDtt extends ImageDttCPU {
int tileX = nt % tilesX;
int tileY = nt / tilesX;
int tIndex = tileY * tilesX + tileX;
// if (tileY >= 122) {
// System.out.println("tileY="+tileY+" tileX="+tileX);
// }
// Prepare the same (currently 10-layer) corrs as double [][], as in CPU version
int pair_mask = 0;
......@@ -1595,7 +1724,7 @@ public class ImageDtt extends ImageDttCPU {
} else {
// no correlation tiles to process
}
if ((dbg_distort != null) &&(globalDebugLevel >=0)) {
if ((dbg_distort != null) &&(globalDebugLevel >= 0)) {
(new ShowDoubleFloatArrays()).showArrays(dbg_distort, tilesX, tilesY, true, "disparity_distortions"); // , dbg_titles);
}
/*
......@@ -1870,7 +1999,7 @@ public class ImageDtt extends ImageDttCPU {
// debug new LMA correlations
if (debugTile) {
System.out.println("Will run new LMA for tileX="+tileX+", tileY="+tileY+"\n\n\n*** Disabled fro the GPU ***\n\n\n");
System.out.println("Will run new LMA for tileX="+tileX+", tileY="+tileY+"\n\n\n*** Disabled for the GPU ***\n\n\n");
// temporarily disabling for the GPU (can be restored as disp_dist is available)
/*
double [] poly_disp = {Double.NaN, 0.0};
......
......@@ -24,6 +24,7 @@ package com.elphel.imagej.tileprocessor;
*/
// ← → ↑ ↓ ⇖ ⇗ ⇘ ⇙ ↔ ↕
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.cameras.CLTParameters;
......@@ -125,6 +126,10 @@ public class ImageDttCPU {
"g0","g1","g2","g3",
"b0","b1","b2","b3",
};
static public String[] CORR_TITLES = {
"top","bottom","left","right","diag-m","diag-o",
"quad","cross","hor","vert",
"s-hor","s-vert","s-quad","s-cross","s-quad-cross","s-combo"};
// "dbg0","dbg1","dbg2","dbg3","dbg4","dbg5","dbg6","dbg7","dbg8","dbg9","dbg10","dbg11","dbg12","dbg13","dbg14","dbg15","dbg16","dbg17","dbg18"};
static int BI_DISP_FULL_INDEX = 0; // 0 - disparity for all directions of the main camera
......@@ -5880,10 +5885,81 @@ public class ImageDttCPU {
}
// final float [][][][] fcorr_td = new float[tilesY][tilesX][][];
// final float [][][][] fcorr_combo_td = new float[4][tilesY][tilesX][];
public static float [][] corr_td_dbg(
final float [][][][] fcorr_td,
// if 0 - fcorr_combo_td = new float[4][tilesY][tilesX][];
// if > 0 - fcorr_td = new float[tilesY][tilesX][num_slices][];
final int num_slices,
final int transform_size,
final int [] wh, // should be initialized as int[2];
final int threadsMax) // maximal number of threads to launch
{
final int tilesY = (num_slices == 0) ? fcorr_td[0].length : fcorr_td.length;
final int tilesX = (num_slices == 0) ? fcorr_td[0][0].length : fcorr_td[0].length;
final int nTiles = tilesX*tilesY;
final int width = tilesX * 2 * transform_size;
final int height = tilesY * 2 * transform_size;
if (wh != null) {
wh[0] = width;
wh[1] = height;
}
final int fnum_slices = (num_slices == 0) ? fcorr_td.length : num_slices;
final int transform_len = transform_size*transform_size; // 64
float [][] dbg_img = new float [fnum_slices][width * height];
for (int i = 0; i < dbg_img.length; i++) {
Arrays.fill(dbg_img[i], Float.NaN);
}
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
int tileY = nTile/tilesX;
int tileX = nTile - tileY * tilesX;
if ((num_slices == 0) || (fcorr_td[tileY][tileX] != null)) {
for (int slice = 0; slice < fnum_slices; slice ++) {
float [] ftile = (num_slices > 0) ? fcorr_td[tileY][tileX][slice] : fcorr_td[slice][tileY][tileX];
if (ftile != null) {
for (int qy = 0; qy < 2; qy++) {
for (int qx = 0; qx < 2; qx++) {
for (int ty = 0; ty < transform_size; ty++) {
int py = (tileY * 2 + qy) * transform_size + ty;
int px = (tileX * 2 + qx) * transform_size;
System.arraycopy(
ftile,
(2 * qy + qx) * transform_len + transform_size * ty,
dbg_img[slice],
py * width + px,
transform_size);
/*
for (int tx = 0; tx < transform_size; tx++) {
int px = (tileX * 2 + qx) * transform_size + tx;
dbg_img[slice][py * width + px] = ftile[(2 * qy + qx) * transform_len + transform_size * ty + tx];
}
*/
}
}
}
}
}
}
}
}
};
}
startAndJoin(threads);
return dbg_img;
}
// extract correlation result in linescan order (for visualization)
public double [][] corr_partial_dbg( // not used in lwir
public static double [][] corr_partial_dbg( // not used in lwir
final double [][][][][] corr_data,
final int corr_size,
final int pairs,
......
......@@ -29,8 +29,12 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.DoubleAccumulator;
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.cameras.ColorProcParameters;
import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.gpu.GPUTileProcessor;
import ij.IJ;
public class OpticalFlow {
public static double [] ZERO3 = {0.0,0.0,0.0};
......@@ -229,6 +233,9 @@ public class OpticalFlow {
}
}
/**
* Calculate confidence for the interscene X,Y correlation
* @param flowXY per-macrotile array of per-tile X,Y of the optical flow vectors. May have nulls
......@@ -2062,6 +2069,7 @@ public class OpticalFlow {
for (int i = 0; i < nscenes; i++) {
int indx = dsrbg.length - i - 1;
time_stamps[i] = scenes[indx].getImageName();
System.out.println("\n"+i+ ": "+ time_stamps[i]+" compareRefSceneTiles()");
if ((i == 0) && !blur_reference) {
dsrbg[0]= scenes[indx_ref].getDSRBG();
} else {
......@@ -2220,6 +2228,319 @@ public class OpticalFlow {
title); // dsrbg_titles);
}
public double [][] getSceneDisparityStrength(
final boolean to_ref_disparity, // false - return scene disparity, true - convert disparity back to the reference scene
final double [] disparity_ref, // invalid tiles - NaN in disparity
final double [] disparity_scene, // invalid tiles - NaN in disparity (just for masking out invalid scene tiles)
final double [] strength_scene, // to calculate interpolated strength
final double [] scene_xyz, // camera center in world coordinates
final double [] scene_atr, // camera orientation relative to world frame
final double [] scene_ers_xyz_dt, // camera ERS linear
final double [] scene_ers_atr_dt, // camera ERS linear
final QuadCLT scene_QuadClt,
final QuadCLT reference_QuadClt,
final int margin,
final double tolerance_ref_absolute,
final double tolerance_ref_relative,
final double tolerance_scene_absolute, // of 4 bi-linear interpolation corners
final double tolerance_scene_relative) // of 4 bi-linear interpolation corners
{
TileProcessor tp = reference_QuadClt.getTileProcessor();
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
final int transform_size = tp.getTileSize();
final int tiles = tilesX*tilesY;
final double scene_disparity_cor = 0.0;
final boolean [] valid_tiles = new boolean[tiles];
scene_QuadClt.getErsCorrection().setErsDt(
scene_ers_xyz_dt, // double [] ers_xyz_dt,
scene_ers_atr_dt); // double [] ers_atr_dt)(ers_scene_original_xyz_dt);
//setupERS() will be inside transformToScenePxPyD()
double [][] scene_pXpYD = transformToScenePxPyD( // will be null for disparity == NaN
disparity_ref, // final double [] disparity_ref, // invalid tiles - NaN in disparity (maybe it should not be masked by margins?)
scene_xyz, // final double [] scene_xyz, // camera center in world coordinates
scene_atr, // final double [] scene_atr, // camera orientation relative to world frame
scene_QuadClt, // final QuadCLT scene_QuadClt,
reference_QuadClt); // final QuadCLT reference_QuadClt)
scene_QuadClt.getGpuQuad().setInterTasks(
scene_pXpYD, // final double [][] pXpYD, // per-tile array of pX,pY,disparity triplets (or nulls)
scene_QuadClt.getGeometryCorrection(), // final GeometryCorrection geometryCorrection,
scene_disparity_cor, // final double disparity_corr,
margin, // final int margin, // do not use tiles if their centers are closer to the edges
valid_tiles, // final boolean [] valid_tiles,
threadsMax); // final int threadsMax) // maximal number of threads to launch
final double [][] disparity_strength = new double [2][tiles];
Arrays.fill(disparity_strength[0], Double.NaN);
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [] corners = new double [4];
double [] strengths = new double [4];
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) if (valid_tiles[nTile]){
double pX = scene_pXpYD[nTile][0];
double pY = scene_pXpYD[nTile][1];
double tX = (pX - transform_size/2)/transform_size;
double tY = (pY - transform_size/2)/transform_size;
double disp_from_ref = scene_pXpYD[nTile][2];
int itX0 = (int) Math.floor(tX);
int itY0 = (int) Math.floor(tY);
double kX = tX - itX0;
double kY = tY - itY0;
double [] corner_weights = {(1.0-kX)*(1.0-kY), kX*(1.0-kY),(1.0-kX)*kY, kX*kY};
int itX1 = itX0 + 1;
if (itX1 >= tilesX) {
itX1 = tilesX - 1;
}
int itY1 = itY0 + 1;
if (itY1 >= tilesY) {
itY1 = tilesY - 1;
}
corners[0] = disparity_scene[itX0 + itY0 * tilesX];
corners[1] = disparity_scene[itX1 + itY0 * tilesX];
corners[2] = disparity_scene[itX0 + itY1 * tilesX];
corners[3] = disparity_scene[itX1 + itY1 * tilesX];
strengths[0] = strength_scene[itX0 + itY0 * tilesX];
strengths[1] = strength_scene[itX1 + itY0 * tilesX];
strengths[2] = strength_scene[itX0 + itY1 * tilesX];
strengths[3] = strength_scene[itX1 + itY1 * tilesX];
double disp_tol_ref = tolerance_ref_absolute + disp_from_ref * tolerance_ref_relative;
double disp_min_ref = disp_from_ref - disp_tol_ref;
double disp_max_ref = disp_from_ref + disp_tol_ref;
int idisp_min = 0, idisp_max = 0;
int num_corners = 0;
for (int i = 0; i < 4; i++) {
if (!Double.isNaN(corners[i])) {
if ((corners[i] < disp_min_ref) || (corners[i] > disp_max_ref)){
corners[i] = Double.NaN;
continue;
}
if (!(corners[i] >= corners[idisp_min])) {
idisp_min = i;
}
if (!(corners[i] <= corners[idisp_max])) {
idisp_max = i;
}
num_corners++;
}
}
if (num_corners > 0) {
double disp_half = 0.5* (corners[idisp_min] + corners[idisp_max]);
double disp_range = 2 * (tolerance_scene_absolute + tolerance_ref_relative * disp_half);
while ((num_corners > 0) && ((corners[idisp_max] - corners[idisp_min]) > disp_range )) {
num_corners--;
if (num_corners > 0) {
if (disp_half > disp_from_ref) { // remove max
corners[idisp_max] = Double.NaN;
// find new max
idisp_max = idisp_min;
for (int i = 0; i < 4; i++) {
if (!(corners[i] <= corners[idisp_max])) {
idisp_max = i;
}
}
} else {
corners[idisp_min] = Double.NaN;
// find new min
idisp_min = idisp_max;
for (int i = 0; i < 4; i++) {
if (!(corners[i] >= corners[idisp_min])) {
idisp_min = i;
}
}
}
}
}
if (num_corners > 0) {
double sw=0.0, swd = 0.0, sws = 0.0;
for (int i = 0; i < 4; i++) {
if (!Double.isNaN(corners[i])) {
sw += corner_weights[i];
swd += corner_weights[i] * corners[i];
sws += corner_weights[i] * strengths[i];
}
}
disparity_strength[0][nTile] = swd / sw;
disparity_strength[1][nTile] = sws / sw;
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (to_ref_disparity) {
ai.set(0);
//double [][] scene_pXpYD
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) if (scene_pXpYD != null) {
if (Double.isNaN(disparity_strength[0][nTile])) {
scene_pXpYD[nTile] = null;
} else { // replace scene disparity (strength will stay the same
scene_pXpYD[nTile][2] = disparity_strength[0][nTile];
}
}
}
};
}
ImageDtt.startAndJoin(threads);
double [][] toref_pXpYD = transformFromScenePxPyD(
scene_pXpYD, // final double [][] pXpYD_scene, // tiles correspond to reference, pX,pY,D - for scene
scene_xyz, // final double [] scene_xyz, // camera center in world coordinates
scene_atr, // final double [] scene_atr, // camera orientation relative to world frame
scene_QuadClt, // final QuadCLT scene_QuadClt,
reference_QuadClt); // final QuadCLT reference_QuadClt)
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) {
if (toref_pXpYD[nTile] != null) {
disparity_strength[0][nTile] = toref_pXpYD[nTile][2];
} else {
disparity_strength[0][nTile] = Double.NaN;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
return disparity_strength;
}
public double [][] transformToScenePxPyD(
final double [] disparity_ref, // invalid tiles - NaN in disparity
final double [] scene_xyz, // camera center in world coordinates
final double [] scene_atr, // camera orientation relative to world frame
final QuadCLT scene_QuadClt,
final QuadCLT reference_QuadClt)
{
TileProcessor tp = reference_QuadClt.getTileProcessor();
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
final int tiles = tilesX*tilesY;
final int transform_size = tp.getTileSize();
final double [][] pXpYD= new double [tiles][];
final ErsCorrection ersReferenceCorrection = reference_QuadClt.getErsCorrection();
final ErsCorrection ersSceneCorrection = scene_QuadClt.getErsCorrection();
ersReferenceCorrection.setupERS(); // just in case - setUP using instance paRAMETERS
ersSceneCorrection.setupERS();
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) if (!Double.isNaN(disparity_ref[nTile])) {
double disparity = disparity_ref[nTile];
int tileY = nTile / tilesX;
int tileX = nTile % tilesX;
double centerX = tileX * transform_size + transform_size/2; // - shiftX;
double centerY = tileY * transform_size + transform_size/2; // - shiftY;
if (disparity < 0) {
disparity = 0.0;
}
if (scene_QuadClt == reference_QuadClt) {
pXpYD[nTile] = new double [] {centerX, centerY, disparity};
} else {
pXpYD[nTile] = ersReferenceCorrection.getImageCoordinatesERS( // ersCorrection - reference
scene_QuadClt, // QuadCLT cameraQuadCLT, // camera station that got image to be to be matched
centerX, // double px, // pixel coordinate X in the reference view
centerY, // double py, // pixel coordinate Y in the reference view
disparity, // double disparity, // reference disparity
true, // boolean distortedView, // This camera view is distorted (diff.rect), false - rectilinear
ZERO3, // double [] reference_xyz, // this view position in world coordinates (typically ZERO3)
ZERO3, // double [] reference_atr, // this view orientation relative to world frame (typically ZERO3)
true, // boolean distortedCamera, // camera view is distorted (false - rectilinear)
scene_xyz, // double [] camera_xyz, // camera center in world coordinates
scene_atr, // double [] camera_atr, // camera orientation relative to world frame
LINE_ERR); // double line_err) // threshold error in scan lines (1.0)
if (pXpYD[nTile] != null) {
if ( (pXpYD[nTile][0] < 0.0) ||
(pXpYD[nTile][1] < 0.0) ||
(pXpYD[nTile][0] > ersSceneCorrection.getSensorWH()[0]) ||
(pXpYD[nTile][1] > ersSceneCorrection.getSensorWH()[1])) {
pXpYD[nTile] = null;
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return pXpYD;
}
public double [][] transformFromScenePxPyD(
final double [][] pXpYD_scene, // tiles correspond to reference, pX,pY,D - for scene
final double [] scene_xyz, // camera center in world coordinates
final double [] scene_atr, // camera orientation relative to world frame
final QuadCLT scene_QuadClt,
final QuadCLT reference_QuadClt)
{
TileProcessor tp = reference_QuadClt.getTileProcessor();
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
final int tiles = tilesX*tilesY;
final double [][] pXpYD= new double [tiles][];
final ErsCorrection ersReferenceCorrection = reference_QuadClt.getErsCorrection();
final ErsCorrection ersSceneCorrection = scene_QuadClt.getErsCorrection();
ersReferenceCorrection.setupERS(); // just in case - setUP using instance paRAMETERS
ersSceneCorrection.setupERS();
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) if (pXpYD_scene[nTile] != null) {
double centerX = pXpYD_scene[nTile][0]; // - shiftX;
double centerY = pXpYD_scene[nTile][1]; // - shiftX;
double disparity = pXpYD_scene[nTile][2];
if (disparity < 0) {
disparity = 0.0;
}
if (scene_QuadClt == reference_QuadClt) {
pXpYD[nTile] = new double [] {centerX, centerY, disparity};
} else {
pXpYD[nTile] = ersSceneCorrection.getImageCoordinatesERS( // ersCorrection - reference
reference_QuadClt, // QuadCLT cameraQuadCLT, // camera station that got image to be to be matched
centerX, // double px, // pixel coordinate X in the reference view
centerY, // double py, // pixel coordinate Y in the reference view
disparity, // double disparity, // reference disparity
true, // boolean distortedView, // This camera view is distorted (diff.rect), false - rectilinear
scene_xyz, // double [] reference_xyz, // this view position in world coordinates (typically ZERO3)
scene_atr, // double [] reference_atr, // this view orientation relative to world frame (typically ZERO3)
true, // boolean distortedCamera, // camera view is distorted (false - rectilinear)
ZERO3, // double [] camera_xyz, // camera center in world coordinates
ZERO3, // double [] camera_atr, // camera orientation relative to world frame
LINE_ERR); // double line_err) // threshold error in scan lines (1.0)
if (pXpYD[nTile] != null) {
if ( (pXpYD[nTile][0] < 0.0) ||
(pXpYD[nTile][1] < 0.0) ||
(pXpYD[nTile][0] > ersReferenceCorrection.getSensorWH()[0]) ||
(pXpYD[nTile][1] > ersReferenceCorrection.getSensorWH()[1])) {
pXpYD[nTile] = null;
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return pXpYD; // Only disparity matters, pX, py - just for testing
}
/**
* Transform scene view to visually match with a reference scene. It is not accurate as it uses resampling and
* related low pass filtering.
......@@ -2320,8 +2641,6 @@ public class OpticalFlow {
double d = pXpYD[2];
azbuffer[nTile].accumulate(pXpYD[2]);
//Z-buffer
// if (!(d < zbuffer[px + py* tilesX])) {
// zbuffer[px + py* tilesX] = d;
if (!(d < azbuffer[nTile].get())) {
if ((spx >= 0) && (spy >= 0) && (spx < stilesX) & (spy < stilesY)) {
int sTile = spx + spy* stilesX;
......@@ -2793,6 +3112,721 @@ public class OpticalFlow {
}
}
public void IntersceneAccumulate(
CLTParameters clt_parameters,
ColorProcParameters colorProcParameters,
QuadCLT ref_scene, // ordered by increasing timestamps
int debug_level
)
{
System.out.println("IntersceneAccumulate(), scene timestamp="+ref_scene.getImageName());
ErsCorrection ers_reference = ref_scene.getErsCorrection();
String [] sts = ers_reference.getScenes();
// get list of all other scenes
int num_scenes = sts.length + 1;
int indx_ref = num_scenes - 1;
QuadCLT [] scenes = new QuadCLT [num_scenes];
scenes[indx_ref] = ref_scene;
for (int i = 0; i < sts.length; i++) {
scenes[i] = ref_scene.spawnQuadCLT(
sts[i],
clt_parameters,
colorProcParameters, //
threadsMax,
-1); // debug_level);
scenes[i].setDSRBG(
clt_parameters, // CLTParameters clt_parameters,
threadsMax, // int threadsMax, // maximal number of threads to launch
updateStatus, // boolean updateStatus,
-1); // debug_level); // int debugLevel)
}
final double [][] combo_dsn = prepareInitialComboDS(
clt_parameters, // final CLTParameters clt_parameters,
scenes, // final QuadCLT [] scenes,
indx_ref, // final int indx_ref,
debug_level-2); // final int debug_level);
final int margin = 8;
final int tilesX = ref_scene.getTileProcessor().getTilesX();
final int tilesY = ref_scene.getTileProcessor().getTilesY();
//// final int tiles =tilesX * tilesY;
if (debug_level >-3) {
String [] dbg_titles = {"disp", "strength", "num_valid"};
(new ShowDoubleFloatArrays()).showArrays(
combo_dsn,
tilesX,
tilesY,
true,
"combo_dsn-initial"+ref_scene.getImageName(),
dbg_titles); // dsrbg_titles);
}
final int max_refines = 10;
for (int nrefine = 0; nrefine < max_refines; nrefine++) {
Runtime.getRuntime().gc();
System.out.println("--- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
double [][] disparity_map =
// double [][][][][] clt_corr_partial =
correlateInterscene(
clt_parameters, // final CLTParameters clt_parameters,
scenes, // final QuadCLT [] scenes,
indx_ref, // final int indx_ref,
combo_dsn[0], // final double [] disparity_ref, // disparity in the reference view tiles (Double.NaN - invalid)
margin, // final int margin,
debug_level); // final int debug_level)
Runtime.getRuntime().gc();
System.out.println("--- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
(new ShowDoubleFloatArrays()).showArrays(
disparity_map,
tilesX,
tilesY,
true,
"accumulated_disparity_map",
ImageDtt.DISPARITY_TITLES
);
// update disparities
final int disparity_index = ImageDtt.DISPARITY_INDEX_CM; // 2
final int strength_index = ImageDtt.DISPARITY_STRENGTH_INDEX; // 10
for (int nTile =0; nTile < combo_dsn[0].length; nTile++) {
if (!Double.isNaN(combo_dsn[0][nTile]) && !Double.isNaN(disparity_map[disparity_index][nTile])) {
combo_dsn[0][nTile] += disparity_map[disparity_index][nTile];
combo_dsn[1][nTile] = disparity_map[strength_index][nTile];
}
}
if (debug_level >-3) {
String [] dbg_titles = {"disp", "strength", "num_valid"};
(new ShowDoubleFloatArrays()).showArrays(
combo_dsn,
tilesX,
tilesY,
true,
"combo_dsn-"+nrefine+"-"+ref_scene.getImageName(),
dbg_titles); // dsrbg_titles);
}
}
/*
if (debug_level > -10){ // -1
ImageDtt image_dtt = new ImageDtt(
clt_parameters.transform_size,
ref_scene.isMonochrome(),
ref_scene.isLwir(),
clt_parameters.getScaleStrength(ref_scene.isAux()),
ref_scene.getGpuQuad());
double [][] dbg_corr_rslt_partial = image_dtt.corr_partial_dbg(
clt_corr_partial,
2*8 - 1, //final int corr_size,
4, // final int pairs,
4, // final int colors,
clt_parameters.corr_border_contrast,
threadsMax,
debug_level);
// titles.length = 15, corr_rslt_partial.length=16!
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
dbg_corr_rslt_partial,
tilesX*(2*8),
tilesY*(2*8),
true,
ref_scene.getImageName()+"-TD-PART_CORR-D"+clt_parameters.disparity,
ImageDtt.CORR_TITLES);
// titles);
}
*/
if (debug_level >-100) {
return;
}
System.out.println("IntersceneAccumulate(), got previous scenes: "+sts.length);
if (debug_level > 1) { // tested OK
System.out.println("IntersceneAccumulate(): preparing image set...");
int nscenes = scenes.length;
// int indx_ref = nscenes - 1;
double [][][] all_scenes_xyzatr = new double [scenes.length][][]; // includes reference (last)
double [][][] all_scenes_ers_dt = new double [scenes.length][][]; // includes reference (last)
all_scenes_xyzatr[indx_ref] = new double [][] {ZERO3,ZERO3};
all_scenes_ers_dt[indx_ref] = new double [][] {
ers_reference.getErsXYZ_dt(),
ers_reference.getErsATR_dt()};
for (int i = 0; i < nscenes; i++) if (i != indx_ref) {
String ts = scenes[i].getImageName();
all_scenes_xyzatr[i] = new double[][] {ers_reference.getSceneXYZ(ts), ers_reference.getSceneATR(ts)};
all_scenes_ers_dt[i] = new double[][] {ers_reference.getSceneErsXYZ_dt(ts), ers_reference.getSceneErsATR_dt(ts)};
}
compareRefSceneTiles(
"" , // String suffix,
true, // false, // boolean blur_reference,
all_scenes_xyzatr, // double [][][] scene_xyzatr, // does not include reference
all_scenes_ers_dt, // double [][][] scene_ers_dt, // does not include reference
scenes, // QuadCLT [] scenes,
8); // int iscale) // 8
}
// create initial disparity map for the reference scene
}
public double [][] prepareInitialComboDS(
final CLTParameters clt_parameters,
final QuadCLT [] scenes,
final int indx_ref,
final int debug_level)
{
final QuadCLT ref_scene = scenes[indx_ref];
final int num_scenes = scenes.length;
final double [][][] initial_ds = new double[num_scenes][][];
final ErsCorrection ers_reference = ref_scene.getErsCorrection();
for (int i = 0; i < num_scenes; i++) {
initial_ds[i] = conditionInitialDS(
clt_parameters, // CLTParameters clt_parameters,
scenes[i], // QuadCLT scene,
-1); // int debug_level);
}
if (debug_level > -1) {
String [] dbg_titles = new String [2*num_scenes];
double [][] dbg_img = new double [2*num_scenes][];
for (int i = 0; i < num_scenes; i++) {
dbg_titles[i + 0] = "d-"+scenes[i].getImageName();
dbg_titles[i + num_scenes] = "s-"+scenes[i].getImageName();
dbg_img [i + 0] = initial_ds[i][0];
dbg_img [i + num_scenes] = initial_ds[i][1];
}
(new ShowDoubleFloatArrays()).showArrays(
dbg_img,
ref_scene.getTileProcessor().getTilesX(),
ref_scene.getTileProcessor().getTilesY(),
true,
"all_set_fill_dispatity_gaps"+ref_scene.getImageName(),
dbg_titles); // dsrbg_titles);
}
final int margin = 8;
final double tolerance_ref_absolute = 0.2; // how much scene disparity may diverge from predicted from reference
final double tolerance_ref_relative = 0.02;
final double tolerance_scene_absolute = 0.2; // how much 4 bi-linear interpolation corners may differ (remove extremes while not)
final double tolerance_scene_relative = 0.02;
double [][][] initial_toref_ds = new double[num_scenes][][];
initial_toref_ds[indx_ref] = initial_ds[indx_ref];
// reference camera ERS should be already set
for (int i = 0; i < num_scenes; i++) if (i != indx_ref) {
String ts = scenes[i].getImageName();
double [] scene_xyz = ers_reference.getSceneXYZ(ts);
double [] scene_atr = ers_reference.getSceneATR(ts);
double [] scene_ers_xyz_dt = ers_reference.getSceneErsXYZ_dt(ts);
double [] scene_ers_atr_dt = ers_reference.getSceneErsATR_dt(ts);
initial_toref_ds[i] = getSceneDisparityStrength(
true, // final boolean to_ref_disparity, // false - return scene disparity, true - convert disparity back to the reference scene
initial_ds[indx_ref][0], // final double [] disparity_ref, // invalid tiles - NaN in disparity
initial_ds[i][0], // final double [] disparity_scene, // invalid tiles - NaN in disparity (just for masking out invalid scene tiles)
initial_ds[i][1], // initial_ds[i][1], // final double [] strength_scene, // to calculate interpolated strength
scene_xyz, // final double [] scene_xyz, // camera center in world coordinates
scene_atr, // final double [] scene_atr, // camera orientation relative to world frame
scene_ers_xyz_dt, // final double [] scene_ers_xyz_dt, // camera ERS linear
scene_ers_atr_dt, // final double [] scene_ers_atr_dt, // camera ERS linear
scenes[i], // final QuadCLT scene_QuadClt,
scenes[indx_ref], // final QuadCLT reference_QuadClt,
margin, // final int margin,
tolerance_ref_absolute, // final double tolerance_ref_absolute,
tolerance_ref_relative, // final double tolerance_ref_relative,
tolerance_scene_absolute, // final double tolerance_scene_absolute, // of 4 bi-linear interpolation corners
tolerance_scene_relative); // final double tolerance_scene_relative) // of 4 bi-linear interpolation corners
}
if (debug_level > -1) {
String [] dbg_titles = new String [2*num_scenes];
double [][] dbg_img = new double [2*num_scenes][];
for (int i = 0; i < num_scenes; i++) {
dbg_titles[i + 0] = "d-"+scenes[i].getImageName();
dbg_titles[i + num_scenes] = "s-"+scenes[i].getImageName();
dbg_img [i + 0] = initial_toref_ds[i][0];
dbg_img [i + num_scenes] = initial_toref_ds[i][1];
}
(new ShowDoubleFloatArrays()).showArrays(
dbg_img,
ref_scene.getTileProcessor().getTilesX(),
ref_scene.getTileProcessor().getTilesY(),
true,
"mapped_scenes_disparity_strength"+ref_scene.getImageName(),
dbg_titles); // dsrbg_titles);
}
//ref_scene
final int tilesX = ref_scene.getTileProcessor().getTilesX();
final int tilesY = ref_scene.getTileProcessor().getTilesY();
final int tiles =tilesX * tilesY;
final double zero_strength = 0.05; // add where disparity exists and strength is 0.0
final double [][] combo_dsn = new double[3][tiles];
Arrays.fill(combo_dsn[0], Double.NaN);
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) {
int ndef = 0;
double sw = 0.0, swd = 0.0;
for (int i = 0; i < initial_toref_ds.length; i++) {
double d = initial_toref_ds[i][0][nTile];
double w = initial_toref_ds[i][1][nTile]+zero_strength;
if (!Double.isNaN(d)) {
sw += w;
swd += w * d;
ndef++;
}
if (ndef > 0) {
combo_dsn[0][nTile] = swd/sw;
combo_dsn[1][nTile] = sw/ndef;
combo_dsn[2][nTile] = 1.0*ndef/initial_toref_ds.length;
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return combo_dsn;
}
public double [][] correlateInterscene(
// public double [][][][][] correlateInterscene(
final CLTParameters clt_parameters,
final QuadCLT [] scenes,
final int indx_ref,
final double [] disparity_ref, // disparity in the reference view tiles (Double.NaN - invalid)
final int margin,
final int debug_level
)
{
final int num_scenes = scenes.length;
final QuadCLT ref_scene = scenes[indx_ref];
final ErsCorrection ers_reference = ref_scene.getErsCorrection();
final int tilesX = ref_scene.getTileProcessor().getTilesX();
final int tilesY = ref_scene.getTileProcessor().getTilesY();
final int tiles =tilesX * tilesY;
float [][][][][] fcorrs_td = new float[num_scenes][tilesY][tilesX][][];
float [][][][][] fcorrs_combo_td = new float[num_scenes][4][tilesY][tilesX][];
ImageDtt image_dtt = new ImageDtt(
clt_parameters.transform_size,
ref_scene.isMonochrome(),
ref_scene.isLwir(),
clt_parameters.getScaleStrength(ref_scene.isAux()),
ref_scene.getGpuQuad());
for (int i = 0; i < num_scenes; i++) {
if (i == indx_ref) {
System.out.println("Correlating reference scene");
}
String ts = scenes[i].getImageName();
double [][] scene_pXpYD;
if (i == indx_ref) {
// transform to self - maybe use a method that sets central points
scene_pXpYD = transformToScenePxPyD(
disparity_ref, // final double [] disparity_ref, // invalid tiles - NaN in disparity (maybe it should not be masked by margins?)
ZERO3, // final double [] scene_xyz, // camera center in world coordinates
ZERO3, // final double [] scene_atr, // camera orientation relative to world frame
ref_scene, // final QuadCLT scene_QuadClt,
ref_scene); // final QuadCLT reference_QuadClt)
} else {
double [] scene_xyz = ers_reference.getSceneXYZ(ts);
double [] scene_atr = ers_reference.getSceneATR(ts);
double [] scene_ers_xyz_dt = ers_reference.getSceneErsXYZ_dt(ts);
double [] scene_ers_atr_dt = ers_reference.getSceneErsATR_dt(ts);
scenes[i].getErsCorrection().setErsDt(
scene_ers_xyz_dt, // double [] ers_xyz_dt,
scene_ers_atr_dt); // double [] ers_atr_dt)(ers_scene_original_xyz_dt);
//setupERS() will be inside transformToScenePxPyD()
scene_pXpYD = transformToScenePxPyD( // will be null for disparity == NaN
disparity_ref, // final double [] disparity_ref, // invalid tiles - NaN in disparity (maybe it should not be masked by margins?)
scene_xyz, // final double [] scene_xyz, // camera center in world coordinates
scene_atr, // final double [] scene_atr, // camera orientation relative to world frame
scenes[i], // final QuadCLT scene_QuadClt,
ref_scene); // final QuadCLT reference_QuadClt)
}
if (scenes[i].getGpuQuad().getQuadCLT() != scenes[i]) {
scenes[i].getGpuQuad().updateQuadCLT(scenes[i]); // to re-load new set of Bayer images to the GPU
}
final double disparity_corr = 0.0; // (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction);
final double gpu_sigma_rb_corr = scenes[i].isMonochrome()? 1.0 : clt_parameters.gpu_sigma_rb_corr;
image_dtt.quadCorrTD(
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
scene_pXpYD, // final double [][] pXpYD, // per-tile array of pX,pY,disparity triplets (or nulls)
fcorrs_td[i], // final float [][][][] fcorr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
fcorrs_combo_td[i], // final float [][][][] fcorr_combo_td, // [4][tilesY][tilesX][pair][4*64] TD of combo corrs: qud, cross, hor,vert
scenes[i].getErsCorrection(), // final GeometryCorrection geometryCorrection,
disparity_corr, // final double disparity_corr, // disparity offset at infinity
margin, // final int margin, // do not use tiles if their centers are closer to the edges
clt_parameters.gpu_sigma_r, // 0.9, 1.1
clt_parameters.gpu_sigma_b, // 0.9, 1.1
clt_parameters.gpu_sigma_g, // 0.6, 0.7
clt_parameters.gpu_sigma_m, // = 0.4; // 0.7;
gpu_sigma_rb_corr, // final double gpu_sigma_rb_corr, // = 0.5; // apply LPF after accumulating R and B correlation before G, monochrome ? 1.0 : gpu_sigma_rb_corr;
clt_parameters.gpu_sigma_corr, // = 0.9;gpu_sigma_corr_m
clt_parameters.corr_red, // +used
clt_parameters.corr_blue, // +used
threadsMax, // final int threadsMax, // maximal number of threads to launch
debug_level); // final int globalDebugLevel)
}
// Combine non-null correlations from all scenes (initially combined and individual for visualization and analysis)
final float [][][][] fcorr_td = new float[tilesY][tilesX][][];
final float [][][][] fcorr_combo_td = new float[4][tilesY][tilesX][];
final int first_combo = 0;
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) {
int tileY = nTile / tilesX;
int tileX = nTile % tilesX;
int num_indiv = 0;
int num_combo = 0;
for (int i = 0; i < num_scenes; i++) {
if (fcorrs_td[i][tileY][tileX] != null) {
if (fcorr_td[tileY][tileX] == null) {
fcorr_td[tileY][tileX] = new float [fcorrs_td[i][tileY][tileX].length][];
for (int j = 0; j < fcorr_td[tileY][tileX].length; j++) {
fcorr_td[tileY][tileX][j] = fcorrs_td[i][tileY][tileX][j].clone();
}
} else {
for (int j = 0; j < fcorr_td[tileY][tileX].length; j++) {
for (int k = 0; k < fcorr_td[tileY][tileX][j].length; k++) {
fcorr_td[tileY][tileX][j][k] += fcorrs_td[i][tileY][tileX][j][k];
}
}
}
num_indiv++;
}
if (fcorrs_combo_td[i][first_combo][tileY][tileX] != null) {
if (fcorr_combo_td[first_combo][tileY][tileX] == null) {
for (int p = 0; p < fcorr_combo_td.length; p++) {
if (fcorrs_combo_td[i][p][tileY][tileX]!=null) {
fcorr_combo_td[p][tileY][tileX] = fcorrs_combo_td[i][p][tileY][tileX].clone();
}
}
} else {
for (int p = 0; p < fcorr_combo_td.length; p++) {
for (int k = 0; k < fcorr_combo_td[p][tileY][tileX].length; k++) {
fcorr_combo_td[p][tileY][tileX][k] += fcorrs_combo_td[i][p][tileY][tileX][k];
}
}
}
num_combo++;
}
}
if (num_indiv > 0) {
double s = 1.0/num_indiv;
for (int j = 0; j < fcorr_td[tileY][tileX].length; j++) {
for (int k = 0; k < fcorr_td[tileY][tileX][j].length; k++) {
fcorr_td[tileY][tileX][j][k] *= s;
}
}
}
if (num_combo > 0) {
double s = 1.0/num_combo;
for (int p = 0; p < fcorr_combo_td.length; p++) {
for (int k = 0; k < fcorr_combo_td[p][tileY][tileX].length; k++) {
fcorr_combo_td[p][tileY][tileX][k] *= s;
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
// // TODO: Visualize each correlation - individual and combo
// testing: overwrite with reference frame correlations
if (debug_level < -100) {
for (int i = 0; i < fcorr_combo_td.length; i++) {
fcorr_combo_td[i] = fcorrs_combo_td[indx_ref][i].clone();
}
for (int i = 0; i < fcorr_td.length; i++) {
fcorr_td[i] = fcorrs_td[indx_ref][i].clone();
}
}
for (int i = 0; i < num_scenes; i++) {
fcorrs_td[i] = null;
fcorrs_combo_td[i] = null;
}
if (debug_level > -10){ // -1
final int indx_corr = -1;
final float [][][][] fcorr_td_dbg = (indx_corr < 0) ? fcorr_td : fcorrs_td[indx_corr];
final float [][][][] fcorr_combo_td_dbg = (indx_corr < 0) ? fcorr_combo_td : fcorrs_combo_td[indx_corr];
int [] wh = new int[2];
float [][] dbg_corr = ImageDtt.corr_td_dbg(
fcorr_td_dbg, // final float [][][][] fcorr_td,
// if 0 - fcorr_combo_td = new float[4][tilesY][tilesX][];
// if > 0 - fcorr_td = new float[tilesY][tilesX][num_slices][];
GPUTileProcessor.NUM_PAIRS, // final int num_slices,
image_dtt.transform_size, // final int transform_size,
wh, // final int [] wh, // should be initialized as int[2];
threadsMax); // final int threadsMax) // maximal number of threads to launch
float [][] dbg_corr_combo = ImageDtt.corr_td_dbg(
fcorr_combo_td_dbg, // final float [][][][] fcorr_td,
// if 0 - fcorr_combo_td = new float[4][tilesY][tilesX][];
// if > 0 - fcorr_td = new float[tilesY][tilesX][num_slices][];
0, // final int num_slices,
image_dtt.transform_size, // final int transform_size,
null, // final int [] wh, // should be initialized as int[2];
threadsMax); // final int threadsMax) // maximal number of threads to launch
float [][] dbg_img = new float[dbg_corr.length + dbg_corr_combo.length][];
for (int i = 0; i < dbg_corr.length; i++) {
dbg_img[i] = dbg_corr[i];
}
for (int i = 0; i < dbg_corr_combo.length; i++) {
dbg_img[i + dbg_corr.length] = dbg_corr_combo[i];
}
// titles.length = 15, corr_rslt_partial.length=16!
String [] dbg_titles = new String [dbg_img.length];
System.arraycopy(ImageDtt.CORR_TITLES, 0, dbg_titles, 0, dbg_titles.length);
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
dbg_img,
wh[0],
wh[1],
true,
ref_scene.getImageName()+"-TD-PART_CORR-D"+clt_parameters.disparity,
dbg_titles);
}
Runtime.getRuntime().gc();
System.out.println("--- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
double [][][][][] clt_corr_partial = null;
clt_corr_partial = new double [tilesY][tilesX][][][];
for (int i = 0; i < tilesY; i++){
for (int j = 0; j < tilesX; j++){
clt_corr_partial[i][j] = null;
}
}
double [][] disparity_map = new double [ImageDtt.DISPARITY_TITLES.length][];
int disparity_modes =
ImageDtt.BITS_ALL_DISPARITIES |
ImageDtt.BITS_ALL_DIFFS | // needs max_diff?
ImageDtt.BITS_OVEREXPOSED; // |
image_dtt.clt_process_tl_correlations_GPU( // convert to pixel domain and process correlations already prepared in fcorr_td and/or fcorr_combo_td
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
// both arrays should have same non-null tiles
fcorr_td, // final float [][][][] corr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
fcorr_combo_td, // final float [][][][] corr_combo_td, // [4][tilesY][tilesX][pair][4*64] TD of combo corrs: qud, cross, hor,vert
// each of the top elements may be null to skip particular combo type
null, // final double [][][][] corr_tiles, // [tilesY][tilesX][pair][] ([(2*gpu_corr_rad+1)*(2*gpu_corr_rad+1)]) or null
clt_corr_partial, // final double [][][][][] clt_corr_partial,// [tilesY][tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
// [tilesY][tilesX] should be set by caller
// When clt_mismatch is non-zero, no far objects extraction will be attempted
null, // final double [][] clt_mismatch, // [12][tilesY * tilesX] // ***** transpose unapplied ***** ?. null - do not calculate
// values in the "main" directions have disparity (*_CM) subtracted, in the perpendicular - as is
disparity_map, // final double [][] disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
// last 2 - contrast, avg/ "geometric average)
disparity_modes, // final int disparity_modes, // bit mask of disparity_map slices to calculate/return
clt_parameters.gpu_corr_scale, // gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values
clt_parameters.getGpuFatZero(ref_scene.isMonochrome()), // final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0\
image_dtt.transform_size - 1, // clt_parameters.gpu_corr_rad, // = transform_size - 1 ?
clt_parameters.max_corr_radius, // final double max_corr_radius, // 3.9;
clt_parameters.clt_window, // final int window_type, // GPU: will not be used
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
threadsMax,
debug_level -1 );
/*
(new ShowDoubleFloatArrays()).showArrays(
disparity_map,
tilesX,
tilesY,
true,
"accumulated_disparity_map",
ImageDtt.DISPARITY_TITLES
// ,dbg_titles
);
*/
Runtime.getRuntime().gc();
System.out.println("--- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
if (debug_level < -10){ // -1
double [][] dbg_corr_rslt_partial = ImageDtt.corr_partial_dbg(
clt_corr_partial,
2*image_dtt.transform_size - 1, //final int corr_size,
4, // final int pairs,
4, // final int colors,
clt_parameters.corr_border_contrast,
threadsMax,
debug_level);
// titles.length = 15, corr_rslt_partial.length=16!
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
dbg_corr_rslt_partial,
tilesX*(2*image_dtt.transform_size),
tilesY*(2*image_dtt.transform_size),
true,
ref_scene.getImageName()+"-TD-PART_CORR-D"+clt_parameters.disparity,
ImageDtt.CORR_TITLES);
}
return disparity_map; // disparity_map
// return clt_corr_partial; // disparity_map
}
private double [][] conditionInitialDS(
CLTParameters clt_parameters,
QuadCLT scene,
int debug_level)
{
final int tilesX = scene.getTileProcessor().getTilesX();
final int tilesY = scene.getTileProcessor().getTilesY();
final int transform_size = scene.getTileProcessor().getTileSize();
final int tiles =tilesX * tilesY;
final int num_bottom = 6; // 5; //4; // average this number of lowest disparity neighbors (of 8)
final int num_passes = 100;
final double max_change = 1e-3;
final double min_disparity = -.2; // 0.0;
final double max_sym_disparity = .2;
final double min_strength_replace = 0.14;
final double min_strength_blur = 0.2; // 0.15
final double sigma = 5; // 2.0;
final int num_blur = 1; // 3;
final double disparity_corr = 0.0;
final double outliers_max_strength = 0.25;
final int outliers_nth_fromextrem = 1; // second from min/max - removes dual-tile max/mins
final double outliers_tolerance_absolute = .2;
final double outliers_tolerance_relative = .02;
final int outliers_max_iter = 100;
final double outliers_max_strength2 = 1.0; // 0.5; any
final int outliers_nth_fromextrem2 = 0; // second from min/max - removes dual-tile max/mins
final double outliers_tolerance_absolute2 = .5;
final double outliers_tolerance_relative2 = .1;
final int margin = 8; // pixels
double [][] dsrbg = scene.getDSRBG();
// mostly filter infinity, clouds, sky
double [] disp_outliers = QuadCLT.removeDisparityOutliers(
new double[][] {dsrbg[QuadCLT.DSRBG_DISPARITY], dsrbg[QuadCLT.DSRBG_STRENGTH]}, // double [][] ds0,
outliers_max_strength, // final double max_strength, // do not touch stronger
outliers_nth_fromextrem, // final int nth_fromextrem, // 0 - compare to max/min. 1 - second max/min, ...
outliers_tolerance_absolute, // final double tolerance_absolute,
outliers_tolerance_relative, // final double tolerance_relative,
tilesX, // final int width,
outliers_max_iter, // final int max_iter,
false, // final boolean fit_completely, // do not add tolerance when replacing
threadsMax, // final int threadsMax,
debug_level); // final int debug_level)
// remove extreme single-tile outliers (some may be strong - 0.404)
disp_outliers = QuadCLT.removeDisparityOutliers(
new double[][] {disp_outliers, dsrbg[QuadCLT.DSRBG_STRENGTH]}, // double [][] ds0,
outliers_max_strength2, // final double max_strength, // do not touch stronger
outliers_nth_fromextrem2, // final int nth_fromextrem, // 0 - compare to max/min. 1 - second max/min, ...
outliers_tolerance_absolute2, // final double tolerance_absolute,
outliers_tolerance_relative2, // final double tolerance_relative,
tilesX, // final int width,
outliers_max_iter, // final int max_iter,
false, // final boolean fit_completely, // do not add tolerance when replacing
threadsMax, // final int threadsMax,
debug_level); // final int debug_level)
double [] disp = QuadCLT.blurWeak(
new double[][] {disp_outliers, dsrbg[QuadCLT.DSRBG_STRENGTH]}, // double [][] ds,
min_strength_blur, // double min_strength_blur,
min_strength_replace, // double min_strength_replace,
num_blur, // int n,
tilesX, // int width,
sigma); // double sigma);
double [][] ds = {disp, dsrbg[QuadCLT.DSRBG_STRENGTH]};
final double [][] ds_filled = QuadCLT.fillDisparityStrength(
ds, // final double [][] ds0,
min_disparity, // final double min_disparity,
max_sym_disparity, // final double max_sym_disparity, // lower disparity - num_bottom = 8;
num_bottom, // final int num_bottom, // average this number of lowest disparity neighbors (of 8)
num_passes, // final int num_passes,
max_change, // final double max_change,
tilesX, // final int width,
threadsMax, // final int threadsMax,
debug_level); // final int debug_level)
// Mask bad tiles
final boolean [] valid_tiles = new boolean [tiles];
final double [][] pXpYD = new double [tiles][3];
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
// final AtomicInteger anum_gaps = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) {
int tileY = nTile / tilesX;
int tileX = nTile % tilesX;
pXpYD[nTile][0] = tileX * transform_size + transform_size/2;
pXpYD[nTile][1] = tileY * transform_size + transform_size/2;
pXpYD[nTile][2] = ds_filled[0][nTile];
}
}
};
}
ImageDtt.startAndJoin(threads);
scene.getGpuQuad().setInterTasks(
pXpYD, // final double [][] pXpYD, // per-tile array of pX,pY,disparity triplets (or nulls)
scene.getGeometryCorrection(), // final GeometryCorrection geometryCorrection,
disparity_corr, // final double disparity_corr,
margin, // final int margin, // do not use tiles if their centers are closer to the edges
valid_tiles, // final boolean [] valid_tiles,
threadsMax); // final int threadsMax) // maximal number of threads to launch
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) {
if (!valid_tiles[nTile]) {
ds_filled[0][nTile] = Double.NaN;
ds_filled[1][nTile] = 0.0;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if ((debug_level > 0) && (clt_parameters.ofp.enable_debug_images)) {
String [] dbg_titles = {"disp", "disp_outliers", "disp_blur", "disp_filled", "str", "str_filled"};
double [][] dbg_img = {dsrbg[QuadCLT.DSRBG_DISPARITY], disp_outliers, ds[0], ds_filled[0], ds[1], ds_filled[1]};
(new ShowDoubleFloatArrays()).showArrays(
dbg_img,
tilesX,
tilesY,
true,
"ref_fill_dispatity_gaps-"+scene.getImageName(),
dbg_titles); // dsrbg_titles);
}
return ds_filled;
}
double [][] getPoseFromErs(
double k_prev,
QuadCLT reference_QuadCLT,
......
......@@ -35,7 +35,10 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.DoubleAccumulator;
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.cameras.ColorProcParameters;
......@@ -71,6 +74,9 @@ public class QuadCLT extends QuadCLTCPU {
}
}
public GPUTileProcessor.GpuQuad getGpuQuad(){
return this.gpuQuad;
}
public QuadCLT restoreFromModel(
CLTParameters clt_parameters,
ColorProcParameters colorProcParameters, //
......@@ -99,7 +105,8 @@ public class QuadCLT extends QuadCLTCPU {
int [] channelFiles = set_channels[0].fileNumber();
boolean [][] saturation_imp = (clt_parameters.sat_level > 0.0)? new boolean[channelFiles.length][] : null;
double [] scaleExposures = new double[channelFiles.length];
ImagePlus [] imp_srcs = conditionImageSet(
// ImagePlus [] imp_srcs =
conditionImageSet(
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
colorProcParameters, // ColorProcParameters colorProcParameters, //
sourceFiles, // String [] sourceFiles,
......@@ -119,6 +126,206 @@ public class QuadCLT extends QuadCLTCPU {
return this; // can only be QuadCLT instance
}
public static double [] removeDisparityOutliers(
final double [][] ds0,
final double max_strength, // do not touch stronger
final int nth_fromextrem, // 0 - compare to max/min. 1 - second max/min, ...
final double tolerance_absolute,
final double tolerance_relative,
final int width,
final int max_iter,
final boolean fit_completely, // do not add tolerance when replacing
final int threadsMax,
final int debug_level)
{
final int tiles = ds0[0].length;
final double [] disparity = ds0[0].clone();
final double [] disparity_out = ds0[0].clone();
final double [] strength = ds0[1]; // will not be updated
final TileNeibs tn = new TileNeibs(width, tiles/width);
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger anum_updated = new AtomicInteger(0);
final int dbg_tile = 8309;
for (int iter = 0; iter < max_iter; iter++) {
ai.set(0);
anum_updated.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [] neibs = new double[8];
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) {
if ((debug_level >0) && (nTile == dbg_tile)) {
System.out.println("removeDisparityOutliers() nTile="+nTile);
}
if ((strength[nTile] < max_strength) && !Double.isNaN(disparity[nTile])) {
Arrays.fill(neibs, Double.NaN);
for (int dir = 0; dir < 8; dir++) {
int ineib = tn.getNeibIndex(nTile, dir);
if (ineib >= 0) {
neibs[dir] = disparity[ineib];
}
}
Arrays.sort(neibs);
int num_defined = neibs.length;
for (int i = 0; i < neibs.length; i++) {
if (Double.isNaN(neibs[i])) {
num_defined = i;
break;
}
}
if (num_defined > 0) {
int nth_min = nth_fromextrem;
if (nth_min >= num_defined) {
nth_min = num_defined - 1;
}
int nth_max = num_defined - 1 - nth_min;
double d_min = neibs[nth_min] - tolerance_absolute - neibs[nth_min]*tolerance_relative;
double d_max = neibs[nth_max] + tolerance_absolute + neibs[nth_max]*tolerance_relative;
if (disparity[nTile] < d_min) {
disparity_out[nTile] = fit_completely? neibs[nth_min]: d_min;
} else if (disparity[nTile] > d_max) {
disparity_out[nTile] = fit_completely? neibs[nth_max]: d_max;
}
if (disparity_out[nTile] != disparity[nTile]) {
anum_updated.getAndIncrement();
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (anum_updated.get() ==0) {
break;
}
System.arraycopy(disparity_out,0,disparity,0,tiles);
}
return disparity_out;
}
public static double [][] fillDisparityStrength(
final double [][] ds0,
final double min_disparity,
final double max_sym_disparity, // lower disparity - num_bottom = 8;
final int num_bottom, // average this number of lowest disparity neighbors (of 8)
final int num_passes,
final double max_change,
final int width,
final int threadsMax,
final int debug_level)
{
final double diagonal_weight = 0.5 * Math.sqrt(2.0); // relative to ortho
double wdiag = 0.25 *diagonal_weight / (diagonal_weight + 1.0);
double wortho = 0.25 / (diagonal_weight + 1.0);
final double [] neibw = {wortho, wdiag, wortho, wdiag, wortho, wdiag, wortho, wdiag};
final double max_change2 = max_change * max_change;
final int min_defined = 3; // do not try to fill if less than this (>=4 - will never fill expand outwards)
final double [][] ds = new double [][] {ds0[0].clone(),ds0[1].clone()};
final int tiles = ds[0].length;
final TileNeibs tn = new TileNeibs(width, tiles/width);
final int [] tile_indices = new int [tiles];
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger anum_gaps = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < tiles; nTile = ai.getAndIncrement()) {
if (ds[0][nTile] < min_disparity) {
ds[0][nTile] = min_disparity;
}
if (Double.isNaN(ds[0][nTile]) || (ds[1][nTile] <= 0)) {
ds[0][nTile] = Double.NaN;
ds[1][nTile] = 0.0;
int indx = anum_gaps.getAndIncrement();
tile_indices[indx] = nTile;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
final int num_gaps = anum_gaps.get();
if (num_gaps == 0) {
return ds; // no gaps already
}
final boolean [] fill_all = {false};
final double [] disp_new = ds[0].clone();
DoubleAccumulator amax_diff = new DoubleAccumulator (Double::max, Double.NEGATIVE_INFINITY);
for (int npass = 0; npass < num_passes; npass+= fill_all[0]? 1:0 ) { // do not limit initial passes
anum_gaps.set(0);
amax_diff.reset();
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [] neibs = new double[8];
double [] neibs_sorted = new double[8];
for (int indx = ai.getAndIncrement(); indx < num_gaps; indx = ai.getAndIncrement()) {
int nTile = tile_indices[indx];
if (!fill_all[0] && !Double.isNaN(ds[0][nTile])) {
continue; // fill only new
}
Arrays.fill(neibs, Double.NaN);
for (int dir = 0; dir < 8; dir++) {
int nt_neib = tn.getNeibIndex(nTile, dir);
if (nt_neib >= 0) {
neibs[dir] = ds[0][nt_neib];
}
}
System.arraycopy(neibs, 0, neibs_sorted, 0, 8);
Arrays.sort(neibs_sorted); // NaNs in the end
if (Double.isNaN(neibs_sorted[min_defined - 1])) {
continue; // too few defined neighbors
}
if (!fill_all[0]) {
anum_gaps.getAndIncrement();
}
double max_disp = neibs_sorted[num_bottom - 1];
if (!(ds[0][nTile] > max_sym_disparity)){
max_disp = Double.NaN;
}
double swd = 0.0, sw = 0.0;
for (int dir = 0; dir < 8; dir++) {
if (!Double.isNaN(neibs[dir]) && !(neibs[dir] > max_disp)) { // handles NaNs
sw += neibw[dir];
swd += neibw[dir] * neibs[dir];
}
}
swd /= sw; // should never be 0.0
//max_change
if (fill_all[0]) {
double d2 = max_change2 * 2;
if (!Double.isNaN(disp_new[nTile])){
double d = swd - disp_new[nTile];
d2 = d * d;
}
amax_diff.accumulate(d2);
}
disp_new[nTile] = swd;
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
System.arraycopy(disp_new, 0, ds[0], 0, tiles);
if ((debug_level > 0) && fill_all[0]) {
System.out.println("fillDisparityStrength() npass="+npass+", change="+Math.sqrt(amax_diff.get())+" ("+max_change+")");
}
if (fill_all[0] && (amax_diff.get() < max_change2)) {
break;
}
fill_all[0] = anum_gaps.get() == 0; // no new tiles filled
} // for (int npass = 0; npass < num_passes; npass+= fill_all[0]? 1:0 )
return ds;
}
public double [][] getDSRBG (){
return dsrbg;
......@@ -283,6 +490,40 @@ public class QuadCLT extends QuadCLTCPU {
return null;
}
public static double[] blurWeak(
double [][] ds,
double min_strength_blur,
double min_strength_replace,
int n,
int width,
double sigma) {
double [] disparity = new double[ds[0].length];
Arrays.fill(disparity, Double.NaN);
for (int i = 0; i < disparity.length; i++) {
if (Double.isNaN(ds[0][i]) || (ds[1][i] < min_strength_blur)) {
disparity[i] = ds[0][i];
}
}
for (int i = 0; i < n; i++) {
disparity = (new DoubleGaussianBlur()).blurWithNaN(
disparity, // double[] pixels,
null, // double [] in_weight, // or null
width, // int width,
disparity.length/width, // int height,
sigma, // double sigmaX,
sigma, // double sigmaY,
0.00001); // double accuracy);
}
for (int i = 0; i < disparity.length; i++) {
if (ds[1][i] > min_strength_replace) {
disparity[i] = ds[0][i];
}
}
return disparity;
}
@Deprecated
public double[] fillNaNGapsOld(
double [] data,
......
......@@ -1935,7 +1935,7 @@ public class QuadCLTCPU {
// int srcChannel=correctionsParameters.getChannelFromSourceTiff(sourceFiles[nFile]);
int srcChannel=fileIndices[iImage][1];
imp_src = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops);
imp_src = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops, this.geometryCorrection.camera_heights);
double scaleExposure=1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_src.getProperty("EXPOSURE")!=null)){
......@@ -2509,7 +2509,7 @@ public class QuadCLTCPU {
int nFile=channelFiles[srcChannel];
imp_srcs[srcChannel]=null;
if (nFile >=0){
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops);
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops, this.geometryCorrection.camera_heights);
scaleExposure[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
......@@ -3117,7 +3117,7 @@ public class QuadCLTCPU {
int nFile=channelFiles[srcChannel];
imp_srcs[srcChannel]=null;
if (nFile >=0){
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops);
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops, this.geometryCorrection.camera_heights);
scaleExposures[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
......@@ -3730,6 +3730,8 @@ public class QuadCLTCPU {
this.image_name = set_name;
ImagePlus [] imp_srcs = new ImagePlus[channelFiles.length];
this.geometryCorrection.woi_tops = new int [channelFiles.length];
this.geometryCorrection.camera_heights = new int [channelFiles.length];
double [][] dbg_dpixels = new double [channelFiles.length][];
boolean is_lwir = colorProcParameters.lwir_islwir;
boolean ignore_saturation = is_lwir;
......@@ -3742,7 +3744,7 @@ public class QuadCLTCPU {
int nFile=channelFiles[srcChannel]; // channelFiles[srcChannel];
imp_srcs[srcChannel]=null;
if (nFile >=0){
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops);
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops, this.geometryCorrection.camera_heights);
scaleExposures[srcChannel] = 1.0;
if (!(referenceExposures == null) && !Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
......@@ -6425,13 +6427,14 @@ public class QuadCLTCPU {
ImagePlus [] imp_srcs = new ImagePlus[channelFiles.length];
this.geometryCorrection.woi_tops = new int [channelFiles.length];
this.geometryCorrection.camera_heights = new int [channelFiles.length];
boolean [][] saturation_imp = (clt_parameters.sat_level > 0.0)? new boolean[channelFiles.length][] : null;
double [] scaleExposures = new double[channelFiles.length];
for (int srcChannel=0; srcChannel<channelFiles.length; srcChannel++){
int nFile=channelFiles[srcChannel];
imp_srcs[srcChannel]=null;
if (nFile >=0){
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops);
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops, this.geometryCorrection.camera_heights);
scaleExposures[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
......@@ -11583,13 +11586,15 @@ public class QuadCLTCPU {
ImagePlus [] imp_srcs = new ImagePlus[channelFiles.length];
this.geometryCorrection.woi_tops = new int [channelFiles.length];
this.geometryCorrection.camera_heights = new int [channelFiles.length];
double [][] dbg_dpixels = batch_mode? null : (new double [channelFiles.length][]);
for (int srcChannel=0; srcChannel<channelFiles.length; srcChannel++){
int nFile=channelFiles[srcChannel];
imp_srcs[srcChannel]=null;
if (nFile >=0){
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops);
imp_srcs[srcChannel] = eyesisCorrections.getJp4Tiff(sourceFiles[nFile], this.geometryCorrection.woi_tops, this.geometryCorrection.camera_heights);
scaleExposures[srcChannel] = 1.0;
if (!Double.isNaN(referenceExposures[nFile]) && (imp_srcs[srcChannel].getProperty("EXPOSURE")!=null)){
......
......@@ -38,6 +38,7 @@ import java.nio.channels.WritableByteChannel;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Properties;
import java.util.Random;
......@@ -8523,17 +8524,12 @@ if (debugLevel > -100) return true; // temporarily !
threadsMax,
debugLevel);
// temporarily fix wrong sign:
ErsCorrection ers = (ErsCorrection) (quadCLTs[i].getGeometryCorrection());
// if (reset_from_extrinsics) {
// System.out.println("Reset ERS parameters from intraframe extrinsics");
// ers.setupERSfromExtrinsics();
// }
// ErsCorrection ers = (ErsCorrection) (quadCLTs[i].getGeometryCorrection());
quadCLTs[i].setDSRBG(
clt_parameters, // CLTParameters clt_parameters,
threadsMax, // int threadsMax, // maximal number of threads to launch
updateStatus, // boolean updateStatus,
debugLevel); // int debugLevel)
/// quadCLTs[i].showDSIMain();
}
......@@ -8547,7 +8543,60 @@ if (debugLevel > -100) return true; // temporarily !
quadCLTs, // QuadCLT [] scenes, // ordered by increasing timestamps
clt_parameters.ofp.debug_level_optical); // 1); // -1); // int debug_level);
System.out.println("End of interSeriesLMA()");
}
public void intersceneAccumulate(
QuadCLT quadCLT_main, // tiles should be set
CLTParameters clt_parameters,
EyesisCorrectionParameters.DebayerParameters debayerParameters,
ColorProcParameters colorProcParameters,
CorrectionColorProc.ColorGainsParameters channelGainParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
EyesisCorrectionParameters.EquirectangularParameters equirectangularParameters,
Properties properties,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel) throws Exception
{
if ((quadCLT_main != null) && (quadCLT_main.getGPU() != null)) {
quadCLT_main.getGPU().resetGeometryCorrection();
quadCLT_main.gpuResetCorrVector(); // .getGPU().resetGeometryCorrectionVector();
}
// final boolean batch_mode = clt_parameters.batch_run;
this.startTime=System.nanoTime();
String [] sourceFiles0=quadCLT_main.correctionsParameters.getSourcePaths();
QuadCLT.SetChannels [] set_channels_main = quadCLT_main.setChannels(debugLevel);
if ((set_channels_main == null) || (set_channels_main.length==0)) {
System.out.println("No files to process (of "+sourceFiles0.length+")");
return;
}
QuadCLT.SetChannels [] set_channels=quadCLT_main.setChannels(debugLevel); // TODO: use just the last one (to need this is no time)
QuadCLT ref_quadCLT = quadCLT_main.spawnQuadCLT(
set_channels[set_channels.length-1].set_name,
clt_parameters,
colorProcParameters, //
threadsMax,
debugLevel);
// temporarily fix wrong sign:
// ErsCorrection ers = (ErsCorrection) (ref_quadCLT.getGeometryCorrection());
ref_quadCLT.setDSRBG( // runs GPU to calculate average R,B,G
clt_parameters, // CLTParameters clt_parameters,
threadsMax, // int threadsMax, // maximal number of threads to launch
updateStatus, // boolean updateStatus,
debugLevel); // int debugLevel)
OpticalFlow opticalFlow = new OpticalFlow(
threadsMax, // int threadsMax, // maximal number of threads to launch
updateStatus); // boolean updateStatus);
opticalFlow.IntersceneAccumulate(
clt_parameters, // CLTParameters clt_parameters,
colorProcParameters, // ColorProcParameters colorProcParameters,
ref_quadCLT, // QuadCLT [] scenes, // ordered by increasing timestamps
clt_parameters.ofp.debug_level_optical); // 1); // -1); // int debug_level);
System.out.println("End of intersceneAccumulate()");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment