Commit db3deeef authored by Andrey Filippov's avatar Andrey Filippov

Developing dual-max LMA. Before simultaneous fitting

parent b9cc7d77
......@@ -547,7 +547,6 @@ public class Corr2dLMA {
}
}
// apply corrections
if (apply) {
for (int ncam = 0; ncam <num_cams; ncam++) {
......@@ -1636,7 +1635,28 @@ public class Corr2dLMA {
return xy_offsets;
}
/**
* Calculate offsets for multiple disparities, for each defined pair x,y expected offset, assuming only disparity, not lazy eye
* @param corrs - pairs 2D correlations (each in scanline order) - just to determine null/non-null
* @param disparity_strengths - expected {disparity, strength} pairs (e.g. from CM)
* @param disp_dist - per camera disparity matrix as a 1d (linescan order))
* @return array of per-disparity, per pair x,y expected center offset in 2D correlations or nulls for undefined pairs (or null if already set)
*/
public double [][][] getPairsOffsets(
double [][] corrs,
boolean [] pair_mask,
double [][] disparity_strengths,
double [][] disp_dist){ //
double [][][] pairs_offsets = new double [disparity_strengths.length][][];
for (int i = 0; i < pairs_offsets.length; i++) {
pairs_offsets[i] = getPairsOffsets(
corrs, // double [][] corrs,
pair_mask, // boolean [] pair_mask,
disparity_strengths[i][0], // double disparity,
disp_dist); // double [][] disp_dist)
}
return pairs_offsets;
}
public void printParams() { // not used in lwir
// to make sure it is updated
......@@ -2062,7 +2082,7 @@ public class Corr2dLMA {
double [][] maxmin_amp = getMaxMinAmpTile();
double [][] abc = getABCTile();
for (int tile = 0; tile < numTiles; tile++) {
ds[tile][0] = Double.NaN;
ds[tile][0] = Double.NaN + 0;
if (Double.isNaN(maxmin_amp[tile][0])) {
continue;
}
......
......@@ -4372,7 +4372,8 @@ public class Correlation2d {
public Corr2dLMA corrLMA2DualMax( // single tile
ImageDttParameters imgdtt_params,
boolean adjust_ly, // adjust Lazy Eye
int combine_mode, // 0 - both, 1 - strongest, 2 - nearest to zero, 3 - FG, 4 - BG
// boolean adjust_ly, // adjust Lazy Eye
double [][] corr_wnd, // correlation window to save on re-calculation of the window
double [] corr_wnd_inv_limited, // correlation window, limited not to be smaller than threshold - used for finding max/convex areas (or null)
double [][] corrs, // may have more elements than pair_mask (corrs may have combo as last elements)
......@@ -4389,15 +4390,25 @@ public class Correlation2d {
int tileY
)
{
// corrs are organized as PAIRS, some are null if not used
// for each enabled and available pair find a maximum, filter convex and create sample list
// boolean need_poly = (disp_str == null); // true; // find initial disparity by polynomial approximation
// double lpf_neib = 0.5; // if >0, add ortho neibs (corners - squared)
// double notch_pwr = 4.0; //calculating notch filter to suppress input data of the weaker maximum
// double adv_power = 2.0; // reduce weight from overlap with adversarial maximum
// int rad_convex_search = 2; // how far from predicted to search for maximums
// int min_num_samples = 4; // minimal number of samples per pair per maximum
// int min_num_pairs = 8; // minimal number of used pairs
boolean debug_graphic = imgdtt_params.lma_debug_graphic && (imgdtt_params.lma_debug_level1 > 3) && (debug_level > 0) ;
debug_graphic |= imgdtt_params.lmamask_dbg && (debug_level > 0);
debug_graphic |= imgdtt_params.lmamask_dbg && (debug_level > 0) ;
// TODO: Remove me
debug_graphic |= true;
/*
String dbg_title = null;
if (debug_graphic) {
dbg_title = String.format("tX%d_tY%d",tileX,tileY);
}
*/
double [][] dbg_corr = debug_graphic ? new double [corrs.length][] : null;
DoubleGaussianBlur gb = null;
if (imgdtt_params.lma_sigma > 0) gb = new DoubleGaussianBlur();
int center = transform_size - 1;
......@@ -4410,87 +4421,92 @@ public class Correlation2d {
rXY, //double [][] rXY, // non-distorted X,Y offset per nominal pixel of disparity
imgdtt_params.lmas_gaussian //boolean gaussian_mode
);
double [][] corr_shapes = new double [disp_str_dual.length][];
double [][] corr_shapes_dia = new double [disp_str_dual.length][];
double [][] norm_shapes = new double [disp_str_dual.length][];
double [][][] pair_shapes_masks = new double [disp_str_dual.length][][];
double [][][] pair_offsets = new double [disp_str_dual.length][][];
for (int nmax = 0; nmax < disp_str_dual.length; nmax++) {
pair_offsets[nmax] = lma.getPairsOffsets(
double [][][] pair_offsets0 = lma.getPairsOffsets(
corrs, // double [][] corrs,
pair_mask, // boolean [] pair_mask,
// disp_str_dual[nmax][0]/imgdtt_params.lmamask_magic, // double disparity,
/// disp_str_dual[nmax][0]/Math.sqrt(2), // *Math.sqrt(2), // double disparity,
// sqrt(2) moved to the caller
disp_str_dual[nmax][0], // *Math.sqrt(2), // double disparity,
disp_str_dual, // double [][] disparity_strengths,
disp_dist); // double [][] disp_dist);
corr_shapes[nmax] = getCorrShape(
corrs, // double [][] corrs,
pair_offsets[nmax]); // double [][] xy_offsets)
if (debug_graphic) {
int min_dia = 96;
double [][] corrs_dia = new double[corrs.length][];
for (int i = min_dia; i < corrs.length; i++) {
corrs_dia[i] = corrs[i];
}
corr_shapes_dia[nmax] = getCorrShape(
corrs_dia, // double [][] corrs,
pair_offsets[nmax]); // double [][] xy_offsets)
double [][][] own_masks0 = new double [pair_offsets0.length][][];
double [][][] lma_corr_weights0 = getLmaWeights(
imgdtt_params, // ImageDttParameters imgdtt_params,
lma, // Corr2dLMA lma,
imgdtt_params.bimax_lpf_neib, // double lpf_neib, // if >0, add ortho neibs (corners - squared)
imgdtt_params.bimax_notch_pwr, // double notch_pwr, // = 4.00;
imgdtt_params.bimax_adv_power, // double adv_power, // reduce weight from overlap with adversarial maximum
corrs, // double [][] corrs, // may have more elements than pair_mask (corrs may have combo as last elements)
disp_dist, // double [][] disp_dist, // per camera disparity matrix as a 1d (linescan order)
disp_dist, // double [][] rXY, // non-distorted X,Y offset per nominal pixel of disparity
pair_mask, // boolean [] pair_mask, // which pairs to process
pair_offsets0, // double [][][] pair_offsets,
own_masks0, // double [][][] own_masks, // individual per-maximum, per-pair masks regardless of adversaries or null
disp_str_dual, // double[][] disp_str_dual, // single or a pair of {disparity, strength} pairs. First is the strongest of two.
debug_level, // int debug_level,
tileX, // int tileX, // just for debug output
tileY); // int tileY
double [][][] lma_corr_weights;
double [][] disp_str_all;
double [][][] own_masks;
double [][][] pair_offsets;
if (lma_corr_weights0.length < 2) {
pair_offsets = pair_offsets0;
lma_corr_weights = lma_corr_weights0;
disp_str_all = disp_str_dual;
own_masks = own_masks0;
} else {
int nearest_max = (Math.abs(disp_str_dual[0][0]) < Math.abs(disp_str_dual[0][0]))? 0 : 1;
int fg_max = (disp_str_dual[0][0] > disp_str_dual[0][0]) ? 0 : 1;
switch (combine_mode) {
case 0: // keep both
pair_offsets = pair_offsets0;
lma_corr_weights = lma_corr_weights0;
disp_str_all = disp_str_dual;
own_masks = own_masks0;
break;
case 1: // keep strongest
pair_offsets = new double [][][] {pair_offsets0 [0]};
lma_corr_weights = new double [][][] {lma_corr_weights0[0]};
disp_str_all = new double [][] {disp_str_dual [0]};
own_masks = new double [][][] {own_masks0 [0]};
break;
case 2: // keep nearest
pair_offsets = new double [][][] {pair_offsets0 [nearest_max]};
lma_corr_weights = new double [][][] {lma_corr_weights0[nearest_max]};
disp_str_all = new double [][] {disp_str_dual [nearest_max]};
own_masks = new double [][][] {own_masks0 [nearest_max]};
break;
case 3: // keep foreground
pair_offsets = new double [][][] {pair_offsets0 [fg_max]};
lma_corr_weights = new double [][][] {lma_corr_weights0[fg_max]};
disp_str_all = new double [][] {disp_str_dual [fg_max]};
own_masks = new double [][][] {own_masks0 [fg_max]};
break;
case 4: // keep background
pair_offsets = new double [][][] {pair_offsets0 [1-fg_max]};
lma_corr_weights = new double [][][] {lma_corr_weights0[1-fg_max]};
disp_str_all = new double [][] {disp_str_dual [1-fg_max]};
own_masks = new double [][][] {own_masks0 [1-fg_max]};
break;
default: // keep both
pair_offsets = pair_offsets0;
lma_corr_weights = lma_corr_weights0;
disp_str_all = disp_str_dual;
own_masks = own_masks0;
}
norm_shapes[nmax] = conditionCorrShape(
corr_shapes[nmax], // double [] corrs_shape,
imgdtt_params.lmamask_min_main, // double min_main,
imgdtt_params.lmamask_min_neib, // double min_neib,
imgdtt_params.lmamask_weight_neib, // double weight_neib);
imgdtt_params.lmamask_weight_neib_neib); // double weight_neib_neib
pair_shapes_masks[nmax] = applyCorrShape(
norm_shapes[nmax], // double [] corrs_shape,
pair_offsets[nmax]); // double [][] xy_offsets)
}
double [][] dbg_corr = debug_graphic ? new double [corrs.length][] : null;
if (debug_graphic) {
(new ShowDoubleFloatArrays()).showArrays(
corrs,
corr_size,
corr_size,
true,
"corr_pairs"+"_x"+tileX+"_y"+tileY,
getCorrTitles());
if (corr_shapes != null) {
for (int nmax = 0; nmax < disp_str_dual.length; nmax++) {
(new ShowDoubleFloatArrays()).showArrays(
new double [][] {corr_shapes[nmax],norm_shapes[nmax], corr_shapes_dia[nmax]},
corr_size,
corr_size,
true,
"corr_shape"+"_x"+tileX+"_y"+tileY+"_M"+nmax,
new String [] {"corr_shape","norm_shape","corr_shape_dia"});
}
}
if (pair_shapes_masks != null) {
for (int nmax = 0; nmax < disp_str_dual.length; nmax++) {
(new ShowDoubleFloatArrays()).showArrays(
pair_shapes_masks[nmax],
corr_size,
corr_size,
true,
"corr_shape_masks"+"_x"+tileX+"_y"+tileY+"_M"+nmax,
getCorrTitles());
}
}
}
// try alternative mask generation by accumulation of the pre-shifted (from CM estimation with magic 0.85) correlations
/*
double [][] filtWeight = new double [corrs.length][];
double [][] samplesWeight = new double [corrs.length][];
double [][][] filtWeight = new double [lma_corr_weights.length][corrs.length][];
int num_disp_samples = 0;
int num_cnvx_samples = 0;
int num_comb_samples = 0;
int high_marg = corr_size - imgdtt_params.lma_soft_marg -1;
boolean [] used_pairs = pair_mask.clone();
int num_used_pairs = 0;
for (int npair = 0; npair < pair_mask.length; npair++) if ((corrs[npair] != null) && (pair_mask[npair])){
double [] corr_blur = null;
if (imgdtt_params.cnvx_en || (pair_shape_masks == null)) {
// if (npair == 65) {
// System.out.println("---npair == "+npair);
// }
if (imgdtt_params.cnvx_en) { // || (pair_shape_masks == null)) {
corr_blur = corrs[npair].clone();
if (corr_wnd_inv_limited != null) {
for (int i = 0; i < corr_blur.length; i++) {
......@@ -4500,19 +4516,31 @@ public class Correlation2d {
if (imgdtt_params.lma_sigma > 0) {
gb.blurDouble(corr_blur, corr_size, corr_size, imgdtt_params.lma_sigma, imgdtt_params.lma_sigma, 0.01);
}
int imx = imgdtt_params.lma_soft_marg * (corr_size + 1);
for (int iy = imgdtt_params.lma_soft_marg; iy < (corr_size - imgdtt_params.lma_soft_marg); iy++) {
for (int ix = imgdtt_params.lma_soft_marg; ix < (corr_size - imgdtt_params.lma_soft_marg); ix++) {
if (dbg_corr != null) {
dbg_corr[npair] = corr_blur;
}
for (int nmax = 0; nmax < lma_corr_weights.length; nmax++) { // use same blurred version for all max-es
int x00 = (int) Math.round(pair_offsets[nmax][npair][0])+center;
int y00 = (int) Math.round(pair_offsets[nmax][npair][1])+center;
int x_min = Math.max (x00 - imgdtt_params.bimax_rad_convex_search,imgdtt_params.lma_soft_marg);
int x_max = Math.min(x00 + imgdtt_params.bimax_rad_convex_search , high_marg);
int y_min = Math.max (y00 - imgdtt_params.bimax_rad_convex_search,imgdtt_params.lma_soft_marg);
int y_max = Math.min(y00 + imgdtt_params.bimax_rad_convex_search, high_marg);
int imx = x_min + y_min * corr_size;
double [] own_mask = own_masks[nmax][npair];
for (int iy = y_min; iy <= y_max; iy++) {
for (int ix = x_min; ix <= x_max; ix++) {
int indx = iy * corr_size + ix;
if (corr_blur[indx] > corr_blur[imx]) imx = indx;
if (corr_blur[indx] * own_mask[indx] > corr_blur[imx] * own_mask[imx]) {
imx = indx;
}
}
}
// filter convex
int ix0 = (imx % corr_size) - center; // signed, around center to match filterConvex
int iy0 = (imx / corr_size) - center; // signed, around center to match filterConvex
filtWeight[npair] = filterConvex(
filtWeight[nmax][npair] = filterConvex(
corr_blur, // double [] corr_data,
imgdtt_params.cnvx_hwnd_size, // int hwin,
ix0, // int x0,
......@@ -4520,46 +4548,37 @@ public class Correlation2d {
imgdtt_params.cnvx_add3x3, // boolean add3x3,
imgdtt_params.cnvx_weight, // double nc_cost,
(debug_level > 2)); // boolean debug);
}
if (dbg_corr != null) dbg_corr [npair] = corr_blur;
// Normalize weight for each pair to compensate for different number of convex samples?
// Combine/use window masks
if (filtWeight[npair] == null) {
samplesWeight[npair] = (pair_shape_masks != null)? pair_shape_masks[npair] : null;
} else if ((pair_shape_masks == null) || (pair_shape_masks[npair] == null) || !imgdtt_params.lmamask_en) {
samplesWeight[npair] = filtWeight[npair];
} else {
samplesWeight[npair] = filtWeight[npair].clone();
if (imgdtt_params.cnvx_or) {
for (int i = 0; i < samplesWeight[npair].length; i++) {
samplesWeight[npair][i] = Math.max(samplesWeight[npair][i], pair_shape_masks[npair][i]);
for (int i = 0; i < filtWeight[nmax][npair].length; i++){
lma_corr_weights[nmax][npair][i] *= filtWeight[nmax][npair][i];
}
} else {
for (int i = 0; i < samplesWeight[npair].length; i++) {
samplesWeight[npair][i] *= pair_shape_masks[npair][i];
}
}
used_pairs[npair] = true;
for (int nmax = 0; nmax < lma_corr_weights.length; nmax++) { // use same blurred version for all max-es
int num_pair_samples = 0;
for (int i = 0; i < lma_corr_weights[nmax][npair].length; i++) if (lma_corr_weights[nmax][npair][i] > 0.0) {
num_pair_samples++;
}
if (debug_lma_tile != null) { // calculate and return number of non-zero tiles
if (pair_shape_masks[npair] != null) {
for (int i = 0; i < samplesWeight[npair].length; i++) if (samplesWeight[npair][i] > 0.0) num_disp_samples++;
if (num_pair_samples < imgdtt_params.bimax_min_num_samples) {
lma_corr_weights[nmax][npair] = null;
used_pairs[npair] = false;
}
if (filtWeight[npair] != null) {
for (int i = 0; i < filtWeight[npair].length; i++) if (filtWeight[npair][i] > 0.0) num_cnvx_samples++;
}
if (samplesWeight[npair] != null) {
for (int i = 0; i < samplesWeight[npair].length; i++) if (samplesWeight[npair][i] > 0.0) num_comb_samples++;
if (used_pairs[npair]) {
num_used_pairs++;
}
}
for (int i = 1; i < samplesWeight[npair].length; i++) if (samplesWeight[npair][i] > 0.0) {
if (num_used_pairs < imgdtt_params.bimax_min_num_pairs) {
return null;
}
for (int npair = 0; npair < pair_mask.length; npair++) if ((corrs[npair] != null) && (used_pairs[npair])){
for (int nmax = 0; nmax < lma_corr_weights.length; nmax++) { // use same blurred version for all max-es
for (int i = 1; i < lma_corr_weights[nmax][npair].length; i++) if (lma_corr_weights[nmax][npair][i] > 0.0) {
int ix = i % corr_size; // >=0
int iy = i / corr_size; // >=0
double v = corrs[npair][i]; // not blurred
double w = samplesWeight[npair][i];
double w = lma_corr_weights[nmax][npair][i];
if (vasw_pwr != 0) {
w *= Math.pow(Math.abs(v), vasw_pwr);
}
......@@ -4573,6 +4592,9 @@ public class Correlation2d {
}
}
}
// Just debug - modify/restore
if (debug_lma_tile != null) { // calculate and return number of non-zero tiles
debug_lma_tile[0] = num_disp_samples;
debug_lma_tile[1] = num_cnvx_samples;
......@@ -4591,18 +4613,21 @@ public class Correlation2d {
"corr_blurred"+"_x"+tileX+"_y"+tileY,
getCorrTitles());
}
if (filtWeight != null) {
for (int nmax = 0; nmax < filtWeight.length; nmax++) {
if (filtWeight[nmax] != null) {
(new ShowDoubleFloatArrays()).showArrays(
filtWeight,
filtWeight[nmax],
corr_size,
corr_size,
true,
"filt_weight"+"_x"+tileX+"_y"+tileY,
"filt_weight"+"_x"+tileX+"_y"+tileY+"_n"+nmax,
getCorrTitles());
}
if (samplesWeight != null) {
}
for (int nmax = 0; nmax < lma_corr_weights.length; nmax++) {
if (lma_corr_weights[nmax] != null) {
(new ShowDoubleFloatArrays()).showArrays(
samplesWeight,
lma_corr_weights[nmax],
corr_size,
corr_size,
true,
......@@ -4610,24 +4635,12 @@ public class Correlation2d {
getCorrTitles());
}
}
// double [][] disp_str = {{xcenter, 1.0}}; // temporary
double [][] disp_str2 = {{0.0, 1.0}}; // temporary // will be calculated/set later
if (disp_str != null) {
disp_str2[0] = disp_str;
}
// initially will use just first (selected) maximum, both - whenLMA will be modified to support 3 maximums.
double [][] disp_str2 = {disp_str_all[0]}; // temporary // will be calculated/set later
boolean lmaSuccess = false;
int num_lma_retries = 0;
double [] disp = null;
// adjust_ly
double [][] ly_offsets_pairs = null;
if (adjust_ly) {
ly_offsets_pairs = getPairsCenters(
corrs, // double [][] corrs,
samplesWeight); // double [][] weights)
}
double step_weight = 0.5; // scale corrections
double min_correction = 0.1; // exit when maximal XY correction is below
while (!lmaSuccess) {
num_lma_retries ++; // debug
......@@ -4635,70 +4648,16 @@ public class Correlation2d {
imgdtt_params.lmas_adjust_wm, // boolean adjust_width, // adjust width of the maximum - lma_adjust_wm
imgdtt_params.lmas_adjust_ag, // boolean adjust_scales, // adjust 2D correlation scales - lma_adjust_ag
imgdtt_params.lmas_adjust_wy, // boolean adjust_ellipse, // allow non-circular correlation maximums lma_adjust_wy
(adjust_ly ? imgdtt_params.lma_adjust_wxy : false), //imgdtt_params.lma_adjust_wxy, // boolean adjust_lazyeye_par, // adjust disparity corrections parallel to disparities lma_adjust_wxy
(adjust_ly ? imgdtt_params.lma_adjust_ly1: false), // imgdtt_params.lma_adjust_ly1, // boolean adjust_lazyeye_ortho, // adjust disparity corrections orthogonal to disparities lma_adjust_ly1
false, // (adjust_ly ? imgdtt_params.lma_adjust_wxy : false), //imgdtt_params.lma_adjust_wxy, // boolean adjust_lazyeye_par, // adjust disparity corrections parallel to disparities lma_adjust_wxy
false, // (adjust_ly ? imgdtt_params.lma_adjust_ly1: false), // imgdtt_params.lma_adjust_ly1, // boolean adjust_lazyeye_ortho, // adjust disparity corrections orthogonal to disparities lma_adjust_ly1
disp_str2, // xcenter,
imgdtt_params.lma_half_width, // double half_width, // A=1/(half_widh)^2 lma_half_width
(adjust_ly ? imgdtt_params.lma_cost_wy : 0.0), // imgdtt_params.lma_cost_wy, // double cost_lazyeye_par, // cost for each of the non-zero disparity corrections lma_cost_wy
(adjust_ly ? imgdtt_params.lma_cost_wxy : 0.0) //imgdtt_params.lma_cost_wxy // double cost_lazyeye_odtho // cost for each of the non-zero ortho disparity corrections lma_cost_wxy
0.0, // (adjust_ly ? imgdtt_params.lma_cost_wy : 0.0), // imgdtt_params.lma_cost_wy, // double cost_lazyeye_par, // cost for each of the non-zero disparity corrections lma_cost_wy
0.0 // (adjust_ly ? imgdtt_params.lma_cost_wxy : 0.0) //imgdtt_params.lma_cost_wxy // double cost_lazyeye_odtho // cost for each of the non-zero ortho disparity corrections lma_cost_wxy
);
lma.setMatrices(disp_dist);
lma.initMatrices(); // should be called after initVector and after setMatrices
boolean all_sensors_used = lma.setInitialLYOffsets(
ly_offsets_pairs, // double [][] pair_centers,
step_weight, // double step_weight, // scale corrections
min_correction, // double min_correction ){ // exit when maximal XY correction is below
(debug_level > 0)); //
if (adjust_ly && !all_sensors_used) {
return null; //LY requested, but not all sensors present
}
//center
disp = null;
if (need_poly) {
disp = lma.polyDisparity(
corr_wnd_inv_limited,
transform_size-1-imgdtt_params.lma_soft_marg,//double max_offset, // 5?
debug_graphic?dbg_title:null); // double [] rslt = {-approx2d[0], approx2d[2], hwx, hwy};
if (disp == null) {
if (imgdtt_params.lmas_poly_continue && (disp == null)) {
disp = disp_str2[0];
if (debug_level > 0) {
System.out.println("Poly disparity=NULL, using tile center for initial LMA");
}
} else {
if (debug_level > 0) {
System.out.println("Poly disparity=NULL, set lmas_poly_continue to true to use tile center instead");
}
}
} else {
disp[1] *= imgdtt_params.lmas_poly_str_scale;
if (debug_level > 0) {
System.out.println(String.format("Poly disparity=%8.5f , str=%8.5f, disp_str2[0][0]=%8.5f, disp_str2[0][1]=%8.5f",
disp[0],disp[1],disp_str2[0][0],disp_str2[0][1]));
}
if (disp[1] < imgdtt_params.lmas_poly_str_min) {
if (debug_level > 0) {
System.out.println("Poly strength too low ("+disp[1]+" < "+imgdtt_params.lmas_poly_str_min+")");
}
disp = null;
}
}
// double[] poly_ds, // null or pair of disparity/strength
if (poly_ds != null) {
poly_ds[0] = (disp==null) ? Double.NaN: disp[0];
poly_ds[1] = (disp==null) ? 0.0: disp[1];
}
} else {
disp = disp_str;
}
if (disp != null) {
disp_str2[0] = disp;
lma.initDisparity( // USED in lwir null pointer
disp_str2); // double [][] disp_str // initial value of disparity
......@@ -4723,17 +4682,10 @@ public class Correlation2d {
} else {
break;
}
} else {
break;
}
}
if (lmaSuccess) {
lma.updateFromVector();
double [][] dispStr = lma.lmaDisparityStrength( //TODO: add parameter to filter out negative minimums ?
imgdtt_params.lmas_min_amp, // minimal ratio of minimal pair correlation amplitude to maximal pair correlation amplitude
imgdtt_params.lmas_max_rel_rms, // maximal relative (to average max/min amplitude LMA RMS) // May be up to 0.3)
......@@ -4746,20 +4698,15 @@ public class Correlation2d {
);
if (dispStr[0][1] <= 0) {
lmaSuccess = false;
if (debug_level > -2) { // 0
System.out.println(String.format("Poly disparity=%8.5f , str=%8.5f", disp[0],disp[1]));
}
if (debug_lma_tile != null) {
debug_lma_tile[3] = num_lma_retries; // number of wasted attempts
debug_lma_tile[4] = lma.getNumIter();
}
} else {
if (debug_level > -2) {
System.out.println(String.format("Poly disparity=%8.5f , str=%8.5f, LMA disparity=%8.5f, str=%8.5f",
disp[0],disp[1],dispStr[0][0],dispStr[0][1]));
System.out.println(String.format("LMA disparity=%8.5f, str=%8.5f",
dispStr[0][0],dispStr[0][1]));
}
// System.out.println("dispStr[0][0]="+dispStr[0][0]+" dispStr[0][1]="+dispStr[0][1]);
double [] rms = lma.getRMS();
if (debug_lma_tile != null) {
debug_lma_tile[3] = num_lma_retries; // number of wasted attempts
......@@ -4776,10 +4723,8 @@ public class Correlation2d {
System.out.println("Input data and approximation:");
lma.printInputDataFx(true);
}
// double [][] ds = null;
if (debug_graphic && lmaSuccess) {
String [] sliceTitles = lma.dbgGetSliceTitles();
// if (corrs.length == 1) { // only for single-tile cluster (here it is always single, and corrs is double [][], not double [][][]
(new ShowDoubleFloatArrays()).showArrays(
lma.dbgGetSamples(null,0)[0],
corr_size,
......@@ -4798,7 +4743,6 @@ public class Correlation2d {
corr_size,
true,
"corr_weights_late"+"_x"+tileX+"_y"+tileY, sliceTitles);
// }
}
}
......@@ -4806,10 +4750,233 @@ public class Correlation2d {
debug_lma_tile[3] = num_lma_retries; // number of wasted attempts
}
return lmaSuccess? lma: null;
*/
return null;
}
void lpf_neib(
double [] data,
double orth_val) {
double scale = 1.0/(1.0 + 4 * orth_val * (1.0 + orth_val));
int [] ortho = {-1, - corr_size, 1, corr_size};
int [] corners = {- corr_size - 1, - corr_size + 1, corr_size -1, corr_size + 1};
double [] scales = {scale, scale*orth_val, scale * orth_val * orth_val}; // center, ortho,corner
double [] d = data.clone();
Arrays.fill(data, 0.0);
int i_last = data.length - corr_size - 1;
for (int i = corr_size+1; i < i_last; i++) { // assuming nothing in a 1-pixel frame
if (d[i] != 0.0) {
data[i] += d[i] * scales[0];
double a = d[i]* scales[1];
for (int offs:ortho) {
data[i+offs] += a;
}
a = d[i]* scales[2];
for (int offs:corners) {
data[i+offs] += a;
}
}
}
}
public double[][][] getLmaWeights(
ImageDttParameters imgdtt_params,
Corr2dLMA lma,
double lpf_neib, // if >0, add ortho neibs (corners - squared)
double notch_pwr, // = 4.00;
double adv_power, // reduce weight from overlap with adversarial maximum
double [][] corrs, // may have more elements than pair_mask (corrs may have combo as last elements)
double [][] disp_dist, // per camera disparity matrix as a 1d (linescan order)
double [][] rXY, // non-distorted X,Y offset per nominal pixel of disparity
boolean [] pair_mask, // which pairs to process
double [][][] pair_offsets,
double [][][] own_masks, // individual per-maximum, per-pair masks regardless of adversaries or null
double[][] disp_str_dual, // single or a pair of {disparity, strength} pairs. First is the strongest of two.
int debug_level,
int tileX, // just for debug output
int tileY){
boolean debug_graphic = imgdtt_params.lma_debug_graphic && (imgdtt_params.lma_debug_level1 > 3) && (debug_level > 0) ;
debug_graphic |= imgdtt_params.lmamask_dbg && (debug_level > 0) || true;
String dbg_title = null;
if (debug_graphic) {
dbg_title = String.format("tX%d_tY%d",tileX,tileY);
}
double [][] corr_shapes = new double [disp_str_dual.length][];
double [][] corr_shapes_dia = new double [disp_str_dual.length][];
double [][] norm_shapes = new double [disp_str_dual.length][];
double [][] corr_sharps = new double [disp_str_dual.length][]; // combination of corr_shapes and norm_shapes
double [][][] pair_shapes_masks = new double [disp_str_dual.length][][];
double [][][] pair_sharp_masks = new double [disp_str_dual.length][][];
boolean is_multi = disp_str_dual.length > 1;
double [][] notch = is_multi ? (new double [corrs.length][]) : null;
double [][] corrs_notched;
double [] notch_shape = null;
for (int nmax = 0; nmax < disp_str_dual.length; nmax++) {
if (is_multi && (nmax > 0)) {
corrs_notched = new double[notch.length][];
for (int nt = 0; nt < notch.length; nt++) {
if (corrs[nt] != null) {
if (notch[nt] != null) {
corrs_notched[nt] = corrs[nt].clone();
for (int i = 0; i < notch[nt].length; i++) {
corrs_notched[nt][i] *= notch[nt][i];
}
} else {
corrs_notched[nt] = corrs[nt];
}
}
}
} else {
corrs_notched = corrs;
}
corr_shapes[nmax] = getCorrShape(
corrs_notched, // double [][] corrs,
pair_offsets[nmax]); // double [][] xy_offsets)
if (debug_graphic) {
int min_dia = 96;
double [][] corrs_dia = new double[corrs.length][];
for (int i = min_dia; i < corrs.length; i++) {
corrs_dia[i] = corrs[i];
}
corr_shapes_dia[nmax] = getCorrShape(
corrs_dia, // double [][] corrs,
pair_offsets[nmax]); // double [][] xy_offsets)
}
norm_shapes[nmax] = conditionCorrShape(
corr_shapes[nmax], // double [] corrs_shape,
imgdtt_params.lmamask_min_main, // double min_main,
imgdtt_params.lmamask_min_neib, // double min_neib,
imgdtt_params.lmamask_weight_neib, // double weight_neib);
imgdtt_params.lmamask_weight_neib_neib); // double weight_neib_neib
pair_shapes_masks[nmax] = applyCorrShape(
norm_shapes[nmax], // double [] corrs_shape,
pair_offsets[nmax]); // double [][] xy_offsets)
// multiply shape and norm_shape and normalize
corr_sharps[nmax] = new double [norm_shapes[nmax].length];
for (int i = 0; i < corr_sharps[nmax].length; i++) if (norm_shapes[nmax][i] > 0.0){
corr_sharps[nmax][i] = norm_shapes[nmax][i] * Math.abs(corr_shapes[nmax][i]); // abs() as we are interested in adversarial influence
}
if (lpf_neib > 0) { // lpf filter
lpf_neib(
corr_sharps[nmax], // double [] data,
lpf_neib); // double orth_val)
for (int i = 0; i < corr_sharps[nmax].length; i++) if ( norm_shapes[nmax][i] <= 0.0){
corr_sharps[nmax][i] = 0.0; // remove possible roll-overs in a first/last line
}
}
double dmax = 0.0;
for (int i = 0; i < corr_sharps[nmax].length; i++) if (norm_shapes[nmax][i] > 0.0){
if (corr_sharps[nmax][i] > dmax) {
dmax = corr_sharps[nmax][i];
}
}
for (int i = 0; i < corr_sharps[nmax].length; i++){
corr_sharps[nmax][i]/= dmax;
}
pair_sharp_masks[nmax]= applyCorrShape(
corr_sharps[nmax], // double [] corrs_shape,
pair_offsets[nmax]); // double [][] xy_offsets)
// FIXME: Some duplicate below - use corr_sharps[nmax]
if (is_multi && (nmax == 0)) {
// notch_shape = corr_shapes[0].clone();
notch_shape = new double [corr_shapes[0].length];
for (int i = 0; i < notch_shape.length; i++) {
if (corr_sharps[nmax][i] <= 0.0) {
notch_shape[i] = 1.0;
} else {
// notch_shape[i] = Math.pow(( 1.0 - notch_shape[i] / dmax * norm_shapes[0][i]), notch_pwr);
notch_shape[i] = Math.pow( 1.0 - corr_sharps[nmax][i], notch_pwr);
}
}
notch = applyCorrShape(
notch_shape, // double [] corrs_shape,
pair_offsets[0]); // double [][] xy_offsets)
}
}
// Apply adversarial selections. Only two maximums are considered here
if (disp_str_dual.length == 2) {
for (int nmax = 0; nmax < 2; nmax ++) {
double over_avd_scale = disp_str_dual[nmax][1] / disp_str_dual[1 - nmax][1];
for (int npair = 0; npair < pair_shapes_masks[nmax].length; npair++) {
if ((pair_shapes_masks[nmax][npair] != null) && (pair_sharp_masks[nmax][npair] != null) && (pair_sharp_masks[1-nmax][npair] != null)) {
for (int i = 0; i < pair_shapes_masks[nmax][npair].length; i++) if (pair_shapes_masks[nmax][npair][i] > 0.0){
if (pair_sharp_masks[1 - nmax][npair][i] > 0.0) { // adversary exists here
double relative_strength = over_avd_scale *
pair_sharp_masks[nmax][npair][i] /
pair_sharp_masks[1 - nmax][npair][i];
double scale = relative_strength / (1.0 + relative_strength);
if (adv_power != 1.0) {
scale = Math.pow(scale, adv_power);
pair_shapes_masks[nmax][npair][i] *= scale;
}
}
}
}
}
}
}
if (debug_graphic) {
(new ShowDoubleFloatArrays()).showArrays(
corrs,
corr_size,
corr_size,
true,
"corr_pairs"+"_x"+tileX+"_y"+tileY,
getCorrTitles());
if (corr_shapes != null) {
for (int nmax = 0; nmax < disp_str_dual.length; nmax++) {
(new ShowDoubleFloatArrays()).showArrays(
new double [][] {corr_shapes[nmax],corr_sharps[nmax], norm_shapes[nmax], corr_shapes_dia[nmax],notch_shape},
corr_size,
corr_size,
true,
"corr_shape"+"_x"+tileX+"_y"+tileY+"_M"+nmax,
new String [] {"corr_shape","corr_sharp","norm_shape","corr_shape_dia","notch_shape"});
}
}
// if (pair_shapes_masks != null) {
for (int nmax = 0; nmax < disp_str_dual.length; nmax++) {
(new ShowDoubleFloatArrays()).showArrays(
pair_shapes_masks[nmax],
corr_size,
corr_size,
true,
"corr_shape_masks"+"_x"+tileX+"_y"+tileY+"_M"+nmax,
getCorrTitles());
}
for (int nmax = 0; nmax < disp_str_dual.length; nmax++) {
(new ShowDoubleFloatArrays()).showArrays(
pair_sharp_masks[nmax],
corr_size,
corr_size,
true,
"pair_sharp_masks"+"_x"+tileX+"_y"+tileY+"_M"+nmax,
getCorrTitles());
}
if (notch != null) {
(new ShowDoubleFloatArrays()).showArrays(
notch,
corr_size,
corr_size,
true,
"notch"+"_x"+tileX+"_y"+tileY,
getCorrTitles());
}
}
if (own_masks != null) {
for (int nmax = 0; nmax < own_masks.length; nmax++) {
own_masks[nmax] = pair_sharp_masks[nmax];
}
}
return pair_shapes_masks;
}
/**
* Condition correlation shape to use as a mask
* @param corrs_shape raw centered correlation shape calculated with getCorrShape()
......
......@@ -2631,7 +2631,8 @@ public class ImageDtt extends ImageDttCPU {
if (debugTile1) {
correlation2d.corrLMA2DualMax( // null pointer
imgdtt_params, // ImageDttParameters imgdtt_params,
imgdtt_params.lmas_LY_single, // false, // boolean adjust_ly, // adjust Lazy Eye
1, // int combine_mode, // 0 - both, 1 - strongest, 2 - nearest to zero, 3 - FG, 4 - BG
// imgdtt_params.lmas_LY_single, // false, // boolean adjust_ly, // adjust Lazy Eye
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, // corrs, // double [][] corrs,
......@@ -2644,7 +2645,6 @@ public class ImageDtt extends ImageDttCPU {
imgdtt_params.ortho_vasw_pwr, // double vasw_pwr, // value as weight to this power,
null, // debug_lma_tile, // double [] debug_lma_tile,
(debugTile0 ? 1: -2), // int debug_level,
// -2, //0, // tile_lma_debug_level, // +2, // int debug_level,
tileX, // int tileX, // just for debug output
tileY );
......
......@@ -77,6 +77,14 @@ public class ImageDttParameters {
public int dbg_pair_mask = 0x3f; // which pairs to combine
public int corr_strip_hight = 9; // number of rows to calculate
//bimax_
public double bimax_lpf_neib = 0.5; // if >0, add ortho neibs (corners - squared)
public double bimax_notch_pwr = 4.0; // calculating notch filter to suppress input data of the weaker maximum
public double bimax_adv_power = 2.0; // reduce weight from overlap with adversarial maximum
public int bimax_rad_convex_search = 2; // how far from predicted to search for maximums
public int bimax_min_num_samples = 4; // minimal number of samples per pair per maximum
public int bimax_min_num_pairs = 8; // minimal number of used pairs
//lmamask_
public boolean lmamask_dbg = false; // show LMA images, exit after single BG
public boolean lmamask_en = false; // Use disparity-based LMA samples filter
......@@ -450,6 +458,21 @@ public class ImageDttParameters {
gd.addNumericField("Number of correlation rows to combine (strip height)", this.corr_strip_hight, 0, 3, "",
"Number of rows to combine/interpolate correlation results. Rows are twice denser than pixels correponding to largest baseline disparity");
gd.addMessage("LMA prefiltering for dual disparities in a tile");
gd.addNumericField("LPF for combined maximums", this.bimax_lpf_neib, 6,8,"",
"0 - no LPF, >0 - add 4 scaled ortho neighbors and 4 corners bscaled as square of this value");
gd.addNumericField("Notch filter power", this.bimax_notch_pwr, 6,8,"",
"Reduce offending (other) correlation maximum by multiplying. High power reduces all < 1.0 values");
gd.addNumericField("Reduction of sample weight by the other maximum", this.bimax_adv_power, 6,8,"",
"If X= (this strength /other strength), scale by X/(1+X) to theis power");
gd.addNumericField("Convex max search around predicted disparity", this.bimax_rad_convex_search, 0, 3, "",
"How far from predicted to search for maximums");
gd.addNumericField("Minimal samples per pair per max", this.bimax_min_num_samples, 0, 3, "",
"Minimal number of samples per pair per maximum to use this pair by LMA (each of the maximums used)");
gd.addNumericField("Minimal number of used pairs", this.bimax_min_num_pairs, 0, 3, "",
"Do not use LMA if total number of used pairs is lower");
gd.addMessage("LMA samples filter based on estimated disparity");
gd.addCheckbox ("Debug LMA", this.lmamask_dbg,
"Generate debug images and exit after first clt_process_tl_correlations() while generating background image");
......@@ -859,6 +882,13 @@ public class ImageDttParameters {
this.dbg_pair_mask= (int) gd.getNextNumber();
this.corr_strip_hight= (int) gd.getNextNumber();
this.bimax_lpf_neib = gd.getNextNumber();
this.bimax_notch_pwr = gd.getNextNumber();
this.bimax_adv_power = gd.getNextNumber();
this.bimax_rad_convex_search= (int) gd.getNextNumber();
this.bimax_min_num_samples= (int) gd.getNextNumber();
this.bimax_min_num_pairs= (int) gd.getNextNumber();
this.lmamask_dbg = gd.getNextBoolean();
this.lmamask_en = gd.getNextBoolean();
this.lmamask_magic = gd.getNextNumber();
......@@ -1078,6 +1108,13 @@ public class ImageDttParameters {
properties.setProperty(prefix+"dbg_pair_mask", this.dbg_pair_mask +"");
properties.setProperty(prefix+"corr_strip_hight", this.corr_strip_hight +"");
properties.setProperty(prefix+"bimax_lpf_neib", this.bimax_lpf_neib +"");
properties.setProperty(prefix+"bimax_notch_pwr", this.bimax_notch_pwr +"");
properties.setProperty(prefix+"bimax_adv_power", this.bimax_adv_power +"");
properties.setProperty(prefix+"bimax_rad_convex_search", this.bimax_rad_convex_search +"");
properties.setProperty(prefix+"bimax_min_num_samples", this.bimax_min_num_samples +"");
properties.setProperty(prefix+"bimax_min_num_pairs", this.bimax_min_num_pairs +"");
properties.setProperty(prefix+"lmamask_dbg", this.lmamask_dbg +"");
properties.setProperty(prefix+"lmamask_en", this.lmamask_en +"");
properties.setProperty(prefix+"lmamask_magic", this.lmamask_magic +"");
......@@ -1301,6 +1338,12 @@ public class ImageDttParameters {
if (properties.getProperty(prefix+"dbg_pair_mask")!=null) this.dbg_pair_mask=Integer.parseInt(properties.getProperty(prefix+"dbg_pair_mask"));
if (properties.getProperty(prefix+"corr_strip_hight")!=null) this.corr_strip_hight=Integer.parseInt(properties.getProperty(prefix+"corr_strip_hight"));
if (properties.getProperty(prefix+"bimax_lpf_neib")!=null) this.bimax_lpf_neib=Double.parseDouble(properties.getProperty(prefix+"bimax_lpf_neib"));
if (properties.getProperty(prefix+"bimax_notch_pwr")!=null) this.bimax_notch_pwr=Double.parseDouble(properties.getProperty(prefix+"bimax_notch_pwr"));
if (properties.getProperty(prefix+"bimax_adv_power")!=null) this.bimax_adv_power=Double.parseDouble(properties.getProperty(prefix+"bimax_adv_power"));
if (properties.getProperty(prefix+"bimax_rad_convex_search")!=null) this.bimax_rad_convex_search=Integer.parseInt(properties.getProperty(prefix+"bimax_rad_convex_search"));
if (properties.getProperty(prefix+"bimax_min_num_samples")!=null) this.bimax_min_num_samples=Integer.parseInt(properties.getProperty(prefix+"bimax_min_num_samples"));
if (properties.getProperty(prefix+"bimax_min_num_pairs")!=null) this.bimax_min_num_pairs=Integer.parseInt(properties.getProperty(prefix+"bimax_min_num_pairs"));
if (properties.getProperty(prefix+"lmamask_dbg")!=null) this.lmamask_dbg=Boolean.parseBoolean(properties.getProperty(prefix+"lmamask_dbg"));
if (properties.getProperty(prefix+"lmamask_en")!=null) this.lmamask_en=Boolean.parseBoolean(properties.getProperty(prefix+"lmamask_en"));
......@@ -1542,6 +1585,13 @@ public class ImageDttParameters {
idp.dbg_pair_mask= this.dbg_pair_mask;
idp.corr_strip_hight= this.corr_strip_hight;
idp.bimax_lpf_neib= this.bimax_lpf_neib;
idp.bimax_notch_pwr= this.bimax_notch_pwr;
idp.bimax_adv_power= this.bimax_adv_power;
idp.bimax_rad_convex_search= this.bimax_rad_convex_search;
idp.bimax_min_num_samples= this.bimax_min_num_samples;
idp.bimax_min_num_pairs= this.bimax_min_num_pairs;
idp.lmamask_dbg= this.lmamask_dbg;
idp.lmamask_en= this.lmamask_en;
idp.lmamask_magic= this.lmamask_magic;
......
......@@ -4361,7 +4361,9 @@ public class OpticalFlow {
// Save pair selection and minimize them for scanning, then restore;
int num_sensors =scenes[indx_ref].getNumSensors();
int save_pairs_selection = clt_parameters.img_dtt.getMcorr(num_sensors);
clt_parameters.img_dtt.setMcorr(num_sensors, 0 ); // remove all
// FIXME: uncomment next
System.out.println ("++++ Uncomment next line ++++");
//// clt_parameters.img_dtt.setMcorr(num_sensors, 0 ); // remove all
clt_parameters.img_dtt.setMcorrNeib(num_sensors,true);
clt_parameters.img_dtt.setMcorrSq (num_sensors,true); // remove even more?
clt_parameters.img_dtt.setMcorrDia (num_sensors,true); // remove even more?
......
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