Commit 901f0a49 authored by Andrey Filippov's avatar Andrey Filippov

Debugging field calibration with GPU

parent dd8f74c3
......@@ -167,7 +167,7 @@ public class CLTParameters {
public boolean inf_restore_disp = true; // Add disparity back to d{x,y}[i] (debug feature)
// Lazy eye parameters
public boolean ly_lma_ers = true; // Use 2020 LMA-based measurement of mismatch
public boolean ly_lma_ers = true; // Use 2020 LMA-based measurement of mismatch (GPU-supported)
public double ly_gt_strength = 0.18; // use some configurable parameters
public boolean ly_gt_use_wnd = true; //
public double ly_gt_rms = 0.2; // split small source samples to FG/BG if all aux tile RMS exceeds this value
......@@ -797,6 +797,7 @@ public class CLTParameters {
public boolean gpu_use_aux = false; // accelerate tile processor for the aux (lwir) quad camera
public boolean gpu_use_aux_macro = false; // accelerate tile processor for the aux (lwir) quad camera in macro mode
public boolean gpu_use_aux_adjust = false; // accelerate tile processor for the aux (lwir) quad camera for field calibration
public boolean gpu_debug_accum = false; // debug multi-tile TD accumulation
public boolean replaceWeakOutliers = true; // false;
......@@ -1600,6 +1601,7 @@ public class CLTParameters {
properties.setProperty(prefix+"gpu_use_aux", this.gpu_use_aux +"");
properties.setProperty(prefix+"gpu_use_aux_macro", this.gpu_use_aux_macro +"");
properties.setProperty(prefix+"gpu_use_aux_adjust", this.gpu_use_aux_adjust +"");
properties.setProperty(prefix+"gpu_debug_accum", this.gpu_debug_accum +"");
properties.setProperty(prefix+"debug_initial_discriminate", this.debug_initial_discriminate+"");
properties.setProperty(prefix+"dbg_migrate", this.dbg_migrate+"");
......@@ -2387,6 +2389,7 @@ public class CLTParameters {
if (properties.getProperty(prefix+"gpu_use_aux")!=null) this.gpu_use_aux=Boolean.parseBoolean(properties.getProperty(prefix+"gpu_use_aux"));
if (properties.getProperty(prefix+"gpu_use_aux_macro")!=null) this.gpu_use_aux_macro=Boolean.parseBoolean(properties.getProperty(prefix+"gpu_use_aux_macro"));
if (properties.getProperty(prefix+"gpu_use_aux_adjust")!=null) this.gpu_use_aux_adjust=Boolean.parseBoolean(properties.getProperty(prefix+"gpu_use_aux_adjust"));
if (properties.getProperty(prefix+"gpu_debug_accum")!=null) this.gpu_debug_accum=Boolean.parseBoolean(properties.getProperty(prefix+"gpu_debug_accum"));
if (properties.getProperty(prefix+"debug_initial_discriminate")!=null) this.debug_initial_discriminate=Boolean.parseBoolean(properties.getProperty(prefix+"debug_initial_discriminate"));
if (properties.getProperty(prefix+"dbg_migrate")!=null) this.dbg_migrate=Boolean.parseBoolean(properties.getProperty(prefix+"dbg_migrate"));
......@@ -2612,7 +2615,7 @@ public class CLTParameters {
gd.addTab ("Lazy eye", "Lazy eye parameters");
gd.addCheckbox ("Use 2020 LMA-based measurement of mismatch", this.ly_lma_ers);
gd.addCheckbox ("Use 2020 LMA-based measurement of mismatch (GPU-supported)", this.ly_lma_ers);
gd.addMessage ("--- main-to-aux depth map parameters ---");
gd.addNumericField("Minimal reference (main) channel correlation strength", this.ly_gt_strength, 3);
gd.addCheckbox ("Use window for AUX tiles to reduce weight of the hi-res tiles near low-res tile boundaries", this.ly_gt_use_wnd);
......@@ -3337,6 +3340,7 @@ public class CLTParameters {
gd.addCheckbox ("Accelerate tile processor for the aux (lwir) quad camera", this.gpu_use_aux);
gd.addCheckbox ("Accelerate tile processor for the aux (lwir) quad camera in macro mode", this.gpu_use_aux_macro);
gd.addCheckbox ("Accelerate tile processor for the aux (lwir) quad camera for field calibration", this.gpu_use_aux_adjust);
gd.addCheckbox ("Debug multi-tile TD accumulation", this.gpu_debug_accum);
gd.addTab ("LWIR", "parameters for LWIR/EO 8-camera rig");
this.lwir.dialogQuestions(gd);
......@@ -4097,6 +4101,7 @@ public class CLTParameters {
this.gpu_use_aux= gd.getNextBoolean();
this.gpu_use_aux_macro= gd.getNextBoolean();
this.gpu_use_aux_adjust= gd.getNextBoolean();
this.gpu_debug_accum= gd.getNextBoolean();
this.lwir.dialogAnswers(gd);
......
......@@ -222,6 +222,18 @@ public class GPUTileProcessor {
}
}
}
public float [][] getDispDist(){
return disp_dist;
}
public float [][] getXY(boolean use_aux){
return use_aux? xy_aux : xy;
}
public int getTileY(){
return ty;
}
public int getTileX(){
return tx;
}
// convert this class instance to float array to match layout of the C struct
public float [] asFloatArray(boolean use_aux) {
......@@ -2043,10 +2055,13 @@ public class GPUTileProcessor {
}
}
setCorrIndicesTdData(
ntile, // int num_tiles, // corr_indices, fdata may be longer than needed
ntile * num_pairs, // int num_tiles, // corr_indices, fdata may be longer than needed
indices, // int [] corr_indices,
fdata); // float [] fdata);
return indices;
// trim indices
int [] indices_trim = new int [ntile * num_pairs];
System.arraycopy(indices, 0, indices_trim, 0 , indices_trim.length);
return indices_trim;
}
public float [][][][] getCorrTilesTd() // [tileY][tileX][pair][4*64] , read all available pairs
......@@ -2104,7 +2119,9 @@ public class GPUTileProcessor {
ntile, // int num_tiles, // corr_indices, fdata may be longer than needed
indices, // int [] corr_indices,
fdata); // float [] fdata);
return indices;
int [] indices_trim = new int [ntile];
System.arraycopy(indices, 0, indices_trim, 0 , indices_trim.length);
return indices_trim;
}
public float [][][] getCorrTilesComboTd() // [tileY][tileX][4*64] , read all available pairs
......
......@@ -53,6 +53,8 @@ public class ImageDtt extends ImageDttCPU {
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
// 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}
final double [][][][] clt_corr_combo, // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
// [type][tilesY][tilesX] should be set by caller
// types: 0 - selected correlation (product+offset), 1 - sum
......@@ -301,6 +303,30 @@ public class ImageDtt extends ImageDttCPU {
imgdtt_params.gpu_verify); // boolean verify
gpuQuad.execSetTilesOffsets(); // prepare tiles offsets in GPU memory
if ((fdisp_dist != null) || (fpxpy != null)) {
final GPUTileProcessor.TpTask[] tp_tasks_full = gpuQuad.getTasks(use_main);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int indx_tile = ai.getAndIncrement(); indx_tile < tp_tasks_full.length; indx_tile = ai.getAndIncrement()) {
GPUTileProcessor.TpTask task = tp_tasks_full[indx_tile];
if (fdisp_dist != null) {
fdisp_dist[task.getTileY()][task.getTileX()] = task.getDispDist();
}
if (fpxpy != null) {
fpxpy[task.getTileY()][task.getTileX()] = task.getXY(use_main); // boolean use_aux);
}
} // end of tile
}
};
}
startAndJoin(threads);
ai.set(0);
}
gpuQuad.execConvertDirect();
if (iclt_fimg != null) {
gpuQuad.execImcltRbgAll(isMonochrome()); // execute GPU kernel
......@@ -418,7 +444,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_td[0]); // generate time domain correlation pairs for quad ortho combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[0]); // generate time domain correlation pairs for quad ortho combination
}
// normalize and convert to pixel domain
gpuQuad.execCorr2D_normalize(
......@@ -434,7 +460,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_td[1]); // generate time domain correlation pairs for cross diagonal combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[1]); // generate time domain correlation pairs for cross diagonal combination
}
gpuQuad.execCorr2D_normalize(
true, // boolean combo, // normalize combo correlations (false - per-pair ones)
......@@ -448,7 +474,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_td[2]); // generate time domain correlation pairs for horizontal combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[2]); // generate time domain correlation pairs for horizontal combination
}
gpuQuad.execCorr2D_normalize(
true, // boolean combo, // normalize combo correlations (false - per-pair ones)
......@@ -461,7 +487,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_td[3]); // generate time domain correlation pairs for vertical combination
gpuQuad.getCorrTilesComboTd(fcorr_combo_td[3]); // generate time domain correlation pairs for vertical combination
}
gpuQuad.execCorr2D_normalize(
true, // boolean combo, // normalize combo correlations (false - per-pair ones)
......@@ -472,7 +498,7 @@ public class ImageDtt extends ImageDttCPU {
if (corr_indices.length > 0) {
/*
/*
if (true) { // debugging only
int [] wh = new int[2];
double [][] dbg_corr = GPUTileProcessor.getCorr2DView(
......@@ -486,11 +512,10 @@ public class ImageDtt extends ImageDttCPU {
wh[0],
wh[1],
true,
"dbg-corr2D", // name+"-CORR2D-D"+clt_parameters.disparity,
"dbg-corr2D-initial", // name+"-CORR2D-D"+clt_parameters.disparity,
GPUTileProcessor.getCorrTitles());
}
*/
final int corr_length = fcorr2D[0].length;// all correlation tiles have the same size
// assuming that the correlation pairs sets are the same for each tile that has correlations
// find this number
......@@ -597,7 +622,7 @@ public class ImageDtt extends ImageDttCPU {
else if (corr_mode == 4) extra_disparity = disparity_map[DISPARITY_INDEX_VERT][tIndex]; // not used in lwir
if (Double.isNaN(extra_disparity)) extra_disparity = 0; // used in lwir
*/
if (Double.isNaN(disparity_map[DISPARITY_STRENGTH_INDEX][tIndex])) {
if ((disparity_map != null) && Double.isNaN(disparity_map[DISPARITY_STRENGTH_INDEX][tIndex])) {
System.out.println("BUG: 3. disparity_map[DISPARITY_STRENGTH_INDEX][tIndex] should not be NaN");
}
......@@ -635,8 +660,9 @@ public class ImageDtt extends ImageDttCPU {
final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
// both arrays should have same non-null tiles
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 double [][][][] corr_tiles, // [tilesY][tilesX][pair][] ([(2*gpu_corr_rad+1)*(2*gpu_corr_rad+1)]) or null
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
......@@ -644,6 +670,7 @@ public class ImageDtt extends ImageDttCPU {
// values in the "main" directions have disparity (*_CM) subtracted, in the perpendicular - as is
final double [][] disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
// last 2 - contrast, avg/ "geometric average)
final int disparity_modes, // bit mask of disparity_map slices to calculate/return
final double gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values
final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0
final int gpu_corr_rad, // = transform_size - 1 ?
......@@ -747,6 +774,15 @@ public class ImageDtt extends ImageDttCPU {
// add optional initialization of debug layers here
// boolean need_macro = false;
// boolean need_corr = true;
// skipping DISPARITY_VARIATIONS_INDEX - it was not used
if (disparity_map != null){
for (int i = 0; i<disparity_map.length;i++) if ((disparity_modes & (1 << i)) != 0){
if ((i == OVEREXPOSED) && (saturation_imp == null)) {
continue;
}
disparity_map[i] = new double [tilesY*tilesX];
}
}
if (clt_mismatch != null){
for (int i = 0; i<clt_mismatch.length;i++){
......@@ -766,7 +802,7 @@ public class ImageDtt extends ImageDttCPU {
float [][] fcorr2D_ = null;
if (fcorr_td != null) {
int [][] pairs_map = {{0,0},{1,1},{2,2},{3,3},{4,4},{5,5}};
corr_indices_ = gpuQuad.setCorrTilesTd(
corr_indices_ = gpuQuad.setCorrTilesTd( // .length = 295866 should set num_corr_tiles!
fcorr_td, // final float [][][][] corr_tiles, // [tileY][tileX][pair][4*64]
pairs_map); // int [][] pairs) // typically {{0,0},{1,1},{2,2},{3,3},{4,4},{5,5} [0] - 3rd index in corr_tiles, [1] -
gpuQuad.execCorr2D_normalize(
......@@ -776,7 +812,7 @@ public class ImageDtt extends ImageDttCPU {
fcorr2D_ = gpuQuad.getCorr2D(gpu_corr_rad); // int corr_rad);
}
final int [] corr_indices = corr_indices_;
final float [][] fcorr2D = fcorr2D_;
final float [][] fcorr2D = fcorr2D_; // len = 49311
final int num_combo= (fcorr_combo_td != null)? fcorr_combo_td.length : 0;
final int [][] corr_combo_indices = (fcorr_combo_td != null)? new int [num_combo][] : null;
......@@ -798,24 +834,23 @@ public class ImageDtt extends ImageDttCPU {
final boolean fneed_macro = false;
if (corr_indices.length > 0) {
/*
if (true) { // debugging only
int [] wh = new int[2];
double [][] dbg_corr = GPUTileProcessor.getCorr2DView(
tilesX,
tilesY,
corr_indices,
fcorr2D,
wh);
(new ShowDoubleFloatArrays()).showArrays(
dbg_corr,
wh[0],
wh[1],
true,
"dbg-corr2D", // name+"-CORR2D-D"+clt_parameters.disparity,
GPUTileProcessor.getCorrTitles());
}
if (true) { // debugging only
int [] wh = new int[2];
double [][] dbg_corr = GPUTileProcessor.getCorr2DView(
tilesX,
tilesY,
corr_indices,
fcorr2D,
wh);
(new ShowDoubleFloatArrays()).showArrays(
dbg_corr,
wh[0],
wh[1],
true,
"dbg-corr2D-fromTD", // name+"-CORR2D-D"+clt_parameters.disparity,
GPUTileProcessor.getCorrTitles());
}
*/
final int corr_length = fcorr2D[0].length;// all correlation tiles have the same size
// assuming that the correlation pairs sets are the same for each tile that has correlations
// find this number
......@@ -847,7 +882,7 @@ public class ImageDtt extends ImageDttCPU {
for (int indx_tile = ai.getAndIncrement(); indx_tile < num_tiles; indx_tile = ai.getAndIncrement()) {
// double [][] corrs = new double [GPUTileProcessor.NUM_PAIRS][corr_length]; // 225-long (15x15)
// added quad and cross combos
double [][] corrs = new double [GPUTileProcessor.NUM_PAIRS + 4][corr_length]; // 225-long (15x15)
double [][] corrs = new double [GPUTileProcessor.NUM_PAIRS + num_combo][corr_length]; // 225-long (15x15)
int indx_corr = indx_tile * num_tile_corr;
int nt = (corr_indices[indx_corr] >> GPUTileProcessor.CORR_NTILE_SHIFT);
int tileX = nt % tilesX;
......@@ -877,27 +912,30 @@ public class ImageDtt extends ImageDttCPU {
}
}
}
int used_pairs = pair_mask; // imgdtt_params.dbg_pair_mask; //TODO: use tile tasks
int tile_lma_debug_level = ((tileX == debug_tileX) && (tileY == debug_tileY))? (imgdtt_params.lma_debug_level-1) : -2;
boolean debugTile =(tileX == debug_tileX) && (tileY == debug_tileY) && (globalDebugLevel > -1);
corr_common_GPU(
imgdtt_params, // final ImageDttParameters imgdtt_params,
clt_corr_partial, // final double [][][][][] clt_corr_partial,
used_pairs, // final int used_pairs,
disparity_map, // final double [][] disparity_map,
clt_mismatch, // final double [][] clt_mismatch,
saturation_imp, // final boolean [][] saturation_imp,
fneed_macro, // final boolean fneed_macro,
corr2d, // final Correlation2d corr2d,
corrs, // final double [][] corrs,
tileX, // final int tileX,
tileY, // final int tileY,
max_corr_radius, // final double max_corr_radius, // 3.9;
tile_lma_debug_level, // int tile_lma_debug_level,
debugTile, // boolean debugTile,
globalDebugLevel); // final int globalDebugLevel)
if (corr_tiles != null) {
corr_tiles[tileY][tileX] = corrs;
}
if ((disparity_map != null) || (clt_corr_partial != null) || (clt_mismatch != null)) {
int used_pairs = pair_mask; // imgdtt_params.dbg_pair_mask; //TODO: use tile tasks
int tile_lma_debug_level = ((tileX == debug_tileX) && (tileY == debug_tileY))? (imgdtt_params.lma_debug_level-1) : -2;
boolean debugTile =(tileX == debug_tileX) && (tileY == debug_tileY) && (globalDebugLevel > -1);
corr_common_GPU(
imgdtt_params, // final ImageDttParameters imgdtt_params,
clt_corr_partial, // final double [][][][][] clt_corr_partial,
used_pairs, // final int used_pairs,
disparity_map, // final double [][] disparity_map,
clt_mismatch, // final double [][] clt_mismatch,
saturation_imp, // final boolean [][] saturation_imp,
fneed_macro, // final boolean fneed_macro,
corr2d, // final Correlation2d corr2d,
corrs, // final double [][] corrs,
tileX, // final int tileX,
tileY, // final int tileY,
max_corr_radius, // final double max_corr_radius, // 3.9;
tile_lma_debug_level, // int tile_lma_debug_level,
debugTile, // boolean debugTile,
globalDebugLevel); // final int globalDebugLevel)
}
// double extra_disparity = 0.0; // used for textures: if allowed, shift images extra before trying to combine
/*
// Disabled for GPU
......@@ -953,7 +991,7 @@ public class ImageDtt extends ImageDttCPU {
final double [][] corrs,
final int tileX,
final int tileY,
final double max_corr_radius, // 3.9;
final double max_corr_radius, // 3.9; only used with clt_mismatch
int tile_lma_debug_level,
boolean debugTile,
final int globalDebugLevel)
......@@ -969,29 +1007,32 @@ public class ImageDtt extends ImageDttCPU {
int tIndex = tileY * tilesX + tileX;
final int [] overexp_all = (saturation_imp != null) ? ( new int [2]): null;
for (int i = 0; i < disparity_map.length; i++) {
if (disparity_map[i] != null) {
if ((((1 << i) & BITS_FROM_GPU) == 0) || !fneed_macro) { // do not touch data already set up
disparity_map[i][tIndex] = (
(i == DISPARITY_STRENGTH_INDEX) ||
(i == DISPARITY_INDEX_HOR_STRENGTH) ||
(i == DISPARITY_INDEX_VERT_STRENGTH)) ? 0.0 : Double.NaN; // once and for all
if (disparity_map != null) {
for (int i = 0; i < disparity_map.length; i++) {
if (disparity_map[i] != null) {
if ((((1 << i) & BITS_FROM_GPU) == 0) || !fneed_macro) { // do not touch data already set up
disparity_map[i][tIndex] = (
(i == DISPARITY_STRENGTH_INDEX) ||
(i == DISPARITY_INDEX_HOR_STRENGTH) ||
(i == DISPARITY_INDEX_VERT_STRENGTH)) ? 0.0 : Double.NaN; // once and for all
}
}
}
}
//clt_mismatch should only be used with disparity_map != null;
if (clt_mismatch != null) {
for (int np = 0; np < clt_mismatch.length/3; np++) {
clt_mismatch[3 * np + 0 ][tIndex] = Double.NaN;
clt_mismatch[3 * np + 1 ][tIndex] = Double.NaN;
clt_mismatch[3 * np + 2 ][tIndex] = 0;
// calculate overexposed fraction
if (saturation_imp != null){
// not yet implemented in GPU
disparity_map[OVEREXPOSED][tIndex] = 0.0; // (1.0 * overexp_all[0]) / overexp_all[1];
}
//clt_mismatch should only be used with disparity_map != null;
if (clt_mismatch != null) {
for (int np = 0; np < clt_mismatch.length/3; np++) {
clt_mismatch[3 * np + 0 ][tIndex] = Double.NaN;
clt_mismatch[3 * np + 1 ][tIndex] = Double.NaN;
clt_mismatch[3 * np + 2 ][tIndex] = 0;
}
}
}
// calculate overexposed fraction
if (saturation_imp != null){
disparity_map[OVEREXPOSED][tIndex] = (1.0 * overexp_all[0]) / overexp_all[1];
}
// calculate all selected pairs correlations
//int all_pairs = imgdtt_params.dbg_pair_mask; //TODO: use tile tasks
......@@ -1116,11 +1157,12 @@ public class ImageDtt extends ImageDttCPU {
double [] disp_str = new double[2];
if (ixy != null) {
disp_str[1] = strip_combo[ixy[0]+transform_size-1]; // strength at integer max on axis
disparity_map[DISPARITY_INDEX_INT][tIndex] = -ixy[0];
// disparity_map[DISPARITY_INDEX_INT + 1][tIndex] =
disparity_map[DISPARITY_STRENGTH_INDEX][tIndex] = disp_str[1];
if (Double.isNaN(disparity_map[DISPARITY_STRENGTH_INDEX][tIndex])) {
System.out.println("BUG: 1. disparity_map[DISPARITY_STRENGTH_INDEX]["+tIndex+"] should not be NaN");
if (disparity_map != null) {
disparity_map[DISPARITY_INDEX_INT][tIndex] = -ixy[0];
disparity_map[DISPARITY_STRENGTH_INDEX][tIndex] = disp_str[1];
if (Double.isNaN(disparity_map[DISPARITY_STRENGTH_INDEX][tIndex])) {
System.out.println("BUG: 1. disparity_map[DISPARITY_STRENGTH_INDEX]["+tIndex+"] should not be NaN");
}
}
corr_stat = corr2d.getMaxXCm( // get fractional center as a "center of mass" inside circle/square from the integer max
strip_combo, // double [] data, // [data_size * data_size]
......@@ -1129,62 +1171,66 @@ public class ImageDtt extends ImageDttCPU {
// corr_wndx, // double [] window_x, // half of a window function in x (disparity) direction
(tile_lma_debug_level > 0)); // boolean debug);
}
if (imgdtt_params.pcorr_use) {
// for compatibility with old code executed unconditionally. TODO: Move to if (corr_stat != null) ... condition below
double [] hor_pair1 = corr2d.getMaxXSOrtho(
corrs, // double [][] correlations,
0x100, // corrs[8] Correlation2d.getMaskHorizontal(1), // int pairs_mask,
imgdtt_params.corr_offset, // double corr_offset,
true, // boolean symmetric, // for comparing with old implementation average with symmetrical before multiplication
false, // boolean is_vert, // transpose X/Y
tile_lma_debug_level > 0); // boolean debug);
if (hor_pair1 != null) {
disparity_map[DISPARITY_INDEX_HOR][tIndex] = -hor_pair1[0];
disparity_map[DISPARITY_INDEX_HOR_STRENGTH][tIndex] = hor_pair1[1];
}
if (disparity_map != null) {
if (imgdtt_params.pcorr_use) {
// for compatibility with old code executed unconditionally. TODO: Move to if (corr_stat != null) ... condition below
double [] hor_pair1 = corr2d.getMaxXSOrtho(
corrs, // double [][] correlations,
0x100, // corrs[8] Correlation2d.getMaskHorizontal(1), // int pairs_mask,
imgdtt_params.corr_offset, // double corr_offset,
true, // boolean symmetric, // for comparing with old implementation average with symmetrical before multiplication
false, // boolean is_vert, // transpose X/Y
tile_lma_debug_level > 0); // boolean debug);
if (hor_pair1 != null){
disparity_map[DISPARITY_INDEX_HOR][tIndex] = -hor_pair1[0];
disparity_map[DISPARITY_INDEX_HOR_STRENGTH][tIndex] = hor_pair1[1];
}
double [] vert_pair1 = corr2d.getMaxXSOrtho(
corrs, // double [][] correlations,
0x200, // corrs[9] Correlation2d.getMaskVertical(1), // int pairs_mask,
imgdtt_params.corr_offset, // double corr_offset,
true, // boolean symmetric, // for comparing with old implementation average with symmetrical before multiplication
false, // already transposed // true, // boolean is_vert, // transpose X/Y
tile_lma_debug_level > 0); // boolean debug);
if (vert_pair1 != null) {
disparity_map[DISPARITY_INDEX_VERT][tIndex] = -vert_pair1[0];
disparity_map[DISPARITY_INDEX_VERT_STRENGTH][tIndex] = vert_pair1[1];
}
} else {
// for compatibility with old code executed unconditionally. TODO: Move to if (corr_stat != null) ... condition below
double [] hor_pair1 = corr2d.getMaxXSOrtho(
corrs, // double [][] correlations,
Correlation2d.getMaskHorizontal(1), // int pairs_mask,
imgdtt_params.corr_offset, // double corr_offset,
true, // boolean symmetric, // for comparing with old implementation average with symmetrical before multiplication
false, // boolean is_vert, // transpose X/Y
tile_lma_debug_level > 0); // boolean debug);
if (hor_pair1 != null) {
disparity_map[DISPARITY_INDEX_HOR][tIndex] = -hor_pair1[0];
disparity_map[DISPARITY_INDEX_HOR_STRENGTH][tIndex] = hor_pair1[1];
}
double [] vert_pair1 = corr2d.getMaxXSOrtho(
corrs, // double [][] correlations,
0x200, // corrs[9] Correlation2d.getMaskVertical(1), // int pairs_mask,
imgdtt_params.corr_offset, // double corr_offset,
true, // boolean symmetric, // for comparing with old implementation average with symmetrical before multiplication
false, // already transposed // true, // boolean is_vert, // transpose X/Y
tile_lma_debug_level > 0); // boolean debug);
if (vert_pair1 != null) {
disparity_map[DISPARITY_INDEX_VERT][tIndex] = -vert_pair1[0];
disparity_map[DISPARITY_INDEX_VERT_STRENGTH][tIndex] = vert_pair1[1];
}
} else {
// for compatibility with old code executed unconditionally. TODO: Move to if (corr_stat != null) ... condition below
double [] hor_pair1 = corr2d.getMaxXSOrtho(
corrs, // double [][] correlations,
Correlation2d.getMaskHorizontal(1), // int pairs_mask,
imgdtt_params.corr_offset, // double corr_offset,
true, // boolean symmetric, // for comparing with old implementation average with symmetrical before multiplication
false, // boolean is_vert, // transpose X/Y
tile_lma_debug_level > 0); // boolean debug);
if ((hor_pair1 != null)) {
disparity_map[DISPARITY_INDEX_HOR][tIndex] = -hor_pair1[0];
disparity_map[DISPARITY_INDEX_HOR_STRENGTH][tIndex] = hor_pair1[1];
}
double [] vert_pair1 = corr2d.getMaxXSOrtho(
corrs, // double [][] correlations,
Correlation2d.getMaskVertical(1), // int pairs_mask,
imgdtt_params.corr_offset, // double corr_offset,
true, // boolean symmetric, // for comparing with old implementation average with symmetrical before multiplication
true, // boolean is_vert, // transpose X/Y
tile_lma_debug_level > 0); // boolean debug);
if (vert_pair1 != null) {
disparity_map[DISPARITY_INDEX_VERT][tIndex] = -vert_pair1[0];
disparity_map[DISPARITY_INDEX_VERT_STRENGTH][tIndex] = vert_pair1[1];
double [] vert_pair1 = corr2d.getMaxXSOrtho(
corrs, // double [][] correlations,
Correlation2d.getMaskVertical(1), // int pairs_mask,
imgdtt_params.corr_offset, // double corr_offset,
true, // boolean symmetric, // for comparing with old implementation average with symmetrical before multiplication
true, // boolean is_vert, // transpose X/Y
tile_lma_debug_level > 0); // boolean debug);
if (vert_pair1 != null) {
disparity_map[DISPARITY_INDEX_VERT][tIndex] = -vert_pair1[0];
disparity_map[DISPARITY_INDEX_VERT_STRENGTH][tIndex] = vert_pair1[1];
}
}
}
// proceed only if CM correlation result is non-null // for compatibility with old code we need it to run regardless of the strength of the normal correlation
if (corr_stat != null) {
// skipping DISPARITY_VARIATIONS_INDEX - it was not used
disp_str[0] = -corr_stat[0];
disparity_map[DISPARITY_INDEX_CM][tIndex] = disp_str[0]; // disparity is negative X
if (disparity_map != null) {
disparity_map[DISPARITY_INDEX_CM][tIndex] = disp_str[0]; // disparity is negative X
}
if (tile_lma_debug_level > 0) {
System.out.println("Will run getMaxXSOrtho( ) for tileX="+tileX+", tileY="+tileY);
}
......@@ -1277,16 +1323,20 @@ public class ImageDtt extends ImageDttCPU {
tileX, tileY,
lma_disparity_strength[0],lma_disparity_strength[1]));
}
disparity_map[DISPARITY_INDEX_POLY] [tIndex] = lma_disparity_strength[0];
if (disparity_map != null) {
disparity_map[DISPARITY_INDEX_POLY] [tIndex] = lma_disparity_strength[0];
}
// if enabled overwrite - replace DISPARITY_INDEX_CM and DISPARITY_STRENGTH_INDEX
if (imgdtt_params.mix_corr_poly) { //true
disp_str[0] = lma_disparity_strength[0];
disp_str[1] = lma_disparity_strength[1];
disparity_map[DISPARITY_INDEX_CM] [tIndex] = disp_str[0];
disparity_map[DISPARITY_STRENGTH_INDEX] [tIndex] = disp_str[1];
if (Double.isNaN(disparity_map[DISPARITY_STRENGTH_INDEX][tIndex])) {
System.out.println("BUG: 2. disparity_map[DISPARITY_STRENGTH_INDEX][tIndex] should not be NaN");
if (disparity_map != null) {
disparity_map[DISPARITY_INDEX_CM] [tIndex] = disp_str[0];
disparity_map[DISPARITY_STRENGTH_INDEX] [tIndex] = disp_str[1];
if (Double.isNaN(disparity_map[DISPARITY_STRENGTH_INDEX][tIndex])) {
System.out.println("BUG: 2. disparity_map[DISPARITY_STRENGTH_INDEX][tIndex] should not be NaN");
}
}
}
// store debug data
......@@ -1333,7 +1383,9 @@ public class ImageDtt extends ImageDttCPU {
if ((mod_disparity_diff[0] != disp_str[0]) && (clt_mismatch == null)){ // if it changed
if (imgdtt_params.fo_correct && (disp_str[1] > imgdtt_params.fo_min_strength)) { // always
disp_str[0] = mod_disparity_diff[0];
disparity_map[DISPARITY_INDEX_CM] [tIndex] = disp_str[0];
if (disparity_map != null) {
disparity_map[DISPARITY_INDEX_CM] [tIndex] = disp_str[0];
}
}
}
}
......@@ -1421,9 +1473,10 @@ public class ImageDtt extends ImageDttCPU {
if (imgdtt_params.corr_poly_only) { // discard tile if LMA failed
disp_str[0] = Double.NaN;
disp_str[1] = 0.0;
disparity_map[DISPARITY_INDEX_CM] [tIndex] = disp_str[0];
disparity_map[DISPARITY_STRENGTH_INDEX] [tIndex] = disp_str[1];
if (disparity_map != null) {
disparity_map[DISPARITY_INDEX_CM] [tIndex] = disp_str[0];
disparity_map[DISPARITY_STRENGTH_INDEX] [tIndex] = disp_str[1];
}
}
}
}
......@@ -1443,6 +1496,519 @@ public class ImageDtt extends ImageDttCPU {
public float [][][][] blur_corr_GPU( // convert to pixel domain and process correlations already prepared in fcorr_td and/or fcorr_combo_td
// final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
final float [][][][] fcorr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
// final int debug_tileX,
// final int debug_tileY,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
if (this.gpuQuad == null) {
System.out.println("clt_aberrations_quad_corr_GPU(): this.gpuQuad is null, bailing out");
return null;
}
final int tilesX=gpuQuad.getTilesX(); // width/transform_size;
final int tilesY=gpuQuad.getTilesY(); // final int tilesY=height/transform_size;
final int numTiles = tilesX*tilesY;
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final float [][][][] fcorr_td_out = new float [tilesY][tilesX][][];
final float [] fweights = {0.125f, 0.0625f, 0.125f, 0.0625f,0.125f, 0.0625f,0.125f, 0.0625f, 0.25f}; // sum = 1.0
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
TileNeibs tn = new TileNeibs(tilesX,tilesY);
for (int indx_tile = ai.getAndIncrement(); indx_tile < numTiles; indx_tile = ai.getAndIncrement()) {
float s = 0;
float [] weights = new float [9];
int corr_len = 0;
int num_pairs = 0;
for (int dir = 0; dir < 9; dir++) { // 8 - center
int indx = tn.getNeibIndex(indx_tile, dir);
if (indx >=0) {
int [] xy = tn.getXY(indx);
if (fcorr_td[xy[1]][xy[0]] != null) {
float fw = fweights[dir];
s += fw;
weights[dir] = fw;
if (num_pairs == 0) {
num_pairs = fcorr_td[xy[1]][xy[0]].length;
corr_len = fcorr_td[xy[1]][xy[0]][0].length;
}
}
}
}
if (s > 0.0) {
for (int i = 0; i < weights.length; i++) {
weights[i] /= s;
}
float [][] tile_corrs = new float [num_pairs][corr_len];
for (int dir = 0; dir < 9; dir++) if (weights[dir] > 0.0f){ // 8 - center
int [] xy = tn.getXY(tn.getNeibIndex(indx_tile, dir));
for (int np = 0; np < num_pairs; np++) {
float [] ft = fcorr_td[xy[1]][xy[0]][np];
for (int i = 0; i < corr_len; i++) {
tile_corrs[np][i] += weights[dir] * ft[i];
}
}
}
int [] xy = tn.getXY(indx_tile);
fcorr_td_out[xy[1]][xy[0]] = tile_corrs;
}
} // end of tile
}
};
}
startAndJoin(threads);
return fcorr_td_out;
}
public float [][][][] blur_corr_combo_GPU( // convert to pixel domain and process correlations already prepared in fcorr_td and/or fcorr_combo_td
final float [][][][] fcorr_combo_td, // [n][tilesY][tilesX][4*64] transform domain representation of combined corr pairs
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
if (this.gpuQuad == null) {
System.out.println("clt_aberrations_quad_corr_GPU(): this.gpuQuad is null, bailing out");
return null;
}
final int tilesX=gpuQuad.getTilesX(); // width/transform_size;
final int tilesY=gpuQuad.getTilesY(); // final int tilesY=height/transform_size;
final int numTiles = tilesX*tilesY;
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final float [][][][] fcorr_td_combo_out = new float [fcorr_combo_td.length][][][];//[tilesY][tilesX][][];
for (int nl = 0; nl < fcorr_combo_td.length; nl++) {
if (fcorr_combo_td[nl] != null) fcorr_td_combo_out[nl] = new float [tilesY][tilesX][];
}
final float [] fweights = {0.125f, 0.0625f, 0.125f, 0.0625f,0.125f, 0.0625f,0.125f, 0.0625f, 0.25f}; // sum = 1.0
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
TileNeibs tn = new TileNeibs(tilesX,tilesY);
for (int indx_tile = ai.getAndIncrement(); indx_tile < numTiles; indx_tile = ai.getAndIncrement()) {
for (int nl = 0; nl < fcorr_combo_td.length; nl++) if (fcorr_combo_td[nl] != null){
float [][][] fcorr_combo = fcorr_combo_td[nl];
float s = 0;
float [] weights = new float [9];
int corr_len = 0;
for (int dir = 0; dir < 9; dir++) { // 8 - center
int indx = tn.getNeibIndex(indx_tile, dir);
if (indx >=0) {
int [] xy = tn.getXY(indx);
if (fcorr_combo[xy[1]][xy[0]] != null) {
float fw = fweights[dir];
s += fw;
weights[dir] = fw;
if (corr_len == 0) {
corr_len = fcorr_combo[xy[1]][xy[0]].length;
}
}
}
}
if (s > 0.0) {
for (int i = 0; i < weights.length; i++) {
weights[i] /= s;
}
float [] tile_corrs = new float [corr_len];
for (int dir = 0; dir < 9; dir++) if (weights[dir] > 0.0f){ // 8 - center
int [] xy = tn.getXY(tn.getNeibIndex(indx_tile, dir));
float [] ft = fcorr_combo[xy[1]][xy[0]];
for (int i = 0; i < corr_len; i++) {
tile_corrs[i] += weights[dir] * ft[i];
}
}
int [] xy = tn.getXY(indx_tile);
fcorr_td_combo_out[nl][xy[1]][xy[0]] = tile_corrs;
}
}
} // end of tile
}
};
}
startAndJoin(threads);
return fcorr_td_combo_out;
}
public double [][] cltMeasureLazyEyeGPU ( // returns d,s lazy eye parameters
final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
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
final float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
final float [][][][] fpxpy, // [tilesY][tilesX][cams][2], tile {pX,pY}
final double gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values
final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0\
final GeometryCorrection geometryCorrection,
final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
final double disparity_corr, // disparity at infinity
final int tileStep, // process tileStep x tileStep cluster of tiles when adjusting lazy eye parameters
final int debug_tileX,
final int debug_tileY,
final int threadsMax, // maximal number of threads to launch
final int globalDebugLevel)
{
final int quad = 4; // number of subcameras
final int num_pairs = 6;
final boolean use_main = geometryCorrection_main != null;
final double [][] rXY = geometryCorrection.getRXY(use_main);
final int tilesX=gpuQuad.getTilesX(); // width/transform_size;
final int tilesY=gpuQuad.getTilesY(); // final int tilesY=height/transform_size;
final int clustersX= (tilesX + tileStep - 1) / tileStep;
final int clustersY= (tilesY + tileStep - 1) / tileStep;
final double [][] lazy_eye_data = new double [clustersY*clustersX][];
final int gpu_corr_rad = transform_size - 1;
final int nClustersInChn=clustersX * clustersY;
/// final int clustSize = tileStep*tileStep;
final int debug_clustX = debug_tileX / tileStep;
final int debug_clustY = debug_tileY / tileStep;
// calculate which tiles to use for each cluster
// will generate sparse array for cluster central tiles to match CPU software
final float [][][][] fcorr_td_centers = new float [tilesY][tilesX][][]; // sparse, only in cluster centers
final int [][] num_in_cluster = new int [clustersY][clustersX]; // only in cluster centers
final double [][][][] disp_dist = new double [clustersY][clustersX][][];
final double [][][][] pxpy = new double [clustersY][clustersX][][];
final double [][] disparity_array_center = new double [clustersY][clustersX];
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
// TODO: Maybe calculate full energy in each TD tile for normalization
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int nCluster = ai.getAndIncrement(); nCluster < nClustersInChn; nCluster = ai.getAndIncrement()) {
int clustY = nCluster / clustersX;
int clustX = nCluster % clustersX;
/// double [][][] centersXY = new double [clustSize][][];
/// double [][][] disp_dist = new double[clustSize][quad][]; // used to correct 3D correlations
/// double [][][] corrs = new double [clustSize][][];
/// double [][] corr_stat = new double [clustSize][];
/// double [] strength = new double [clustSize];
/// double [][] disp_str = new double [clustSize][];
/// double [][] pxpy = new double [clustSize][2];
boolean debugCluster = (clustX == debug_clustX) && (clustY == debug_clustY);
/// boolean debugCluster1 = (Math.abs(clustX - debug_clustX) < 10) && (Math.abs(clustY - debug_clustY) < 10);
if (debugCluster) {
System.out.println("debugCluster");
}
/// int clust_lma_debug_level = debugCluster? imgdtt_params.lma_debug_level : -5;
// filter only tiles with similar disparity to enable lazy eye for the ERS.
int num_good_tiles = 0;
double avg= 0.0;
/// int corr_len = 0;
while (true) {
int mnTx = -1, mnTy = -1, mxTx = -1, mxTy = -1;
double mn = Double.NaN;
double mx = Double.NaN;
num_good_tiles = 0;
avg= 0.0;
for (int cTileY = 0; cTileY < tileStep; cTileY++) {
int tileY = clustY * tileStep + cTileY ;
if (tileY < tilesY) {
for (int cTileX = 0; cTileX < tileStep; cTileX++) {
int tileX = clustX * tileStep + cTileX ;
//// if ((tileX < tilesX) && (tile_op[tileY][tileX] != 0)) {
if ((tileX < tilesX) && (fcorr_td[tileY][tileX] != null)) {
double d = disparity_array [tileY][tileX];
avg += d;
if (!(d <= mx)) {
mx = d;
mxTx = tileX;
mxTy = tileY;
}
if (!(d >= mn)) {
mn = d;
mnTx = tileX;
mnTy = tileY;
}
num_good_tiles++;
}
}
}
}
if (num_good_tiles ==0) {
break;
}
if ((mx-mn) <= imgdtt_params.lma_disp_range ) {
break;
}
avg /= num_good_tiles;
if ((mx-avg) > (avg-mn)) {
fcorr_td[mxTy][mxTx] = null;
} else {
fcorr_td[mnTy][mnTx] = null;
}
//imgdtt_params.lma_disp_range
}
// for now - num_good_tiles - the only strength measure
// should it be calculated from the correlation normalization?
// will try to calculate through the sum of squared normalizations
float [][] ftd = new float [num_pairs][4* transform_size * transform_size];
if (num_good_tiles > 0) {
double dscale = 1.0/num_good_tiles;
// average fdisp_dist and fpxpy over remaining tiles
double [][] avg_disp_dist = new double [quad][4];
double [][] avg_pxpy = new double [quad][2];
for (int cTileY = 0; cTileY < tileStep; cTileY++) {
int tileY = clustY * tileStep + cTileY ;
if (tileY < tilesY) {
for (int cTileX = 0; cTileX < tileStep; cTileX++) {
int tileX = clustX * tileStep + cTileX ;
if ((tileX < tilesX) && (fcorr_td[tileY][tileX] != null)) {
for (int nc = 0; nc < quad; nc++) {
for (int i = 0; i < 4; i++) {
avg_disp_dist[nc][i] += fdisp_dist[tileY][tileX][nc][i];
}
for (int i = 0; i < 2; i++) {
avg_pxpy[nc][i] += fpxpy[tileY][tileX][nc][i];
}
}
}
}
}
}
int centerY = clustY * tileStep + tileStep/2; // integer was 242!
int centerX = clustX * tileStep + tileStep/2; // integer
if (centerY >= tilesY) {
centerY = tilesY - 1;
}
if (centerX >= tilesX) {
centerX = tilesX - 1;
}
// tile_op[centerY][centerX] = task_val;
num_in_cluster [clustY][clustX] = num_good_tiles;
disparity_array_center[clustY][clustX] = avg;
for (int nc = 0; nc < quad; nc++) {
for (int i = 0; i < 4; i++) {
avg_disp_dist[nc][i] *= dscale;
}
for (int i = 0; i < 2; i++) {
avg_pxpy[nc][i] *= dscale;
}
}
disp_dist[clustY][clustX] = avg_disp_dist;
pxpy [clustY][clustX] = avg_pxpy;
// accumulate TD tiles
// If needed - save average
for (int cTileY = 0; cTileY < tileStep; cTileY++) {
int tileY = clustY * tileStep + cTileY ;
if (tileY < tilesY) {
for (int cTileX = 0; cTileX < tileStep; cTileX++) {
int tileX = clustX * tileStep + cTileX ;
if ((tileX < tilesX) && (fcorr_td[tileY][tileX] != null)) {
for (int np = 0; np <num_pairs; np++) {
for (int i = 0; i < ftd[np].length; i++) {
ftd[np][i]+=fcorr_td[tileY][tileX][np][i];
}
}
}
}
}
}
float fscale = 1.0f/num_good_tiles;
for (int np = 0; np <num_pairs; np++) {
for (int i = 0; i < ftd[np].length; i++) {
ftd[np][i] *= fscale;
}
}
fcorr_td_centers[centerY][centerX]= ftd;
}
} // end of cluster
}
};
}
startAndJoin(threads);
int [][] pairs_map = {{0,0},{1,1},{2,2},{3,3},{4,4},{5,5}};
final int [] corr_indices = gpuQuad.setCorrTilesTd( // .length = 295866 should set num_corr_tiles!
fcorr_td_centers, // final float [][][][] corr_tiles, // [tileY][tileX][pair][4*64]
pairs_map); // int [][] pairs) // typically {{0,0},{1,1},{2,2},{3,3},{4,4},{5,5} [0] - 3rd index in corr_tiles, [1] -
gpuQuad.execCorr2D_normalize(
false, // boolean combo, // normalize combo correlations (false - per-pair ones)
gpu_fat_zero, // double fat_zero);
gpu_corr_rad); // int corr_radius
final float [][] fcorr2D = gpuQuad.getCorr2D(gpu_corr_rad); // int corr_rad);
final int corr_length = fcorr2D[0].length;// all correlation tiles have the same size
final int num_tiles = corr_indices.length / num_pairs;
final double [][] corr_wnd = Corr2dLMA.getCorrWnd(
transform_size,
imgdtt_params.lma_wnd);
final double [] corr_wnd_inv_limited = (imgdtt_params.lma_min_wnd <= 1.0)? new double [corr_wnd.length * corr_wnd[0].length]: null;
if (corr_wnd_inv_limited != null) {
double inv_pwr = imgdtt_params.lma_wnd_pwr - (imgdtt_params.lma_wnd - 1.0); // compensate for lma_wnd
for (int i = imgdtt_params.lma_hard_marg; i < (corr_wnd.length - imgdtt_params.lma_hard_marg); i++) {
for (int j = imgdtt_params.lma_hard_marg; j < (corr_wnd.length - imgdtt_params.lma_hard_marg); j++) {
corr_wnd_inv_limited[i * (corr_wnd.length) + j] = 1.0/Math.max(Math.pow(corr_wnd[i][j],
inv_pwr),
imgdtt_params.lma_min_wnd);
}
}
}
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
Correlation2d corr2d = new Correlation2d(
imgdtt_params, // ImageDttParameters imgdtt_params,
transform_size, // int transform_size,
2.0, // double wndx_scale, // (wndy scale is always 1.0)
isMonochrome(), // boolean monochrome,
(globalDebugLevel > -1)); // boolean debug)
corr2d.createOrtoNotch(
imgdtt_params.getEnhOrthoWidth(isAux()), // double getEnhOrthoWidth(isAux()),
imgdtt_params.getEnhOrthoScale(isAux()), //double getEnhOrthoScale(isAux()),
(imgdtt_params.lma_debug_level > 1)); // boolean debug);
for (int indx_tile = ai.getAndIncrement(); indx_tile < num_tiles; indx_tile = ai.getAndIncrement()) {
double [][] corrs = new double [GPUTileProcessor.NUM_PAIRS][corr_length]; // 225-long (15x15)
int indx_corr = indx_tile * num_pairs;
int nt = (corr_indices[indx_corr] >> GPUTileProcessor.CORR_NTILE_SHIFT);
int tileX = nt % tilesX;
int tileY = nt / tilesX;
int clustX = tileX/tileStep;
int clustY = tileY/tileStep;
double [] disp_str = null;
for (int indx_pair = 0; indx_pair < num_pairs; indx_pair++) {
int pair = corr_indices[indx_corr] & GPUTileProcessor.CORR_PAIRS_MASK; // ((1 << CORR_NTILE_SHIFT) - 1); // np should
assert pair < GPUTileProcessor.NUM_PAIRS : "invalid correllation pair";
/// pair_mask |= (1 << pair);
for (int i = 0; i < corr_length; i++) {
corrs[pair][i] = gpu_corr_scale * fcorr2D[indx_corr][i]; // from float to double
}
indx_corr++;
}
// final float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
double [][] tile_disp_dist = disp_dist[clustY][clustX];
/*
double [][] disp_dist = new double [fdd.length][fdd[0].length];
for (int n = 0; n < fdd.length; n++) {
for (int i = 0; i < fdd[0].length; i++) {
disp_dist[n][i] = fdd[n][i]; // float to double
}
}
*/
// debug new LMA correlations
boolean debugCluster = (clustX == debug_clustX) && (clustY == debug_clustY);
int tile_lma_debug_level = ((tileX == debug_tileX) && (tileY == debug_tileY))? imgdtt_params.lma_debug_level : -1;
int tdl = debugCluster ? tile_lma_debug_level : -3;
if (debugCluster && (globalDebugLevel > -1)) { // -2)) {
System.out.println("Will run new LMA for tileX="+tileX+", tileY="+tileY);
}
double [] poly_disp = {Double.NaN, 0.0};
Corr2dLMA lma2 = corr2d.corrLMA2( // num_tiles == 1
imgdtt_params, // ImageDttParameters imgdtt_params,
corr_wnd, // double [][] corr_wnd, // correlation window to save on re-calculation of the window
corr_wnd_inv_limited, // corr_wnd_limited, // correlation window, limited not to be smaller than threshold - used for finding max/convex areas (or null)
corrs, // double [][] corrs,
tile_disp_dist,
rXY, // double [][] rXY, // non-distorted X,Y offset per nominal pixel of disparity
imgdtt_params.dbg_pair_mask, // int pair_mask, // which pairs to process
null, // disp_str[cTile], //corr_stat[0], // double xcenter, // preliminary center x in pixels for largest baseline
poly_disp, // double[] poly_ds, // null or pair of disparity/strength
imgdtt_params.ortho_vasw_pwr, // double vasw_pwr, // value as weight to this power,
tdl, // tile_lma_debug_level, //+2, // int debug_level,
tileX, // int tileX, // just for debug output
tileY); // int tileY
if (lma2 != null) {
// was for single tile
disp_str = lma2.lmaDisparityStrength(
imgdtt_params.lmas_max_rel_rms, // maximal relative (to average max/min amplitude LMA RMS) // May be up to 0.3)
imgdtt_params.lmas_min_strength, // minimal composite strength (sqrt(average amp squared over absolute RMS)
imgdtt_params.lmas_min_ac, // minimal of A and C coefficients maximum (measures sharpest point/line)
imgdtt_params.lmas_max_area, // double lma_max_area, // maximal half-area (if > 0.0)
imgdtt_params.lma_str_scale, // convert lma-generated strength to match previous ones - scale
imgdtt_params.lma_str_offset // convert lma-generated strength to match previous ones - add to result
)[0];
if (tile_lma_debug_level > 0) {
double [][] ds_dbg = {disp_str};
lma2.printStats(ds_dbg,1);
}
//was for multi-tile
int nCluster = clustY * clustersX + clustX;
double [][] ddnd = lma2.getDdNd();
double [] stats = lma2.getStats(num_in_cluster[clustY][clustX]);
double [][] lma_ds = lma2.lmaDisparityStrength( // [1][2]
imgdtt_params.lma_max_rel_rms, // maximal relative (to average max/min amplitude LMA RMS) // May be up to 0.3)
imgdtt_params.lma_min_strength, // minimal composite strength (sqrt(average amp squared over absolute RMS)
imgdtt_params.lma_min_ac, // minimal of A and C coefficients maximum (measures sharpest point/line)
imgdtt_params.lma_max_area, //double lma_max_area, // maximal half-area (if > 0.0)
1.0, // imgdtt_params.lma_str_scale, // convert lma-generated strength to match previous ones - scale
0.0); // imgdtt_params.lma_str_offset); // convert lma-generated strength to match previous ones - add to result
/// double [][] extra_stats = lma2.getTileStats();
// final double [][] lazy_eye_data = new double [clustersY*clustersX][];
// calculate average disparity per cluster using a sum of the disparity_array and the result of the LMA
lazy_eye_data[nCluster] = new double [ExtrinsicAdjustment.INDX_LENGTH];
double sum_w = 0;
// FIXME - single CTileX =0; cTileY = 0
/// int cTileY = 0;
/// int cTileX = 0;
/// int tIndex = tileY * tilesX + tileX;
if ((lma_ds[0] != null) && (lma_ds[0][1]> 0.0)) {
double w = lma_ds[0][1];
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_DISP] += (lma_ds[0][0] + disparity_array_center[clustY][clustX] + disparity_corr) * w;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_TARGET] += (disparity_array_center[clustY][clustX] + disparity_corr) * w;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_DIFF] += lma_ds[0][0] * w;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_PX + 0] += pxpy[clustY][clustX][0][0] * w;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_PX + 1] += pxpy[clustY][clustX][0][1] * w;
for (int cam = 0; cam < quad; cam++) {
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_DYDDISP0 + cam] += tile_disp_dist[cam][2] * w;
}
sum_w += w;
}
if (sum_w > 0.0) { // may be simplified as there is only one tile now
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_STRENGTH] = stats[0];
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_DISP] /= sum_w;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_TARGET] /= sum_w;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_DIFF] /= sum_w;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_PX + 0] /= sum_w;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_PX + 1] /= sum_w;
for (int cam = 0; cam < quad; cam++) {
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_DYDDISP0 + cam] /= sum_w;
}
for (int cam = 0; cam < ddnd.length; cam++) {
if (ddnd[cam] != null) { //convert to x,y from dd/nd
lazy_eye_data[nCluster][2 * cam + ExtrinsicAdjustment.INDX_X0 + 0] = ddnd[cam][0] * rXY[cam][0] - ddnd[cam][1] * rXY[cam][1];
lazy_eye_data[nCluster][2 * cam + ExtrinsicAdjustment.INDX_X0 + 1] = ddnd[cam][0] * rXY[cam][1] + ddnd[cam][1] * rXY[cam][0];
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_DD0 + cam] = ddnd[cam][0];
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_ND0 + cam] = ddnd[cam][1];
} else {
lazy_eye_data[nCluster][2 * cam + ExtrinsicAdjustment.INDX_X0 + 0] = Double.NaN;
lazy_eye_data[nCluster][2 * cam + ExtrinsicAdjustment.INDX_X0 + 1] = Double.NaN;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_DD0 + cam] = Double.NaN;
lazy_eye_data[nCluster][ExtrinsicAdjustment.INDX_ND0 + cam] = Double.NaN;
}
}
} else {
lazy_eye_data[nCluster] = null;
}
}
} // end of tile
}
};
}
startAndJoin(threads);
return lazy_eye_data;
}
......
......@@ -1509,7 +1509,7 @@ public class ImageDttCPU {
}
// removing macro and FPGA modes
public double [][] cltMeasureLazyEye ( // returns d,s lazy eye parameters
public double[][] cltMeasureLazyEye ( // returns d,s lazy eye parameters
final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
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
......@@ -1753,6 +1753,7 @@ public class ImageDttCPU {
// filter only tiles with similar disparity to enable lazy eye for the ERS.
int num_good_tiles = 0;
while (true) {
// num_good_tiles = 0; // FIXME: Was missing - uncomment?
int mnTx = -1, mnTy = -1, mxTx = -1, mxTy = -1;
double mn = Double.NaN;
double mx = Double.NaN;
......@@ -2148,7 +2149,7 @@ public class ImageDttCPU {
imgdtt_params.lmas_max_rel_rms, // maximal relative (to average max/min amplitude LMA RMS) // May be up to 0.3)
imgdtt_params.lmas_min_strength, // minimal composite strength (sqrt(average amp squared over absolute RMS)
imgdtt_params.lmas_min_ac, // minimal of A and C coefficients maximum (measures sharpest point/line)
imgdtt_params.lmas_max_area, //double lma_max_area, // maximal half-area (if > 0.0)
imgdtt_params.lmas_max_area, // double lma_max_area, // maximal half-area (if > 0.0)
imgdtt_params.lma_str_scale, // convert lma-generated strength to match previous ones - scale
imgdtt_params.lma_str_offset // convert lma-generated strength to match previous ones - add to result
)[0];
......
......@@ -47,7 +47,6 @@ import com.elphel.imagej.gpu.GPUTileProcessor;
import ij.ImagePlus;
import ij.ImageStack;
public class QuadCLT extends QuadCLTCPU {
private GPUTileProcessor.GpuQuad gpuQuad = null;
public QuadCLT(
......@@ -68,154 +67,6 @@ public class QuadCLT extends QuadCLTCPU {
public GPUTileProcessor.GpuQuad getGPU() {
return this.gpuQuad;
}
/*
public CLTPass3d CLTBackgroundMeasGPU( // measure background - not used at all?
CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
CLTPass3d scan_rslt = new CLTPass3d(tp);
int d = ImageDtt.setImgMask(0, 0xf);
d = ImageDtt.setPairMask(d,0xf);
d = ImageDtt.setForcedDisparity(d,true);
int [][] tile_op = tp.setSameTileOp(clt_parameters, d, debugLevel);
double [][] disparity_array = tp.setSameDisparity(0.0); // [tp.tilesY][tp.tilesX] - individual per-tile expected disparity
// undecided, so 2 modes of combining alpha - same as rgb, or use center tile only
double [][][][] clt_corr_combo = new double [ImageDtt.TCORR_TITLES.length][tilesY][tilesX][]; // will only be used inside?
double min_corr_selected = clt_parameters.min_corr; // 0.02
double [][] disparity_map = new double [ImageDtt.DISPARITY_TITLES.length][]; //[0] -residual disparity, [1] - orthogonal (just for debugging)
double [][] shiftXY = new double [4][2];
if (!clt_parameters.fine_corr_ignore) {
double [][] shiftXY0 = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
{clt_parameters.fine_corr_x_2,clt_parameters.fine_corr_y_2},
{clt_parameters.fine_corr_x_3,clt_parameters.fine_corr_y_3}};
shiftXY = shiftXY0;
}
double [][][][] texture_tiles = new double [tilesY][tilesX][][]; // ["RGBA".length()][];
ImageDtt image_dtt = new ImageDtt(
clt_parameters.transform_size,
isMonochrome(),
isLwir(),
clt_parameters.getScaleStrength(isAux()));
double z_correction = clt_parameters.z_correction;
if (clt_parameters.z_corr_map.containsKey(image_name)){ // not used in lwir
z_correction +=clt_parameters.z_corr_map.get(image_name);
}
final double disparity_corr = (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction);
double [][][][][] clt_corr_partial = null;
if (clt_parameters.img_dtt.gpu_mode_debug) {
clt_corr_combo = 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;
}
}
}
image_dtt.clt_aberrations_quad_corr(
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
1, // final int macro_scale, // to correlate tile data instead of the pixel data: 1 - pixels, 8 - tiles
tile_op, // per-tile operation bit codes
disparity_array, // clt_parameters.disparity, // final double disparity,
image_data, // final double [][][] imade_data, // first index - number of image in a quad
saturation_imp, // boolean [][] saturation_imp, // (near) saturated pixels or null
// correlation results - final and partial
clt_corr_combo, // [tp.tilesY][tp.tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
clt_corr_partial, // null, // clt_corr_partial, // [tp.tilesY][tp.tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
null, // [tp.tilesY][tp.tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
// Use it with disparity_maps[scan_step]? clt_mismatch, // [tp.tilesY][tp.tilesX][pair]{dx,dy,weight}[(2*transform_size-1)*(2*transform_size-1)] // transpose unapplied. null - do not calculate
disparity_map, // [12][tp.tilesY * tp.tilesX]
texture_tiles, // [tp.tilesY][tp.tilesX]["RGBA".length()][];
tilesX * image_dtt.transform_size, // imp_quad[0].getWidth(), // final int width,
clt_parameters.getFatZero(isMonochrome()), // add to denominator to modify phase correlation (same units as data1, data2). <0 - pure sum
clt_parameters.corr_sym,
clt_parameters.corr_offset,
clt_parameters.corr_red,
clt_parameters.corr_blue,
clt_parameters.getCorrSigma(image_dtt.isMonochrome()),
clt_parameters.corr_normalize, // normalize correlation results by rms
min_corr_selected, // 0.0001; // minimal correlation value to consider valid
clt_parameters.max_corr_sigma,// 1.5; // weights of points around global max to find fractional
clt_parameters.max_corr_radius,
clt_parameters.max_corr_double, // Double pass when masking center of mass to reduce preference for integer values
clt_parameters.corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
clt_parameters.min_shot, // 10.0; // Do not adjust for shot noise if lower than
clt_parameters.scale_shot, // 3.0; // scale when dividing by sqrt ( <0 - disable correction)
clt_parameters.diff_sigma, // 5.0;//RMS difference from average to reduce weights (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
clt_parameters.min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
clt_parameters.dust_remove, // Do not reduce average weight when only one image differes much from the average
clt_parameters.keep_weights, // Add port weights to RGBA stack (debug feature)
geometryCorrection, // final GeometryCorrection geometryCorrection,
null, // final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
clt_parameters.kernel_step,
/// image_dtt.transform_size,
clt_parameters.clt_window,
shiftXY, //
disparity_corr, // final double disparity_corr, // disparity at infinity
(clt_parameters.fcorr_ignore? null: this.fine_corr),
clt_parameters.corr_magic_scale, // still not understood coefficient that reduces reported disparity value. Seems to be around 0.85
clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing
clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down)
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
(clt_parameters.dbg_mode & 64) != 0, // no fract shift
(clt_parameters.dbg_mode & 128) != 0, // no convolve
// (clt_parameters.dbg_mode & 256) != 0, // transpose convolve
threadsMax,
debugLevel);
scan_rslt.disparity = disparity_array;
scan_rslt.tile_op = tile_op;
scan_rslt.disparity_map = disparity_map;
scan_rslt.texture_tiles = texture_tiles;
scan_rslt.is_measured = true;
scan_rslt.is_combo = false;
scan_rslt.resetProcessed();
if (clt_corr_partial!=null){ // only to debug matching gpu/cpu
if (debugLevel > -1){ // -1
String [] allColorNames = {"red","blue","green","combo"};
String [] titles = new String[clt_corr_partial.length];
for (int i = 0; i < titles.length; i++){
titles[i]=allColorNames[i % allColorNames.length]+"_"+(i / allColorNames.length);
}
double [][] corr_rslt_partial = image_dtt.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,
debugLevel);
// titles.length = 15, corr_rslt_partial.length=16!
System.out.println("corr_rslt_partial.length = "+corr_rslt_partial.length+", titles.length = "+titles.length);
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
corr_rslt_partial,
tilesX*(2*image_dtt.transform_size),
tilesY*(2*image_dtt.transform_size),
true,
image_name+sAux()+"-PART_CORR-GPU-D"+clt_parameters.disparity);
}
}
return scan_rslt;
}
*/
public void processCLTQuadCorrGPU(
ImagePlus [] imp_quad,
boolean [][] saturation_imp, // (near) saturated pixels or null // Not needed use this.saturation_imp
......@@ -1284,6 +1135,8 @@ public class QuadCLT extends QuadCLTCPU {
null, // final float [][][][] corr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
null, // 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 float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
null, // final float [][][][] fpxpy, // [tilesY][tilesX][cams][2], tile {pX,pY}
//// Uses quadCLT from gpuQuad
// correlation results - final and partial
clt_corr_combo, // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
......@@ -1343,12 +1196,7 @@ public class QuadCLT extends QuadCLTCPU {
scan_rslt.is_combo = false;
scan_rslt.resetProcessed();
if (clt_corr_partial!=null){ // only to debug matching gpu/cpu
if (debugLevel > -3){ // -1
String [] allColorNames = {"red","blue","green","combo"};
String [] titles = new String[clt_corr_partial.length];
for (int i = 0; i < titles.length; i++){
titles[i]=allColorNames[i % allColorNames.length]+"_"+(i / allColorNames.length);
}
if (debugLevel > -1){ // -1
double [][] corr_rslt_partial = image_dtt.corr_partial_dbg(
clt_corr_partial,
2*image_dtt.transform_size - 1, //final int corr_size,
......@@ -1358,7 +1206,6 @@ public class QuadCLT extends QuadCLTCPU {
threadsMax,
debugLevel);
// titles.length = 15, corr_rslt_partial.length=16!
System.out.println("corr_rslt_partial.length = "+corr_rslt_partial.length+", titles.length = "+titles.length);
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
corr_rslt_partial,
tilesX*(2*image_dtt.transform_size),
......@@ -1453,7 +1300,8 @@ public class QuadCLT extends QuadCLTCPU {
return imp_texture_full;
}
// Resore to CLTMeasureCorr when done testing
public CLTPass3d CLTMeasureCorr( // perform single pass according to prepared tiles operations and disparity // not used in lwir
CLTParameters clt_parameters,
final int scanIndex,
......@@ -1529,6 +1377,8 @@ public class QuadCLT extends QuadCLTCPU {
null, // final float [][][][] corr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
null, // 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 float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
null, // final float [][][][] fpxpy, // [tilesY][tilesX][cams][2], tile {pX,pY}
//// Uses quadCLT from gpuQuad
// correlation results - final and partial
null, // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
......@@ -1588,6 +1438,267 @@ public class QuadCLT extends QuadCLTCPU {
}
public CLTPass3d CLTMeasureCorrTesting( // perform single pass according to prepared tiles operations and disparity // not used in lwir
CLTParameters clt_parameters,
final int scanIndex,
final boolean save_textures,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
if ((gpuQuad == null) || !(isAux()?clt_parameters.gpu_use_aux : clt_parameters.gpu_use_main)) {
return super.CLTMeasureCorr( // perform single pass according to prepared tiles operations and disparity
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
scanIndex, // final int scanIndex,
save_textures, // final boolean save_textures,
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
}
// GPU will not use textures. Maybe set texture_selection instead?
// final int transform_size =clt_parameters.transform_size;
CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
int [][] tile_op = scan.tile_op;
double [][] disparity_array = scan.disparity;
boolean [] tex_sel = null;
if (save_textures) {
tex_sel = new boolean [tilesY*tilesX];
for (int ty = 0; ty < tilesY; ty++) {
for (int tx = 0; tx < tilesX; tx++) {
if (tile_op[ty][tx] != 0){
tex_sel[ty * tilesX + tx] = true;
}
}
}
}
double [][] disparity_map = new double [ImageDtt.DISPARITY_TITLES.length][];
/*
double [][] shiftXY = new double [4][2];
// not used
if (!clt_parameters.fine_corr_ignore) {
double [][] shiftXY0 = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
{clt_parameters.fine_corr_x_2,clt_parameters.fine_corr_y_2},
{clt_parameters.fine_corr_x_3,clt_parameters.fine_corr_y_3}};
shiftXY = shiftXY0;
}
*/
ImageDtt image_dtt = new ImageDtt(
clt_parameters.transform_size,
isMonochrome(),
isLwir(),
clt_parameters.getScaleStrength(isAux()),
gpuQuad);
double z_correction = clt_parameters.z_correction;
if (clt_parameters.z_corr_map.containsKey(image_name)){ // not used in lwir
z_correction +=clt_parameters.z_corr_map.get(image_name);
}
final double disparity_corr = (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction);
// TODO: find where BITS_ALL_DIFFS is not needed and remove - it takes much longer than correlation in the GPU
int disparity_modes =
ImageDtt.BITS_ALL_DISPARITIES |
ImageDtt.BITS_ALL_DIFFS | // needs max_diff?
ImageDtt.BITS_OVEREXPOSED; // |
// ImageDtt.BITS_TONE_RGB;
// testing - remove later
float [][][][] corr_td = new float[tilesY][tilesX][][];
float [][][][] corr_combo_td = new float [4][tilesY][tilesX][];
double [][][][][] clt_corr_partial0 = null;
clt_corr_partial0 = new double [tilesY][tilesX][][][];
for (int i = 0; i < tilesY; i++){
for (int j = 0; j < tilesX; j++){
clt_corr_partial0[i][j] = null;
}
}
image_dtt.clt_aberrations_quad_corr_GPU( // USED in LWIR
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
1, // final int macro_scale, // to correlate tile data instead of the pixel data: 1 - pixels, 8 - tiles
tile_op, // per-tile operation bit codes
disparity_array, // clt_parameters.disparity, // final double disparity,
corr_td, // final float [][][][] corr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
corr_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 float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
null, // final float [][][][] fpxpy, // [tilesY][tilesX][cams][2], tile {pX,pY}
//// Uses quadCLT from gpuQuad
// correlation results - final and partial
null, // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
// [type][tilesY][tilesX] should be set by caller
// types: 0 - selected correlation (product+offset), 1 - sum
clt_corr_partial0, // 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, // 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, // disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
// last 2 - contrast, avg/ "geometric average)
disparity_modes, // disparity_modes, // bit mask of disparity_map slices to calculate/return
null, // final double [][][][] texture_tiles, // compatible with the CPU ones
null, // texture_img, // texture_img, // null or [3][] (RGB) or [4][] RGBA
null, // texture_woi, // texture_woi, // null or generated texture location/size
null, // iclt_fimg, // will return quad images or null to skip, use quadCLT.linearStackToColor
// new parameters, will replace some other?
// clt_parameters.getFatZero(isMonochrome()), // final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0\
clt_parameters.gpu_corr_scale, // gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values
clt_parameters.getGpuFatZero(isMonochrome()), // final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0\
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;
(isMonochrome()? 1.0 : clt_parameters.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
image_dtt.transform_size - 1, // clt_parameters.gpu_corr_rad, // = transform_size - 1 ?
clt_parameters.corr_red, // +used
clt_parameters.corr_blue, // +used
clt_parameters.max_corr_radius,// 3.9;
clt_parameters.corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
clt_parameters.min_shot, // 10.0; // Do not adjust for shot noise if lower than
clt_parameters.scale_shot, // 3.0; // scale when dividing by sqrt ( <0 - disable correction)
clt_parameters.diff_sigma, // 5.0;//RMS difference from average to reduce weights (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
clt_parameters.min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
clt_parameters.dust_remove, // Do not reduce average weight when only one image differes much from the average
geometryCorrection, // final GeometryCorrection geometryCorrection,
null, // final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
clt_parameters.clt_window,
disparity_corr, // final double disparity_corr, // disparity at infinity
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
threadsMax,
debugLevel);
scan.disparity_map = disparity_map;
scan.texture_tiles = null;
scan.setTextureSelection(tex_sel);
scan.is_measured = true; // but no disparity map/textures
scan.is_combo = false;
scan.resetProcessed();
// testing
// float [][][][] corr_td = new float[tilesY][tilesX][][];
// float [][][][] corr_combo_td = new float [4][tilesY][tilesX][];
(new ShowDoubleFloatArrays()).showArrays(
disparity_map,
tilesX,
tilesY,
true,
"original_disparity_map"
// ,dbg_titles
);
if (debugLevel > -10){ // -1
double [][] corr_rslt_partial = image_dtt.corr_partial_dbg(
clt_corr_partial0,
2*image_dtt.transform_size - 1, //final int corr_size,
4, // final int pairs,
4, // final int colors,
clt_parameters.corr_border_contrast,
threadsMax,
debugLevel);
// titles.length = 15, corr_rslt_partial.length=16!
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
corr_rslt_partial,
tilesX*(2*image_dtt.transform_size),
tilesY*(2*image_dtt.transform_size),
true,
image_name+sAux()+"-ORIG-PART_CORR-D"+clt_parameters.disparity);
// titles);
}
double [][][][][] clt_corr_partial1 = null;
clt_corr_partial1 = new double [tilesY][tilesX][][][];
for (int i = 0; i < tilesY; i++){
for (int j = 0; j < tilesX; j++){
clt_corr_partial1[i][j] = null;
}
}
double [][] disparity_map1 = new double [ImageDtt.DISPARITY_TITLES.length][];
float [][][][] corr_td_blur = image_dtt.blur_corr_GPU( // convert to pixel domain and process correlations already prepared in fcorr_td and/or fcorr_combo_td
// final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
corr_td, // final float [][][][] fcorr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
// final int debug_tileX,
// final int debug_tileY,
threadsMax, // final int threadsMax, // maximal number of threads to launch
debugLevel); // final int globalDebugLevel)
float [][][][] corr_combo_blur = image_dtt.blur_corr_combo_GPU( // convert to pixel domain and process correlations already prepared in fcorr_td and/or fcorr_combo_td
// final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
corr_combo_td, // final float [][][][] fcorr_combo_td, // [n][tilesY][tilesX][4*64] transform domain representation of combined corr pairs
// final int debug_tileX,
// final int debug_tileY,
threadsMax, // final int threadsMax, // maximal number of threads to launch
debugLevel); // final int globalDebugLevel)
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
corr_td_blur, // final float [][][][] corr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
corr_combo_blur, // 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_partial1, // 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_map1, // 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(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,
debugLevel);
(new ShowDoubleFloatArrays()).showArrays(
disparity_map1,
tilesX,
tilesY,
true,
"rebuilt_disparity_map"
// ,dbg_titles
);
if (debugLevel > -10){ // -1
double [][] corr_rslt_partial = image_dtt.corr_partial_dbg(
clt_corr_partial1,
2*image_dtt.transform_size - 1, //final int corr_size,
4, // final int pairs,
4, // final int colors,
clt_parameters.corr_border_contrast,
threadsMax,
debugLevel);
// titles.length = 15, corr_rslt_partial.length=16!
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
corr_rslt_partial,
tilesX*(2*image_dtt.transform_size),
tilesY*(2*image_dtt.transform_size),
true,
image_name+sAux()+"-TD-PART_CORR-D"+clt_parameters.disparity);
// titles);
}
return scan;
}
public String getPassImage( // get image from a single pass, return relative path for x3d // USED in lwir
CLTParameters clt_parameters,
ColorProcParameters colorProcParameters,
......@@ -1847,6 +1958,8 @@ public class QuadCLT extends QuadCLTCPU {
null, // final float [][][][] corr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
null, // 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 float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
null, // final float [][][][] fpxpy, // [tilesY][tilesX][cams][2], tile {pX,pY}
//// Uses quadCLT from gpuQuad
// correlation results - final and partial
null, // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
......@@ -1963,6 +2076,8 @@ public class QuadCLT extends QuadCLTCPU {
null, // final float [][][][] corr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
null, // 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 float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
null, // final float [][][][] fpxpy, // [tilesY][tilesX][cams][2], tile {pX,pY}
//// Uses quadCLT from gpuQuad
// correlation results - final and partial
null, // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
......@@ -2049,5 +2164,239 @@ public class QuadCLT extends QuadCLTCPU {
}
public CLTPass3d CLTMeasureLY( // perform single pass according to prepared tiles operations and disparity // USED in lwir
final CLTParameters clt_parameters,
final int scanIndex,
final int bgIndex, // combine, if >=0
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
int debugLevel)
{
final int dbg_x = -295-debugLevel;
final int dbg_y = -160-debugLevel;
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
final int cluster_size =clt_parameters.tileStep;
final int clustersX= (tilesX + cluster_size - 1) / cluster_size;
final int clustersY= (tilesY + cluster_size - 1) / cluster_size;
CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
scan.setLazyEyeClusterSize(cluster_size);
boolean [] force_disparity= new boolean[clustersX * clustersY];
// scan.setLazyEyeForceDisparity(force_disparity);
if (bgIndex >= 0) {
CLTPass3d bg_scan = tp.clt_3d_passes.get(bgIndex);
// if at least one tile in a cluster is BG, use BG for the whole cluster and set lazy_eye_force_disparity
for (int cY = 0; cY < clustersY; cY ++) {
for (int cX = 0; cX < clustersX; cX ++) {
boolean has_bg = false;
for (int cty = 0; (cty < cluster_size) && !has_bg; cty++) {
int ty = cY * cluster_size + cty;
if (ty < tilesY) for (int ctx = 0; ctx < cluster_size; ctx++) {
int tx = cX * cluster_size + ctx;
if ((tx < tilesX ) && (bg_scan.tile_op[ty][tx] > 0)) {
has_bg = true;
break;
}
}
}
if (has_bg) {
for (int cty = 0; cty < cluster_size; cty++) {
int ty = cY * cluster_size + cty;
if (ty < tilesY) for (int ctx = 0; ctx < cluster_size; ctx++) {
int tx = cX * cluster_size + ctx;
if (tx < tilesX ) {
scan.tile_op[ty][tx] = bg_scan.tile_op[ty][tx];
scan.disparity[ty][tx] = bg_scan.disparity[ty][tx];
}
}
}
force_disparity[cY * clustersX + cX] = true;
}
}
}
scan.setLazyEyeForceDisparity(force_disparity);
}
int [][] tile_op = scan.tile_op;
double [][] disparity_array = scan.disparity;
// Should not happen !
if (scan.disparity == null) { // not used in lwir
System.out.println ("** BUG: should not happen - scan.disparity == null ! **");
System.out.println ("Trying to recover");
double [] backup_disparity = scan.getDisparity(0);
if (backup_disparity == null) {
System.out.println ("** BUG: no disparity at all !");
backup_disparity = new double[tilesX*tilesY];
}
scan.disparity = new double[tilesY][tilesX];
for (int ty = 0; ty < tilesY; ty++) {
for (int tx = 0; tx < tilesX; tx++) {
scan.disparity[ty][tx] = backup_disparity[ty*tilesX + tx];
if (Double.isNaN(scan.disparity[ty][tx])) {
scan.disparity[ty][tx] = 0;
tile_op[ty][tx] = 0;
}
}
}
disparity_array = scan.disparity;
}
if (debugLevel > -1){
int numTiles = 0;
for (int ty = 0; ty < tile_op.length; ty ++) for (int tx = 0; tx < tile_op[ty].length; tx ++){
if (tile_op[ty][tx] != 0) numTiles ++;
}
System.out.println("CLTMeasure("+scanIndex+"): numTiles = "+numTiles);
if ((dbg_y >= 0) && (dbg_x >= 0) && (tile_op[dbg_y][dbg_x] != 0)){
System.out.println("CLTMeasure("+scanIndex+"): tile_op["+dbg_y+"]["+dbg_x+"] = "+tile_op[dbg_y][dbg_x]);
}
}
double min_corr_selected = clt_parameters.min_corr;
double [][] shiftXY = new double [4][2];
if (!clt_parameters.fine_corr_ignore) {
double [][] shiftXY0 = {
{clt_parameters.fine_corr_x_0,clt_parameters.fine_corr_y_0},
{clt_parameters.fine_corr_x_1,clt_parameters.fine_corr_y_1},
{clt_parameters.fine_corr_x_2,clt_parameters.fine_corr_y_2},
{clt_parameters.fine_corr_x_3,clt_parameters.fine_corr_y_3}};
shiftXY = shiftXY0;
}
ImageDtt image_dtt = new ImageDtt(
clt_parameters.transform_size,
isMonochrome(),
isLwir(),
clt_parameters.getScaleStrength(isAux()),
gpuQuad);
double z_correction = clt_parameters.z_correction;
if (clt_parameters.z_corr_map.containsKey(image_name)){ // not used in lwir
z_correction +=clt_parameters.z_corr_map.get(image_name);
}
final double disparity_corr = (z_correction == 0) ? 0.0 : geometryCorrection.getDisparityFromZ(1.0/z_correction);
if (debugLevel > -5){
tp.showScan(
scan, // CLTPass3d scan,
"LY-combo_scan-"+scan+"_post"); //String title)
}
// use new, LMA-based mismatch calculation
double [][] lazy_eye_data = null;
if ((gpuQuad == null) || !(isAux()?clt_parameters.gpu_use_aux_adjust : clt_parameters.gpu_use_main_adjust)) { // CPU
lazy_eye_data = image_dtt.cltMeasureLazyEye ( // returns d,s lazy eye parameters
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
tile_op, // per-tile operation bit codes
disparity_array, // clt_parameters.disparity, // final double disparity,
image_data, // final double [][][] imade_data, // first index - number of image in a quad
saturation_imp, // boolean [][] saturation_imp, // (near) saturated pixels or null
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
null, // disparity_map, // [12][tp.tilesY * tp.tilesX]
tilesX * image_dtt.transform_size, // imp_quad[0].getWidth(), // final int width,
clt_parameters.getFatZero(isMonochrome()), // add to denominator to modify phase correlation (same units as data1, data2). <0 - pure sum
clt_parameters.corr_red,
clt_parameters.corr_blue,
clt_parameters.getCorrSigma(image_dtt.isMonochrome()),
min_corr_selected, // 0.0001; // minimal correlation value to consider valid
geometryCorrection, // final GeometryCorrection geometryCorrection,
null, // final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
clt_kernels, // final double [][][][][][] clt_kernels, // [channel_in_quad][color][tileY][tileX][band][pixel] , size should match image (have 1 tile around)
clt_parameters.kernel_step,
// image_dtt.transform_size,
clt_parameters.clt_window,
shiftXY, //
disparity_corr, // final double disparity_corr, // disparity at infinity
clt_parameters.shift_x, // final int shiftX, // shift image horizontally (positive - right) - just for testing
clt_parameters.shift_y, // final int shiftY, // shift image vertically (positive - down)
clt_parameters.tileStep, // final int tileStep, // process tileStep x tileStep cluster of tiles when adjusting lazy eye parameters
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
threadsMax,
debugLevel - 2);
} else {// GPU
// First - measure and get fcorr_td, fdisp_dist, fpxpy
float [][][][] fcorr_td = new float[tilesY][tilesX][][];
float [][][][] fdisp_dist = new float[tilesY][tilesX][][];
float [][][][] fpxpy = new float[tilesY][tilesX][][];
final double gpu_fat_zero = clt_parameters.getGpuFatZero(isMonochrome());
image_dtt.clt_aberrations_quad_corr_GPU( // USED in LWIR
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
1, // final int macro_scale, // to correlate tile data instead of the pixel data: 1 - pixels, 8 - tiles
tile_op, // per-tile operation bit codes
disparity_array, // clt_parameters.disparity, // final double disparity,
fcorr_td, // final float [][][][] corr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs
null, // 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
fdisp_dist, // final float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
fpxpy, // final float [][][][] fdisp_dist, // [tilesY][tilesX][cams][2], tile {pX,pY}
//// Uses quadCLT from gpuQuad
// correlation results - final and partial
null, // [type][tilesY][tilesX][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate
// [type][tilesY][tilesX] should be set by caller
// types: 0 - selected correlation (product+offset), 1 - sum
null, // 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, // 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
null, // disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do not calculate
// last 2 - contrast, avg/ "geometric average)
0, // disparity_modes, // disparity_modes, // bit mask of disparity_map slices to calculate/return
null, // final double [][][][] texture_tiles, // compatible with the CPU ones
null, // texture_img, // texture_img, // null or [3][] (RGB) or [4][] RGBA
null, // texture_woi, // texture_woi, // null or generated texture location/size
null, // iclt_fimg, // will return quad images or null to skip, use quadCLT.linearStackToColor
clt_parameters.gpu_corr_scale, //.gpu_corr_scale, // gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values
gpu_fat_zero, // final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0\
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;
(isMonochrome()? 1.0 : clt_parameters.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
image_dtt.transform_size - 1, // clt_parameters.gpu_corr_rad, // = transform_size - 1 ?
clt_parameters.corr_red, // +used
clt_parameters.corr_blue, // +used
clt_parameters.max_corr_radius,// 3.9;
clt_parameters.corr_mode, // Correlation mode: 0 - integer max, 1 - center of mass, 2 - polynomial
clt_parameters.min_shot, // 10.0; // Do not adjust for shot noise if lower than
clt_parameters.scale_shot, // 3.0; // scale when dividing by sqrt ( <0 - disable correction)
clt_parameters.diff_sigma, // 5.0;//RMS difference from average to reduce weights (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_threshold, // 5.0; // RMS difference from average to discard channel (~ 1.0 - 1/255 full scale image)
clt_parameters.diff_gauss, // true; // when averaging images, use gaussian around average as weight (false - sharp all/nothing)
clt_parameters.min_agree, // 3.0; // minimal number of channels to agree on a point (real number to work with fuzzy averages)
clt_parameters.dust_remove, // Do not reduce average weight when only one image differes much from the average
geometryCorrection, // final GeometryCorrection geometryCorrection,
null, // final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
clt_parameters.clt_window,
disparity_corr, // final double disparity_corr, // disparity at infinity
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
threadsMax,
debugLevel);
lazy_eye_data = image_dtt.cltMeasureLazyEyeGPU ( // returns d,s lazy eye parameters
clt_parameters.img_dtt, // final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others
disparity_array, // final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
fcorr_td, // final float [][][][] fcorr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr
fdisp_dist, // final float [][][][] fdisp_dist, // [tilesY][tilesX][cams][4], // disparity derivatives vectors or null
fpxpy, // final float [][][][] fpxpy, // [tilesY][tilesX][cams][2], tile {pX,pY}
clt_parameters.gpu_corr_scale, // gpu_corr_scale, // final double gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values
gpu_fat_zero, // final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0\
geometryCorrection, // final GeometryCorrection geometryCorrection,
null, // geometryCorrection_main, // final GeometryCorrection geometryCorrection_main, // if not null correct this camera (aux) to the coordinates of the main
disparity_corr, // final double disparity_corr, // disparity at infinity
clt_parameters.tileStep, // final int tileStep, // process tileStep x tileStep cluster of tiles when adjusting lazy eye parameters
clt_parameters.tileX, // final int debug_tileX,
clt_parameters.tileY, // final int debug_tileY,
threadsMax,
debugLevel);
}
scan.setLazyEyeData(lazy_eye_data);
scan.is_measured = true; // but no disparity map/textures
scan.is_combo = false;
scan.resetProcessed();
return scan;
}
}
......@@ -7403,17 +7403,37 @@ public class QuadCLTCPU {
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
"after_refinePassSetup-"+tp.clt_3d_passes.size());
// Just debugging
if (clt_parameters.gpu_debug_accum) {
CLTMeasureCorrTesting( // perform single pass according to prepared tiles operations and disparity
clt_parameters,
0,
false, // true, // final boolean save_textures,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
CLTMeasureCorrTesting( // perform single pass according to prepared tiles operations and disparity
clt_parameters,
refine_pass,
false, // true, // final boolean save_textures,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
}
// End of just debugging
CLTMeasureCorr( // perform single pass according to prepared tiles operations and disparity
// image_data, // first index - number of image in a quad
// saturation_imp, //final boolean [][] saturation_imp, // (near) saturated pixels or null
clt_parameters,
refine_pass,
false, // true, // final boolean save_textures,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
if (debugLevel > -1){
System.out.println("CLTMeasure("+refine_pass+")");
if (debugLevel > -3){
System.out.println("CLTMeasure("+refine_pass+")-*");
}
if (show_init_refine) tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
......@@ -7664,12 +7684,28 @@ public class QuadCLTCPU {
for (int nTile = 0 ; nTile < bg_use.length; nTile++) {
if (bg_sel[nTile] &&
(filtered_bgnd_disp_strength[1][nTile] > 0.0) &&
(bg_str[nTile] > clt_parameters.fcorr_inf_strength) &&
((bg_overexp == null) || (bg_overexp[nTile] < clt_parameters.lym_overexp))
(bg_str[nTile] > clt_parameters.fcorr_inf_strength) && // 0.13
((bg_overexp == null) || (bg_overexp[nTile] < clt_parameters.lym_overexp)) //1e-4
){
bg_use[nTile] = true;
}
}
if (true) {
String [] dbg_titles = {"fdisp", "fstr", "disp", "str", "overexp","sel","use"};
double [][] ddd = {filtered_bgnd_disp_strength[0],filtered_bgnd_disp_strength[1],null,bg_str,bg_overexp, null, null};
ddd[5] = new double [bg_sel.length];
ddd[6] = new double [bg_sel.length];
for (int nTile = 0 ; nTile < bg_use.length; nTile++) {
ddd[5][nTile] = bg_sel[nTile]?1.0:0.0;
ddd[6][nTile] = bg_use[nTile]?1.0:0.0;
}
(new ShowDoubleFloatArrays()).showArrays(
ddd,
tp.getTilesX(),
tp.getTilesY(),
true,
"filtered_bgnd_disp_strength",dbg_titles);
}
int num_bg = tp.clt_3d_passes.get(bg_scan).setTileOpDisparity( // other minimal strength?
bg_use, // boolean [] selection,
null); // double [] disparity); // null for 0
......@@ -7694,12 +7730,8 @@ public class QuadCLTCPU {
System.out.println("Number of background tiles = " + num_bg+", number of lazy eye tiles = " + num_combo);
}
// measure combo
CLTMeasure( // perform single pass according to prepared tiles operations and disparity
// image_data, // first index - number of image in a quad
// saturation_imp, // boolean [][] saturation_imp, // (near) saturated pixels or null
/*
CLTMeasure( // perform single pass according to prepared tiles operations and disparity **** CPU?
clt_parameters,
combo_scan,
false, // final boolean save_textures,
......@@ -7708,9 +7740,18 @@ public class QuadCLTCPU {
tp.threadsMax, // maximal number of threads to launch
false, // updateStatus,
debugLevelInner - 1);
if (!batch_mode && clt_parameters.show_extrinsic && (debugLevel >-1)) {
*/
CLTMeasureCorr( // perform single pass according to prepared tiles operations and disparity **** CPU?
clt_parameters,
combo_scan,
false, // final boolean save_textures,
tp.threadsMax, // maximal number of threads to launch
false, // updateStatus,
debugLevelInner - 1);
if (!batch_mode && clt_parameters.show_extrinsic && (debugLevel >-3)) {
tp.showScan(
tp.clt_3d_passes.get(bg_scan), // CLTPass3d scan,
tp.clt_3d_passes.get(bg_scan), // CLTPass3d scan, badly filtered?
"bg_scan_post"); //String title)
tp.showScan(
tp.clt_3d_passes.get(combo_scan), // CLTPass3d scan,
......@@ -7755,7 +7796,25 @@ public class QuadCLTCPU {
combo_use[nTile] = true;
}
}
int num_combo1 = tp.clt_3d_passes.get(combo_scan).setTileOpDisparity(
if (true) {
String [] dbg_titles = {"fdisp", "fstr", "disp", "str", "overexp","sel","use"};
double [][] ddd = {filtered_combo_scand_isp_strength[0],filtered_combo_scand_isp_strength[1],combo_disp,combo_str,combo_overexp, null, null};
ddd[5] = new double [combo_use.length];
ddd[6] = new double [combo_use.length];
for (int nTile = 0 ; nTile < combo_use.length; nTile++) {
//ddd[5][nTile] = bg_sel[nTile]?1.0:0.0;
ddd[6][nTile] = combo_use[nTile]?1.0:0.0;
}
(new ShowDoubleFloatArrays()).showArrays(
ddd,
tp.getTilesX(),
tp.getTilesY(),
true,
"filtered_combo_scand_isp_strength",dbg_titles);
}
int num_combo1 = tp.clt_3d_passes.get(combo_scan).setTileOpDisparity( // GPU ==0 !
combo_use, // boolean [] selection,
combo_disp); // double [] disparity);
if (debugLevel > -1) {
......@@ -7772,7 +7831,7 @@ public class QuadCLTCPU {
dbg_bg_use[i] = bg_use[i]? 1.0:0.0;
dbg_combo_use[i] = combo_use[i]? 1.0:0.0;
}
double [][]dbg_img = {
double [][]dbg_img = { // bg_use - all 0? (never assigned)?
filtered_bgnd_disp_strength[0],
filtered_bgnd_disp_strength[1],
filtered_combo_scand_isp_strength[0],
......@@ -7816,9 +7875,9 @@ public class QuadCLTCPU {
false, // updateStatus,
debugLevelInner -1); // - 1); // -5-1
if (debugLevel > -2) {
tp.showScan(
tp.clt_3d_passes.get(combo_scan), // CLTPass3d scan,
"LY_combo_scan-"+combo_scan+"_post"); //String title)
tp.showScan(
tp.clt_3d_passes.get(combo_scan), // CLTPass3d scan,
"LY_combo_scan-"+combo_scan+"_post"); //String title)
}
int tilesX = tp.getTilesX();
......@@ -7913,9 +7972,8 @@ public class QuadCLTCPU {
break;
}
if (update_disp_from_latest) {
/*
CLTMeasure( // perform single pass according to prepared tiles operations and disparity
// image_data, // first index - number of image in a quad
// saturation_imp, // boolean [][] saturation_imp, // (near) saturated pixels or null
clt_parameters,
combo_scan,
false, // final boolean save_textures,
......@@ -7924,14 +7982,20 @@ public class QuadCLTCPU {
tp.threadsMax, // maximal number of threads to launch
false, // updateStatus,
debugLevelInner - 1);
*/
CLTMeasureCorr( // perform single pass according to prepared tiles operations and disparity
clt_parameters,
combo_scan,
false, // final boolean save_textures,
tp.threadsMax, // maximal number of threads to launch
false, // updateStatus,
debugLevelInner - 1);
}
} else {
} else { // Old, no-GPU
double [][] bg_mismatch = new double[12][];
double [][] combo_mismatch = new double[12][];
CLTMeasure( // perform single pass according to prepared tiles operations and disparity
// image_data, // first index - number of image in a quad
// saturation_imp, // boolean [][] saturation_imp, // (near) saturated pixels or null
clt_parameters,
bg_scan,
false, // final boolean save_textures,
......@@ -7941,8 +8005,6 @@ public class QuadCLTCPU {
false, // updateStatus,
debugLevelInner - 1);
CLTMeasure( // perform single pass according to prepared tiles operations and disparity
// image_data, // first index - number of image in a quad
// saturation_imp, // boolean [][] saturation_imp, // (near) saturated pixels or null
clt_parameters,
combo_scan,
false, // final boolean save_textures,
......@@ -11317,4 +11379,21 @@ public class QuadCLTCPU {
}
scan.setTilesRBGA(tileTones);
}
// non-trivial in QuadCLT (for the GPU)
public CLTPass3d CLTMeasureCorrTesting( // perform single pass according to prepared tiles operations and disparity // not used in lwir
CLTParameters clt_parameters,
final int scanIndex,
final boolean save_textures,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
return CLTMeasureCorrTesting( // perform single pass according to prepared tiles operations and disparity // not used in lwir
clt_parameters,
scanIndex,
save_textures,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
}
}
......@@ -8315,7 +8315,6 @@ if (debugLevel > -100) return true; // temporarily !
}
}
/*
boolean ok = quadCLT_main.extrinsicsCLT(
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // adjust_poly,
......@@ -8325,8 +8324,6 @@ if (debugLevel > -100) return true; // temporarily !
// clear memory for main
quadCLT_main.tp.resetCLTPasses();
if (!ok) break;
*/
}
// Generate 4 main camera images and thumbnail
if (quadCLT_main.correctionsParameters.clt_batch_4img){
......
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