Commit c5a13cd6 authored by Andrey Filippov's avatar Andrey Filippov

Fixed CM bug for bi-quad, more on low-texture filtering

parent 2ea2b2c9
......@@ -120,6 +120,15 @@ public class BiQuadParameters {
public double pf_damp_tilt = 0.001; // Tilt cost for damping insufficient plane data
public double pf_rwsigma = 0.7; // influence of far neighbors diminish as a Gaussian with this sigma
public double pf_rwsigma_narrow = 0.2; // used to determine initial tilt ( 1/radius)
public boolean pf_use_alt = false; // When fitting for the best plane - look for alernative measured tiles too
public double pf_goal_fraction_rms = 0.5; // Try to make rms to be this fraction of maximal acceptable by removing outliers
public double pf_boost_low_density = 0.8; // Strength assigned to fake tiles from neighbors (the lower - the higher)
// Apply when filling gaps, not when growing
public int pf_fourq_min = 1; // Each of the 4 corners should have at least this number of tiles.
public int pf_fourq_gap = 1; // Symmetrical vertical and horizontal center areas that do not belong to any corner
// int trimWeakFG(
public boolean pf_en_trim_fg = false; // Trim weak FZG
......@@ -371,6 +380,20 @@ public class BiQuadParameters {
"Sigma is relative to selection radius (square half-side)");
gd.addNumericField("Weight function Gaussian sigma (relative to radius) for initial plane fitting", this.pf_rwsigma_narrow, 4,6,"",
"Weight function Gaussian sigma (relative to selection radius) for initial plane fitting. May be ~=1/radius");
gd.addCheckbox ("When fitting for the best plane - look for alernative measured tiles too", this.pf_use_alt,
"When selecting tiles that fit best to the plane, try alternative (weaker) disparities too");
gd.addNumericField("Try to make rms to be this fraction of maximal acceptable by removing outliers", this.pf_goal_fraction_rms, 4,6,"pix",
"When removing outliers to fit planes, stop removing when the RMS of the remaining drops below this fraction of the maxium allowed RMS (should be < 1.0");
gd.addNumericField("Strength assigned to fake tiles from neighbors (the lower - the higher)", this.pf_boost_low_density, 4,6,"pix",
"Returned strength assigned to the tiles increases with this value - seems to be a bug");
gd.addNumericField("Each of the 4 corners should have at least this number of tiles", this.pf_fourq_min, 0,3,"",
"Apply (>0) only for filling gaps, not during expansion. It requires that every of the 4 corners of the sample square has this number of tiles for a plane");
gd.addNumericField("Four corners center gap half-width (1 - 1 tile, 2 - 3 tiles, 3 - 5 tiles, ...", this.pf_fourq_gap, 0,3,"",
"Specifies corners of the sample square that should have tiles remain, after removing centre columns and center rows");
gd.addCheckbox ("Trim hanging FG", this.pf_en_trim_fg,
"Try trimming hanging FG (need improvement)");
gd.addNumericField("Absolute tolerane to determine that a tile is a background one for the selected plane",this.pf_atolerance, 4,6,"pix",
......@@ -574,6 +597,14 @@ public class BiQuadParameters {
this.pf_damp_tilt= gd.getNextNumber();
this.pf_rwsigma= gd.getNextNumber();
this.pf_rwsigma_narrow= gd.getNextNumber();
this.pf_use_alt= gd.getNextBoolean();
this.pf_goal_fraction_rms= gd.getNextNumber();
this.pf_boost_low_density= gd.getNextNumber();
this.pf_fourq_min= (int) gd.getNextNumber();
this.pf_fourq_gap= (int) gd.getNextNumber();
this.pf_en_trim_fg= gd.getNextBoolean();
this.pf_atolerance= gd.getNextNumber();
this.pf_rtolerance= gd.getNextNumber();
......@@ -590,7 +621,6 @@ public class BiQuadParameters {
this.pf_new_diff= gd.getNextNumber();
this.pf_min_new= (int) gd.getNextNumber();
this.ltfar_en= gd.getNextBoolean();
this.ltfar_auto_floor= gd.getNextBoolean();
this.ltfar_min_disparity= gd.getNextNumber();
......@@ -719,6 +749,13 @@ public class BiQuadParameters {
properties.setProperty(prefix+"pf_damp_tilt", this.pf_damp_tilt+"");
properties.setProperty(prefix+"pf_rwsigma", this.pf_rwsigma+"");
properties.setProperty(prefix+"pf_rwsigma_narrow", this.pf_rwsigma_narrow+"");
properties.setProperty(prefix+"pf_use_alt", this.pf_use_alt+"");
properties.setProperty(prefix+"pf_goal_fraction_rms", this.pf_goal_fraction_rms+"");
properties.setProperty(prefix+"pf_boost_low_density", this.pf_boost_low_density+"");
properties.setProperty(prefix+"pf_fourq_min", this.pf_fourq_min+"");
properties.setProperty(prefix+"pf_fourq_gap", this.pf_fourq_gap+"");
properties.setProperty(prefix+"pf_en_trim_fg", this.pf_en_trim_fg+"");
properties.setProperty(prefix+"pf_atolerance", this.pf_atolerance+"");
properties.setProperty(prefix+"pf_rtolerance", this.pf_rtolerance+"");
......@@ -845,8 +882,8 @@ public class BiQuadParameters {
if (properties.getProperty(prefix+"pf_strength_rfloor")!=null) this.pf_strength_rfloor=Double.parseDouble(properties.getProperty(prefix+"pf_strength_rfloor"));
if (properties.getProperty(prefix+"pf_cond_rtrusted")!=null) this.pf_cond_rtrusted=Double.parseDouble(properties.getProperty(prefix+"pf_cond_rtrusted"));
if (properties.getProperty(prefix+"pf_strength_pow")!=null) this.pf_strength_pow=Double.parseDouble(properties.getProperty(prefix+"pf_strength_pow"));
if (properties.getProperty(prefix+"pf_disp_afloor")!=null) this.pf_strength_pow=Double.parseDouble(properties.getProperty(prefix+"pf_disp_afloor"));
if (properties.getProperty(prefix+"pf_disp_rfloor")!=null) this.pf_strength_pow=Double.parseDouble(properties.getProperty(prefix+"pf_disp_rfloor"));
if (properties.getProperty(prefix+"pf_disp_afloor")!=null) this.pf_disp_afloor=Double.parseDouble(properties.getProperty(prefix+"pf_disp_afloor"));
if (properties.getProperty(prefix+"pf_disp_rfloor")!=null) this.pf_disp_rfloor=Double.parseDouble(properties.getProperty(prefix+"pf_disp_rfloor"));
if (properties.getProperty(prefix+"pf_smpl_radius")!=null) this.pf_smpl_radius=Integer.parseInt(properties.getProperty(prefix+"pf_smpl_radius"));
if (properties.getProperty(prefix+"pf_smpl_num")!=null) this.pf_smpl_num=Integer.parseInt(properties.getProperty(prefix+"pf_smpl_num"));
if (properties.getProperty(prefix+"pf_smpl_num_narrow")!=null) this.pf_smpl_num_narrow=Integer.parseInt(properties.getProperty(prefix+"pf_smpl_num_narrow"));
......@@ -861,6 +898,12 @@ public class BiQuadParameters {
if (properties.getProperty(prefix+"pf_rwsigma")!=null) this.pf_rwsigma=Double.parseDouble(properties.getProperty(prefix+"pf_rwsigma"));
if (properties.getProperty(prefix+"pf_rwsigma_narrow")!=null) this.pf_rwsigma_narrow=Double.parseDouble(properties.getProperty(prefix+"pf_rwsigma_narrow"));
if (properties.getProperty(prefix+"pf_use_alt")!=null) this.pf_use_alt=Boolean.parseBoolean(properties.getProperty(prefix+"pf_use_alt"));
if (properties.getProperty(prefix+"pf_goal_fraction_rms")!=null) this.pf_goal_fraction_rms=Double.parseDouble(properties.getProperty(prefix+"pf_goal_fraction_rms"));
if (properties.getProperty(prefix+"pf_boost_low_density")!=null) this.pf_boost_low_density=Double.parseDouble(properties.getProperty(prefix+"pf_boost_low_density"));
if (properties.getProperty(prefix+"pf_fourq_min")!=null) this.pf_fourq_min=Integer.parseInt(properties.getProperty(prefix+"pf_fourq_min"));
if (properties.getProperty(prefix+"pf_fourq_gap")!=null) this.pf_fourq_gap=Integer.parseInt(properties.getProperty(prefix+"pf_fourq_gap"));
if (properties.getProperty(prefix+"pf_en_trim_fg")!=null) this.pf_en_trim_fg=Boolean.parseBoolean(properties.getProperty(prefix+"pf_en_trim_fg"));
if (properties.getProperty(prefix+"pf_atolerance")!=null) this.pf_atolerance=Double.parseDouble(properties.getProperty(prefix+"pf_atolerance"));
......@@ -1005,6 +1048,14 @@ public class BiQuadParameters {
bqp.pf_damp_tilt= this.pf_damp_tilt;
bqp.pf_rwsigma= this.pf_rwsigma;
bqp.pf_rwsigma_narrow= this.pf_rwsigma_narrow;
bqp.pf_use_alt= this.pf_use_alt;
bqp.pf_goal_fraction_rms = this.pf_goal_fraction_rms;
bqp.pf_boost_low_density= this.pf_boost_low_density;
bqp.pf_fourq_min= this.pf_fourq_min;
bqp.pf_fourq_gap= this.pf_fourq_gap;
bqp.pf_en_trim_fg = this.pf_en_trim_fg;
bqp.pf_atolerance= this.pf_atolerance;
bqp.pf_rtolerance= this.pf_rtolerance;
......
......@@ -148,47 +148,146 @@ public class BiScan {
return ds;
}
public void showScan(String title) { // FIXME!
// trusted should be set, copied and replaced as needed
public double [][] getFilteredDisparityStrength( // FIXME
final double [][] disparityStrength,
final double min_disparity, // keep original disparity far tiles
final double trusted_strength, // trusted correlation strength
final double strength_rfloor, // strength floor - relative to trusted
final boolean discard_unreliable,// replace v
final boolean discard_weak, // consider weak trusted tiles (not promoted to trusted) as empty
final boolean discard_strong, // suggest new disparitieas even for strong tiles
final double strength_pow, // raise strength-floor to this power
final double [] smpl_radius_array, // space-variant radius
final int smpl_radius,
final int smpl_num, // = 3; // Number after removing worst (should be >1)
final double smpl_fract, // Number of friends among all neighbors
final int smpl_num_narrow, // = 3; // Number after removing worst (should be >1)
final double max_adiff, // Maximal absolute difference betweenthe center tile and friends
final double max_rdiff, // Maximal relative difference between the center tile and friends
final double max_atilt, // = 2.0; // pix per tile
final double max_rtilt, // = 0.2; // (pix / disparity) per tile
final double smpl_arms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
final double smpl_rrms, // = 0.005; // Maximal RMS/disparity in addition to smplRms
final double damp_tilt, // = 0.001; // Tilt cost for damping insufficient plane data
final double rwsigma, // = 0.7; // influence of far neighbors diminish as a Gaussian with this sigma
final double rwsigma_narrow, // = used to determine initial tilt
final double center_weight, // use center tile too (0.0 - do not use)
final boolean use_alt, // use tiles from other scans if they fit better
final double goal_fraction_rms, // Try to make rms to be this fraction of maximal acceptable by removing outliers
final double boost_low_density, // 0 - strength is proportional to 1/density, 1.0 - same as remaining tiles
final int fourq_min, // each of the 4 corners should have at least this number of tiles.
final int fourq_gap, // symmetrical vertical and horizontal center areas that do not belong to any corner
final int dbg_x,
final int dbg_y,
final int debugLevel
){
final int num_tiles = biCamDSI.tnImage.getSizeX()*biCamDSI.tnImage.getSizeY();
double [][] ds0 = getDisparityStrength( // FIXME
false, // final boolean only_strong,
false, // final boolean only_trusted,
true) ; // final boolean only_enabled);
double [][] ds = new double[2][num_tiles];
// double boost_low_density = 0.8; // 1.0; //0.2;
suggestNewScan(
disparityStrength, // final double [][] disparityStrength,
trusted_strength, // final double trusted_strength, // trusted correlation strength
strength_rfloor, // final double strength_rfloor, // strength floor - relative to trusted
true, // final boolean discard_cond, // consider conditionally trusted tiles (not promoted to trusted) as empty
true, // final boolean discard_weak, // consider conditionally trusted tiles (not promoted to trusted) as empty
true, // final boolean discard_strong, // consider conditionally trusted tiles (not promoted to trusted) as empty
strength_pow, // final double strength_pow, // raise strength-floor to this power
smpl_radius, // final int smpl_radius,
smpl_num, // final int smpl_num, // = 3; // Number after removing worst (should be >1)
smpl_fract, // final double smpl_fract, // Number of friends among all neighbors
smpl_num_narrow, // final int smpl_num_narrow, // = 3; // Number after removing worst (should be >1)
max_adiff, // final double max_adiff, // Maximal absolute difference betweenthe center tile and friends
max_rdiff, // final double max_rdiff, // Maximal relative difference between the center tile and friends
max_atilt, // final double max_atilt, // = 2.0; // pix per tile
max_rtilt, // final double max_rtilt, // = 0.2; // (pix / disparity) per tile
smpl_arms, // final double smpl_arms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
smpl_rrms, // final double smpl_rrms, // = 0.005; // Maximal RMS/disparity in addition to smplRms
damp_tilt, // final double damp_tilt, // = 0.001; // Tilt cost for damping insufficient plane data
rwsigma, // final double rwsigma, // = 0.7; // influence of far neighbors diminish as a Gaussian with this sigma
rwsigma_narrow, // final double rwsigma_narrow, // = used to determine initial tilt
0.0, // final double new_diff, // minimal difference between the new suggested and the already tried/measured one
false, // final boolean remove_all_tried, // remove from suggested - not only disabled, but all tried
center_weight, // final double center_weight, // use center tile too (0.0 - do not use)
use_alt, // final boolean use_alt, // use tiles from other scans if they fit better
boost_low_density, // final double boost_low_density, // 0 - strength is proportional to 1/density, 1.0 - same as remaining tiles
goal_fraction_rms, // final double goal_fraction_rms, // Try to make rms to be this fraction of maximal acceptable by removing outliers
ds, // final double [][] smooth_ds, // optionally fill strength array when used for smoothing DSI
fourq_min, // final int fourq_min, // each of the 4 corners should have at least this number of tiles.
fourq_gap, // final int fourq_gap, // symmetrical vertical and horizontal center areas that do not belong to any corner
dbg_x, // final int dbg_x,
dbg_y, // final int dbg_y,
debugLevel); // final int debugLevel);
for (int nTile = 0; nTile < num_tiles; nTile++) {
if ((ds0[1][nTile] > 0.0) && (
(ds[0][nTile] <= 0.0) ||
!discard_unreliable ||
(strong_trusted[nTile] && !discard_strong) ||
(trusted[nTile] && !discard_weak) ||
(ds[0][nTile] < min_disparity))) {
ds[0][nTile] = ds0[0][nTile];
ds[1][nTile] = ds0[1][nTile];
}
}
return ds;
}
public void showScan(String title) {
showScan(title,null);
}
public void showScan(String title, double [][] ext_ds) {
String [] titles= {
"all", // 0
"enabled", // 1
"cond_trusted", // 2
"weak trusted", // 3
"strong trusted", // 4
"measured", // 5
"suggested", // 6
"measured strength", // 7
"strength" }; // 8
double [][] ds_all = getDisparityStrength( // FIXME
"ext_disp", // 0
"all", // 0 1
"enabled", // 1 2
"cond_trusted", // 2 3
"weak trusted", // 3 4
"strong trusted", // 4 5
"measured", // 5 6
"suggested", // 6 7
"ext strength", // 8
"measured strength", // 7 9
"strength" }; // 8 10
double [][] ds_all = getDisparityStrength(
false, // final boolean only_strong,
false, // final boolean only_trusted,
false) ; // final boolean only_enabled);
double [][] ds = getDisparityStrength( // FIXME
double [][] ds = getDisparityStrength(
false, // final boolean only_strong,
false, // final boolean only_trusted,
true) ; // final boolean only_enabled);
double [][] dbg_data = new double[titles.length][];
dbg_data[5] = this.disparity_measured;
dbg_data[0] = ds_all[0];
dbg_data[7] = this.strength_measured;
dbg_data[8] = ds_all[1];
dbg_data[1] = ds[0];
dbg_data[ 6] = this.disparity_measured;
dbg_data[ 1] = ds_all[0];
dbg_data[ 9] = this.strength_measured;
dbg_data[10] = ds_all[1];
dbg_data[ 2] = ds[0];
if (ext_ds != null) {
dbg_data[ 0] = ext_ds[0];
dbg_data[ 8] = ext_ds[1];
}
if (this.cond_trusted != null) {
dbg_data[2] = ds[0].clone();
for (int i = 0; i < this.cond_trusted.length; i++) if (!cond_trusted[i]) dbg_data[2][i] = Double.NaN;
dbg_data[3] = ds[0].clone();
for (int i = 0; i < this.cond_trusted.length; i++) if (!cond_trusted[i]) dbg_data[3][i] = Double.NaN;
}
if (this.trusted != null) {
dbg_data[3] = ds[0].clone();
for (int i = 0; i < this.trusted.length; i++) if (!trusted[i]) dbg_data[3][i] = Double.NaN;
dbg_data[4] = ds[0].clone();
for (int i = 0; i < this.trusted.length; i++) if (!trusted[i]) dbg_data[4][i] = Double.NaN;
}
if (this.strong_trusted != null) {
dbg_data[4] = ds[0].clone();
for (int i = 0; i < this.strong_trusted.length; i++) if (!strong_trusted[i]) dbg_data[4][i] = Double.NaN;
dbg_data[5] = ds[0].clone();
for (int i = 0; i < this.strong_trusted.length; i++) if (!strong_trusted[i]) dbg_data[5][i] = Double.NaN;
}
if (this.target_disparity != null) {
dbg_data[6] = this.target_disparity.clone();
dbg_data[7] = this.target_disparity.clone();
}
(new showDoubleFloatArrays()).showArrays(
dbg_data,
......@@ -380,6 +479,8 @@ public class BiScan {
* 2) target disaprity that lead to the current measurement after refinement
* 3) any other disable measurement
* 4) any target disparity that lead to the disabled measurement
* @param disparityStrength - a pair of array or null. If null, will calculate fro the current scan
* if not null - use as is
* @param trusted_strength strength to trust unconditionally
* @param strength_rfloor strength floor to subrtact as a fraction of the trusted strength
* @param discard_cond if true may suggest new disparities for conditionally trusted tiles
......@@ -401,6 +502,13 @@ public class BiScan {
* @param rwsigma_narrow Gaussian sigma for the preliminary plain fitting using the closesttiles ~= 1/smpl_radius
* @param new_diff minimal difference between the new suggested and the already tried/measured one
* @param remove_all_tried remove from suggested - not only disabled, but all tried
* @param center_weight weight of the tile itself (0.0 - do not use). Should be set to 0.0 for suggesting, >0 - for "smoothing"
* @param use_alt use tiles from other scans if they fit better
* @param goal_fraction_rms try to make rms to be this fraction of maximal acceptable by removing outliers
* @param boost_low_density 0.0 - strength is proportional to 1/density, 1.0 - same as remaining tiles
* @param smooth_ds optionally fill disaprity/strength instead of the target_disparity
* @param fourq_min each of the 4 corners should have at least this number of tiles.
* @param fourq_gap symmetrical vertical and horizontal center areas that do not belong to any corner
* @param dbg_x tileX to debug
* @param dbg_y tileY to debug
* @param debugLevel debug level
......@@ -409,17 +517,18 @@ public class BiScan {
*/
int suggestNewScan(
final double [][] disparityStrength,
final double trusted_strength, // trusted correlation strength
final double strength_rfloor, // strength floor - relative to trusted
final boolean discard_cond, // consider conditionally trusted tiles (not promoted to trusted) as empty
final boolean discard_weak, // consider weak trusted tiles (not promoted to trusted) as empty
final boolean discard_strong, // suggest new disparitieas even for strong tiles
final boolean discard_strong, // suggest new disparities even for strong tiles
final double strength_pow, // raise strength-floor to this power
final int smpl_radius,
final int smpl_num, // = 3; // Number after removing worst (should be >1)
final double smpl_fract, // Number of friends among all neighbors
final int smpl_num_narrow, // = 3; // Number after removing worst (should be >1)
final double max_adiff, // Maximal absolute difference betweenthe center tile and friends
final double max_adiff, // Maximal absolute difference between the center tile and friends
final double max_rdiff, // Maximal relative difference between the center tile and friends
final double max_atilt, // = 2.0; // pix per tile
final double max_rtilt, // = 0.2; // (pix / disparity) per tile
......@@ -430,32 +539,75 @@ public class BiScan {
final double rwsigma_narrow, // = used to determine initial tilt
final double new_diff, // minimal difference between the new suggested and the already tried/measured one
final boolean remove_all_tried, // remove from suggested - not only disabled, but all tried
final double center_weight, // use center tile too (0.0 - do not use)
final boolean use_alt, // use tiles from other scans if they fit better
final double goal_fraction_rms, // Try to make rms to be this fraction of maximal acceptable by removing outliers
final double boost_low_density, // 0 - strength is proportional to 1/density, 1.0 - same as remaining tiles
final double [][] smooth_ds, // optionally fill disaprity/strength instead of the target_disparity
final int fourq_min, // each of the 4 corners should have at least this number of tiles.
final int fourq_gap, // symmetrical vertical and horizontal center areas that do not belong to any corner
final int dbg_x,
final int dbg_y,
final int debugLevel
) {
final TileNeibs tnImage = biCamDSI.tnImage;
final int dbg_tile = (debugLevel > 0)?(dbg_y * tnImage.sizeX + dbg_x): -1;
final double wsigma = rwsigma*smpl_radius;
final double wsigma_narrow = rwsigma_narrow*smpl_radius;
final int smpl_side = 2 * smpl_radius + 1; // Sample size (side of a square)
final int smpl_len = smpl_side*smpl_side;
final int smpl_center = (smpl_side + 1) * smpl_radius;
// prepare window
final double [][] weights = new double [smpl_radius + 1][smpl_radius + 1];
final double [][] weights_narrow = new double [smpl_radius + 1][smpl_radius + 1];
for (int i = 0; i <weights.length; i++) {
for (int j = i; j <weights[i].length; j++) {
weights[i][j] = (wsigma >0.0) ?Math.exp(-(i*i+j*j)/(2*wsigma*wsigma)):1.0;
weights[j][i] = weights[i][j];
weights_narrow[i][j] = (wsigma_narrow >0.0) ?Math.exp(-(i*i+j*j)/(2*wsigma_narrow*wsigma_narrow)):1.0;
weights_narrow[j][i] = weights_narrow[i][j];
{ // normalize
for (int i = 0; i <= smpl_radius; i++) {
for (int j = i; j <= smpl_radius; j++) {
weights[i][j] = (wsigma >0.0) ?Math.exp(-(i*i+j*j)/(2*wsigma*wsigma)):1.0;
weights[j][i] = weights[i][j];
weights_narrow[i][j] = (wsigma_narrow >0.0) ?Math.exp(-(i*i+j*j)/(2*wsigma_narrow*wsigma_narrow)):1.0;
weights_narrow[j][i] = weights_narrow[i][j];
}
}
weights[0][0] *= center_weight;
weights_narrow[0][0] *= center_weight;
double sw_full = 0.0, sw_narrow = 0.0;
for (int i = 0; i <= smpl_radius; i++) {
for (int j = i; j <= smpl_radius; j++) {
sw_full += weights[i][j];
sw_narrow += weights_narrow[i][j];
}
}
double k_full = 1.0/sw_full;
double k_narrow = 1.0/sw_narrow;
for (int i = 0; i <= smpl_radius; i++) {
for (int j = i; j <= smpl_radius; j++) {
weights[i][j] *=k_full;
weights_narrow[i][j]*=k_narrow;
}
}
}
final double [][] ds = getDisparityStrength( // FIXME
final int [] fourq_corner = new int[smpl_len];
for (int i = 0; i < smpl_side; i++) {
for (int j = 0; j < smpl_side; j++) {
int indx = i* smpl_side + j;
if (((i > (smpl_radius - fourq_gap)) && (i < (smpl_radius + fourq_gap))) ||
((j > (smpl_radius - fourq_gap)) && (j < (smpl_radius + fourq_gap)))){
fourq_corner[indx] = 4; // will not be used
} else {
fourq_corner[indx] = ((i > smpl_radius) ? 2 : 0) + ((j > smpl_radius) ? 1 : 0); //122
}
}
}
final double [][] ds = (disparityStrength != null) ? disparityStrength: getDisparityStrength(
false, // final boolean only_strong,
false, // final boolean only_trusted,
true) ; // final boolean only_enabled);
final int num_tiles = tnImage.getSizeX()*tnImage.getSizeY();
final double strength_floor = trusted_strength * strength_rfloor;
final int smpl_side = 2 * smpl_radius + 1; // Sample size (side of a square)
final int smpl_len = smpl_side*smpl_side;
final boolean [] trusted_sw = discard_weak ? (this.strong_trusted) : (discard_cond ? this.trusted: this.cond_trusted);
......@@ -473,8 +625,12 @@ public class BiScan {
threads[ithread] = new Thread() {
@Override
public void run() {
int smpl_center = (smpl_side + 1) * smpl_radius;
for (int nTile = ai.getAndIncrement(); nTile < num_tiles; nTile = ai.getAndIncrement()) if (discard_strong || !trusted_sw[nTile]){
boolean debug = nTile == dbg_tile;
if (debug) {
System.out.println("suggestNewScan(): debbugging nTile="+nTile);
System.out.println("suggestNewScan(): debbugging nTile="+nTile);
}
// Select all neighbors, then filter
double [] smpl_d = new double [smpl_len];
double [] smpl_w = new double [smpl_len];
......@@ -484,25 +640,30 @@ public class BiScan {
double sw = 0, swd = 0;
for (int dy = -smpl_radius; dy <= smpl_radius; dy++) {
int ady = (dy > 0)? dy:(-dy);
for (int dx = -smpl_radius; dx <= smpl_radius; dx++) if ((dx != 0) || (dy != 0)){
for (int dx = -smpl_radius; dx <= smpl_radius; dx++) { // if ((dx != 0) || (dy != 0)){
int nTile1 = tnImage.getNeibIndex(nTile, dx, dy);
if ((nTile1 >= 0) && trusted[nTile1]) { // weak trusted OK
nall++;
int adx = (dx > 0)? dx:(-dx);
int smpl_indx = smpl_center + dy*smpl_side + dx;
double w = ds[1][nTile1]-strength_floor;
smpl_d[smpl_indx] = ds[0][nTile1];
smpl_w[smpl_indx] = w * weights[ady][adx];
smpl_w_narrow[smpl_indx] = w * weights_narrow[ady][adx];
if (strength_pow != 1.0) {
smpl_w[smpl_indx] = Math.pow(smpl_w[smpl_indx], strength_pow);
smpl_w_narrow[smpl_indx] = Math.pow(smpl_w_narrow[smpl_indx], strength_pow);
if ( w > 0) {
if (strength_pow != 1.0) {
w = Math.pow(w, strength_pow);
}
smpl_d[smpl_indx] = ds[0][nTile1];
smpl_w[smpl_indx] = w * weights[ady][adx];
smpl_w_narrow[smpl_indx] = w * weights_narrow[ady][adx];
sw += smpl_w_narrow[smpl_indx];
swd += smpl_w_narrow[smpl_indx]* smpl_d[smpl_indx];
}
sw += smpl_w_narrow[smpl_indx];
swd += smpl_w_narrow[smpl_indx]* smpl_d[smpl_indx];
}
}
}
if (debug) {
System.out.println("suggestNewScan(): sw="+sw);
}
if (sw == 0.0) {
continue; //
......@@ -523,6 +684,7 @@ public class BiScan {
if (nsmpls < smpl_num_narrow) { // no tiles even to start
continue; //
}
double max_rms = smpl_arms + smpl_rrms * disp_mean; // do not need to wait fro the final disparity for this estimate
double [] fit_rslt = fitPlaneRemoveOutliers(
smpl_radius, // int smpl_radius,
max_tilt, // double max_tilt,
......@@ -532,11 +694,63 @@ public class BiScan {
smpl_w_narrow, // double [] smpl_w, // will be modified,
smpl_p, // double [] smpl_p, // will be set if provided
smpl_num_narrow, // int fin_samples, // remove until this number remain
goal_fraction_rms*max_rms, // double fin_rms,
fourq_min, // int fourq_min, // each of the 4 corners should have at least this number of tiles.
fourq_corner, // int [] fourq_corner, // array specifying corner number (0..3), -1 - gap. null when not used
debugLevel); // int debugLevel)
if ( (fit_rslt == null) || (fit_rslt[0] > (smpl_arms + smpl_rrms * fit_rslt[1]))){
// if ( (fit_rslt == null) || (fit_rslt[0] > (smpl_arms + smpl_rrms * fit_rslt[1]))){
if ( (fit_rslt == null) || (fit_rslt[0] > max_rms)){
continue; // narrow selection - too high rms
}
max_rms = smpl_arms + smpl_rrms * fit_rslt[1]; // updated center disparity and so rms
disp_mean = fit_rslt[1]; // smpl_p[smpl_center]; // center of the fitted plane
// try to use alternatives for the discarded (not only) tiles
if (use_alt) {
int nnew = findBetterFitToPlane( // ; // new assignments
smpl_radius, // int smpl_radius,
nTile, // int nTile,
strength_floor, // double strength_floor,
strength_pow, // double strength_pow,
weights, // double [][] weights,
weights_narrow, // double [][] weights_narrow,
smpl_w, // double [] smpl_w,
smpl_w_narrow, // double [] smpl_w_narrow,
smpl_d, // double [] smpl_d,
smpl_p); // double [] smpl_p);
if (nnew > 0) { // there were some changes, recalculate narrow fit plane
fit_rslt = fitPlaneRemoveOutliers(
smpl_radius, // int smpl_radius,
max_tilt, // double max_tilt,
damp_tilt, // double damp_tilt, // = 0.001; // Tilt cost for damping insufficient plane data
true, // boolean full_plane,
smpl_d, // double [] smpl_d,
smpl_w_narrow, // double [] smpl_w, // will be modified,
smpl_p, // double [] smpl_p, // will be set if provided
smpl_num_narrow, // int fin_samples, // remove until this number remain
goal_fraction_rms*max_rms, // double fin_rms,
fourq_min, // int fourq_min, // each of the 4 corners should have at least this number of tiles.
fourq_corner, // int [] fourq_corner, // array specifying corner number (0..3), -1 - gap. null when not used
debugLevel); // int debugLevel)
// if ( (fit_rslt == null) || (fit_rslt[0] > (smpl_arms + smpl_rrms * fit_rslt[1]))){
if ( (fit_rslt == null) || (fit_rslt[0] > max_rms)){
continue; // narrow selection - too high rms
}
disp_mean = fit_rslt[1]; // smpl_p[smpl_center]; // center of the fitted plane
}
// plane may have changed, look for the best fit in history again
nnew = findBetterFitToPlane( // ; // new assignments
smpl_radius, // int smpl_radius,
nTile, // int nTile,
strength_floor, // double strength_floor,
strength_pow, // double strength_pow,
weights, // double [][] weights,
weights_narrow, // double [][] weights_narrow,
smpl_w, // double [] smpl_w,
smpl_w_narrow, // double [] smpl_w_narrow,
smpl_d, // double [] smpl_d,
smpl_p); // double [] smpl_p);
} //if (use_alt) {
// re-select tiles to fit the plane and use wide weights
double max_diff = max_adiff + max_rdiff * disp_mean; // no provisions for tilt (or add a fraction)?
nsmpls = 0;
......@@ -547,6 +761,7 @@ public class BiScan {
smpl_w[indxs] = 0.0;
}
}
if (nsmpls < fin_samples) { // no tiles even to satrt
continue; //
}
......@@ -559,40 +774,79 @@ public class BiScan {
smpl_w, // double [] smpl_w, // will be modified,
smpl_p, // double [] smpl_p, // will be set if provided
fin_samples, // int fin_samples, // remove until this number remain
goal_fraction_rms*max_rms, // double fin_rms,
fourq_min, // int fourq_min, // each of the 4 corners should have at least this number of tiles.
fourq_corner, // int [] fourq_corner, // array specifying corner number (0..3), -1 - gap. null when not used
debugLevel); // int debugLevel)
if ( (fit_rslt == null) || (fit_rslt[0] > (smpl_arms + smpl_rrms * fit_rslt[1]))){
// if ( (fit_rslt == null) || (fit_rslt[0] > (smpl_arms + smpl_rrms * fit_rslt[1]))){
if ( (fit_rslt == null) || (fit_rslt[0] > max_rms)){
continue; // narrow selection - too high rms
}
if (Math.abs(fit_rslt[1] - ds[0][nTile]) < new_diff) { // suggested is too close to already measured
continue; // already measured for this tile
}
// compare to the previous suggestion
int previous_indx = ((src_index[nTile] < 0)? list_index:src_index[nTile]) -1;
double previous_target = (previous_indx >= 0)? biCamDSI.getBiScan(previous_indx).target_disparity[nTile]:Double.NaN; // Nothing is known about the target of the 0-scan
if (Math.abs(fit_rslt[1] - previous_target) < new_diff) { // suggested is too close to already suggested and result - disabled
continue; // already measured for this tile
}
// see if close one was already disabled
// do not compare with the scans that were not disabled - re-try them?remove_all_tried
boolean valid_suggestion = true;
for (BiScan other_scan:biCamDSI.biScans) if (other_scan.disabled_measurement[nTile] || remove_all_tried) {
// int other_indx = (other_scan.src_index[nTile] < 0)? other_scan.list_index:other_scan.src_index[nTile];
// double other_disparity = biCamDSI.getBiScan(other_indx).disparity_measured[nTile];
double other_disparity = other_scan.disparity_measured[nTile];
if (Math.abs(fit_rslt[1] - other_disparity) < new_diff) { // suggested is too close to already measured and disabled
valid_suggestion = false;
break; // already measured for this tile
if ((disparityStrength == null) && (new_diff > 0.0)) {
if (Math.abs(fit_rslt[1] - ds[0][nTile]) < new_diff) { // suggested is too close to already measured
continue; // already measured for this tile
}
int other_indx = other_scan.list_index;
double other_target = (other_indx > 0)? biCamDSI.getBiScan(other_indx - 1).target_disparity[nTile]:Double.NaN; // Nothing is known about the target of the 0-scan
if (Math.abs(fit_rslt[1] - other_target) < new_diff) { // suggested is too close to already suggested and result - disabled
valid_suggestion = false;
break; // already measured for this tile
// compare to the previous suggestion
int previous_indx = ((src_index[nTile] < 0)? list_index:src_index[nTile]) -1;
double previous_target = (previous_indx >= 0)? biCamDSI.getBiScan(previous_indx).target_disparity[nTile]:Double.NaN; // Nothing is known about the target of the 0-scan
if (Math.abs(fit_rslt[1] - previous_target) < new_diff) { // suggested is too close to already suggested and result - disabled
continue; // already measured for this tile
}
// see if close one was already disabled
// do not compare with the scans that were not disabled - re-try them?remove_all_tried
// If disparityStrength[][] is provided, do not use history. If difference is <= 0 - also no sense to look there
// for (BiScan other_scan:biCamDSI.biScans) if (other_scan.disabled_measurement[nTile] || remove_all_tried) {
for (BiScan other_scan:biCamDSI.biScans) if ( (other_scan.list_index <= list_index) && (other_scan.disabled_measurement[nTile] || remove_all_tried)) {
// int other_indx = (other_scan.src_index[nTile] < 0)? other_scan.list_index:other_scan.src_index[nTile];
// double other_disparity = biCamDSI.getBiScan(other_indx).disparity_measured[nTile];
double other_disparity = other_scan.disparity_measured[nTile];
if (Math.abs(fit_rslt[1] - other_disparity) < new_diff) { // suggested is too close to already measured and disabled
valid_suggestion = false;
break; // already measured for this tile
}
int other_indx = other_scan.list_index;
double other_target = (other_indx > 0)? biCamDSI.getBiScan(other_indx - 1).target_disparity[nTile]:Double.NaN; // Nothing is known about the target of the 0-scan
if (Math.abs(fit_rslt[1] - other_target) < new_diff) { // suggested is too close to already suggested and result - disabled
valid_suggestion = false;
break; // already measured for this tile
}
}
}
if (valid_suggestion) {
target_disparity[nTile] = fit_rslt[1];
num_new.getAndIncrement();
if (smooth_ds == null) { // fill target disparity
target_disparity[nTile] = fit_rslt[1];
} else { // this method is used to provide a filtered DSI - no changes to the target_disparity
smooth_ds[0][nTile] = fit_rslt[1];
double s0 = 0, s1 = 0;
for (int dy = -smpl_radius; dy <= smpl_radius; dy++) {
int ady = (dy > 0)? dy:(-dy);
for (int dx = -smpl_radius; dx <= smpl_radius; dx++) { // if ((dx != 0) || (dy != 0)){
int adx = (dx > 0)? dx:(-dx);
int smpl_indx = smpl_center + dy*smpl_side + dx;
if (smpl_w[smpl_indx] > 0.0) {
s0+= weights[ady][adx];
s1+= weights[ady][adx] * smpl_w[smpl_indx];
}
}
}
//boost_low_density, // false weight of low density tiles is reduced, true - boosted
double w = s1;
if (boost_low_density > 0.0) {
w/= Math.pow(s0, boost_low_density);
}
if (strength_pow != 1.0) {
w = Math.pow(w, 1.0 / strength_pow);
}
w += strength_floor;
smooth_ds[1][nTile] = w;
if (Double.isNaN(w)) {
System.out.println("suggestNewScan(): nTile="+nTile+" w="+w);
System.out.println("suggestNewScan(): nTile="+nTile+" w="+w);
}
}
}
}
}
......@@ -603,6 +857,74 @@ public class BiScan {
return num_new.get();
}
private int findBetterFitToPlane(
int smpl_radius,
int nTile,
double strength_floor,
double strength_pow,
double [][] weights,
double [][] weights_narrow,
double [] smpl_w,
double [] smpl_w_narrow,
double [] smpl_d,
double [] smpl_p
)
{
final TileNeibs tnImage = biCamDSI.tnImage;
final int smpl_side = 2 * smpl_radius + 1; // Sample size (side of a square)
// final int smpl_len = smpl_side*smpl_side;
final int smpl_center = (smpl_side + 1) * smpl_radius;
int nnew = 0; // new assignments
for (int dy = -smpl_radius; dy <= smpl_radius; dy++) {
int ady = (dy > 0)? dy:(-dy);
for (int dx = -smpl_radius; dx <= smpl_radius; dx++){
int adx = (dx > 0)? dx:(-dx);
int smpl_indx = smpl_center + dy*smpl_side + dx;
if (smpl_w [smpl_indx] > 0.0) { // is in "untouched" weights
int nTile1 = tnImage.getNeibIndex(nTile, dx, dy);
// if ((nTile1 >= 0) && trusted[nTile1]) { // weak trusted OK
if (nTile1 >= 0) { // will use any strength > 0
// see if there is a measurement that fits better to the plane
int best_indx=-1;
double best_diff = Math.abs(smpl_d[smpl_indx] - smpl_p[smpl_indx]);
for (int scan_indx = list_index; scan_indx >= 0; scan_indx--) { // include the latest measurement
BiScan scan = biCamDSI.getBiScan(scan_indx);
if (scan.disabled_measurement[nTile]) { // || (scan.src_index[nTile] != indx)){ // skip all but enabled
continue;
}
double disp = scan.disparity_measured[nTile1];
if (Double.isNaN(disp)) {
continue;
}
if (scan.strength_measured[nTile1] <= strength_floor) {
continue;
}
double diff = Math.abs(disp - smpl_p[smpl_indx]);
if ((best_indx < 0) || (diff < best_diff)){
best_indx = scan_indx;
best_diff = diff;
}
}
if (best_indx >= 0) {
BiScan scan = biCamDSI.getBiScan(best_indx);
smpl_d[smpl_indx] = scan.disparity_measured[nTile1];
double w = scan.strength_measured[nTile1] -strength_floor ;
if (w > 0.0) { // should be anyway
if (strength_pow != 1.0) {
w = Math.pow(w, strength_pow);
}
smpl_w[smpl_indx] = w * weights[ady][adx];
smpl_w_narrow[smpl_indx] = w * weights_narrow[ady][adx];
nnew++;
}
}
}
}
}
}
return nnew;
}
// Simple version for non-flat strong areas - try duplicating neighbor
int suggestNewScan(
......@@ -653,7 +975,7 @@ public class BiScan {
}
// see if close one was already disabled
boolean valid_suggestion = true;
for (BiScan other_scan:biCamDSI.biScans) if (other_scan.disabled_measurement[nTile] || remove_all_tried) {
for (BiScan other_scan:biCamDSI.biScans) if ( (other_scan.list_index <= list_index) && (other_scan.disabled_measurement[nTile] || remove_all_tried)) {
// int other_indx = (other_scan.src_index[nTile] < 0)? other_scan.list_index:other_scan.src_index[nTile];
// double other_disparity = biCamDSI.getBiScan(other_indx).disparity_measured[nTile];
double other_disparity = other_scan.disparity_measured[nTile];
......@@ -735,6 +1057,7 @@ public class BiScan {
final int debugLevel
) {
final double goal_fraction_rms = 0.5;
final TileNeibs tnImage = biCamDSI.tnImage;
final double wsigma = rwsigma*smpl_radius;
final double [][] ds = getDisparityStrength( // already has disabled zeroed
......@@ -754,6 +1077,25 @@ public class BiScan {
weights[j][i] = weights[i][j];
}
}
final boolean [][] halves = new boolean [8][smpl_len];
{
for (int i = 0; i < smpl_side; i++) {
for (int j = 0; j < smpl_side; j++) {
int indxs = i*smpl_side+ j;
halves[0][indxs] = (i <= smpl_radius);
halves[4][indxs] = (i >= smpl_radius);
halves[2][indxs] = (j >= smpl_radius);
halves[6][indxs] = (j <= smpl_radius);
halves[1][indxs] = (j >= i);
halves[5][indxs] = (j <= i);
halves[3][indxs] = ((i + j) >= (2 * smpl_radius));
halves[7][indxs] = ((i + j) <= (2 * smpl_radius));
}
}
}
final Thread[] threads = ImageDtt.newThreadArray(biCamDSI.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger num_non_weak = new AtomicInteger(0);
......@@ -831,8 +1173,9 @@ public class BiScan {
}
int fin_samples= (int) ( nall * smpl_fract);
if (fin_samples < smpl_num) fin_samples = smpl_num;
double max_rms = smpl_arms + smpl_rrms * disp_center;
if (nsmpls >= fin_samples) {
double [] smpl_w_persistent = smpl_w.clone();
double [] fit_rslt = fitPlaneRemoveOutliers(
smpl_radius, // int smpl_radius,
max_tilt, // double max_tilt,
......@@ -842,13 +1185,22 @@ public class BiScan {
smpl_w, // double [] smpl_w, // will be modified,
smpl_p, // double [] smpl_p, // will be set if provided
fin_samples, // int fin_samples, // remove until this number remain
goal_fraction_rms*max_rms, // double fin_rms,
0, // int fourq_min, // each of the 4 corners should have at least this number of tiles.
null, // int [] fourq_corner, // array specifying corner number (0..3), -1 - gap. null when not used
debugLevel); // int debugLevel)
if ( (fit_rslt != null) && (fit_rslt[0] < (smpl_arms + smpl_rrms * fit_rslt[1]))){
// if ( (fit_rslt != null) && (fit_rslt[0] < (smpl_arms + smpl_rrms * fit_rslt[1]))){
if ( (fit_rslt != null) && (fit_rslt[0] < max_rms)){
// Trusted tile, save it
trusted[nTile] = true;
num_trusted_plane.getAndIncrement();
continue;
}
// try 8 "halves" around the tile - it may be weak background close to the strong foreground (or stray FG tile)
}
}
}
};
......@@ -934,6 +1286,7 @@ public class BiScan {
final int debugLevel
) {
final double goal_fraction_rms = 0.5;
final TileNeibs tnImage = biCamDSI.tnImage;
final int dbg_tile = (debugLevel>-2)?(dbg_x + tnImage.sizeX*dbg_y):-1;
final double wsigma = rwsigma*smpl_radius;
......@@ -1021,6 +1374,8 @@ public class BiScan {
}
int fin_samples= (int) ( nall * smpl_fract);
if (fin_samples < smpl_num) fin_samples = smpl_num;
double max_rms = smpl_arms + smpl_rrms * disp_center;
// final double goal_fraction_rms = 0.5;
if (nsmpls >= fin_samples) {
double [] fit_rslt = fitPlaneRemoveOutliers(
......@@ -1032,8 +1387,12 @@ public class BiScan {
smpl_w, // double [] smpl_w, // will be modified,
smpl_p, // double [] smpl_p, // will be set if provided
fin_samples, // int fin_samples, // remove until this number remain
goal_fraction_rms*max_rms, // double fin_rms,
0, // int fourq_min, // each of the 4 corners should have at least this number of tiles.
null, // int [] fourq_corner, // array specifying corner number (0..3), -1 - gap. null when not used
debugLevel); // int debugLevel)
if ( (fit_rslt != null) && (fit_rslt[0] < (smpl_arms + smpl_rrms * fit_rslt[1]))){
// if ( (fit_rslt != null) && (fit_rslt[0] < (smpl_arms + smpl_rrms * fit_rslt[1]))){
if ( (fit_rslt != null) && (fit_rslt[0] < max_rms)){
// check directions here, use smpl_w_all, smpl_d and smpl_p
// int [] num_this_closer = new int [num_dirs];
// int [] num_this_closer_strong = new int [num_dirs];
......@@ -1177,17 +1536,23 @@ public class BiScan {
/**
* Remove worst outliers when fitting planes until the specified number of samples are left, re-fitting
* plane after each iteration
* plane after each iteration.
* Additional mode for filling gaps (not extending) - "four quadrants" is activated when fourq_min > 0
* In this mode each of the four corners of the sample square (after removing center 2*fourq_gap -1 rows
* and columns should have at least fourq_min remaining tiles
* @param smpl_radius sample "radius", square side is 2 * smpl_radius + 1
* @param max_tilt maximal DSI plane tilt (pixels/tile)
* @param damp_tilt tilt cost for damping insufficient plane data
* @param full_plane generate full tilted plane, not only for non-zero tiles
* @param smpl_d array of disparity values to approximate
* @param smpl_w weights - only >0.0 are processed
* @param smpl_p approximated disparity values, amy be null. When provided (not null), will have calculated disparity approximation
* @param fin_samples
* @param smpl_p approximated disparity values, may be null. When provided (not null), will have calculated disparity approximation
* @param fin_samples remove until this number of tiles remain
* @param fin_rms - OK RMS - exit if it is below (set to 0.0 if unknown yet)
* @param fourq_min each of the 4 corners should have at least this number of tiles.
* @param fourq_corner array specifying corner number (0..3), -1 - gap. null when not used
* @param debugLevel debug level
* @return array of 4 values: rmas of the remaining samples, average (center) disparity value, tiltX, tiltY
* @return array of 4 values: rms of the remaining samples, average (center) disparity value, tiltX, tiltY
*/
public double [] fitPlaneRemoveOutliers(
int smpl_radius,
......@@ -1198,16 +1563,31 @@ public class BiScan {
double [] smpl_w, // will be modified,
double [] smpl_p, // will be set if provided
int fin_samples, // remove until this number remain
double fin_rms,
int fourq_min,
int [] fourq_corner,
int debugLevel)
{
int [] num_in_corners = ((fourq_corner == null) || (fourq_min == 0)) ? null: new int [5]; // last is not used
double [] disp_tilts = null;
final int smpl_side = 2 * smpl_radius + 1; // Sample size (side of a square)
int num_in_sample = 0;
for (int i = 0; i < smpl_w.length; i++) if (smpl_w[i]> 0.0) num_in_sample++;
for (int i = 0; i < smpl_w.length; i++) if (smpl_w[i]> 0.0) {
num_in_sample++;
if (num_in_corners != null) num_in_corners[fourq_corner[i]]++;
}
int smpl_len = smpl_w.length;
if (num_in_sample <fin_samples) {
if (num_in_sample < fin_samples) {
return null;
}
if (num_in_corners != null) {
for (int i = 0; i < 4; i++) {
if (num_in_corners[i] < fourq_min) {
return null;
}
}
}
double rms = Double.NaN;
if (smpl_p == null) smpl_p = new double [smpl_len];
while (num_in_sample >= fin_samples) {
......@@ -1236,10 +1616,19 @@ public class BiScan {
rms = (sw > 0.0)? Math.sqrt(sd2/sw): Double.NaN;
// remove worst - it should not make remaining set
if (num_in_sample > fin_samples) { // remove worst if it is not the last run where only calculations are needed
if ((num_in_sample > fin_samples) && !(rms < fin_rms)) { // remove worst if it is not the last run where only calculations are needed
int iworst = -1;
double dworst2 = 0.0;
for (int indxs = 0; indxs < smpl_len; indxs++) if (smpl_w[indxs] > 0.0) {
// verify that the worst tile will not leave the corner too empty
int num_corner = 4; // unused, gap
if (num_in_corners != null) {
num_corner = fourq_corner[indxs];
if ((num_corner < 4) && (num_in_corners[num_corner] <= fourq_min)) {
continue; // can not remove this tile
}
}
double d2 = smpl_d[indxs] - smpl_p[indxs];
d2 *=d2;
if (d2 > dworst2) {
......@@ -1252,7 +1641,7 @@ public class BiScan {
}
}
}
if (iworst < 0){
if (iworst < 0){ // can happen if damp_tilt == 0.0 and will become colinear
if (debugLevel > 0) {
System.out.println("**** this may be BUG in fitPlaneRemoveOutliers() can not find the worst sample - all tiles fit perfectly ****");
}
......@@ -1260,6 +1649,9 @@ public class BiScan {
break;
}
// remove worst sample
if (num_in_corners != null) {
num_in_corners[fourq_corner[iworst]]--; // corner counter - can remove from the gap, but nobody count that
}
smpl_w[iworst] = 0.0;
num_in_sample --;
} else {
......
......@@ -38,6 +38,7 @@ public class Correlation2d {
private final double [] ortho_notch_filter;
private final double [] corr_wndx;
private final double [] corr_wndy;
private final double [] corr_wndy_notch;
// configuration for 8-lens and 4-lens cameras. 8-lens has baseline = 1 for 1..4 and 1/2 for 4..7
/*0 1
......@@ -133,16 +134,25 @@ public class Correlation2d {
this.ortho_notch_filter = new double [corr_size];
this.corr_wndy = halfFlatTopWindow(
imgdtt_params.corr_wndy_size, // int ihwidth,
imgdtt_params.corr_wndy_hwidth, // double hwidth,
imgdtt_params.corr_wndy_hwidth, // double hwidth,
imgdtt_params.corr_wndy_blur, // double blur,
true, // boolean normalize,
true, // boolean normalize,
false, // boolean notch,
1.0); // double scale);
this.corr_wndx = halfFlatTopWindow(
imgdtt_params.corr_wndx_size, // int ihwidth,
imgdtt_params.corr_wndx_hwidth, // double hwidth,
imgdtt_params.corr_wndx_blur, // double blur,
true, // boolean normalize,
false, // boolean notch,
wndx_scale); // double scale);
this.corr_wndy_notch = halfFlatTopWindow(
imgdtt_params.corr_strip_notch, // int ihwidth,
imgdtt_params.corr_notch_hwidth,// double hwidth,
imgdtt_params.corr_notch_blur, // double blur,
true, // boolean normalize,
true, // boolean notch,
wndx_scale); // double scale);
}
......@@ -908,9 +918,20 @@ public class Correlation2d {
this.corr_wndx, // double [] window_x, // half of a window function in x (disparity) direction
debug);// boolean debug);
}
public double [] getMaxXCm( // get fractional center as a "center of mass" inside circle/square from the integer max
public double [] getMaxXCmNotch( // get fractional center as a "center of mass" inside circle/square from the integer max
double [] data, // [data_size * data_size]
int ixcenter, // integer center x
boolean debug) {
return getMaxXCm( // get fractional center as a "center of mass" inside circle/square from the integer max
data, // double [] data, // [data_size * data_size]
ixcenter, // int ixcenter, // integer center x
this.corr_wndy_notch, // double [] window_y, // (half) window function in y-direction(perpendicular to disparity: for row0 ==1
this.corr_wndx, // double [] window_x, // half of a window function in x (disparity) direction
debug); // boolean debug);
}
public double [] getMaxXCm( // get fractional center as a "center of mass" inside circle/square from the integer max
double [] data, // rectangular strip of 1/2 of the correlation are with odd rows shifted by 1/2 pixels
int ixcenter, // integer center x
double [] window_y, // (half) window function in y-direction(perpendicular to disparity: for row0 ==1
double [] window_x, // half of a window function in x (disparity) direction
boolean debug) {
......@@ -926,7 +947,29 @@ public class Correlation2d {
wy_scale = 1.0/swy;
}
double [][]dbg_data = null;
if (debug) {
String [] dbg_titles = {"strip","*wnd_y"};
dbg_data = new double [2][];
dbg_data[0] = debugStrip3(data);
double [] data_0 = data.clone();
for (int i = 0; i < data_height; i++) {
for (int j = 0; j < data_width; j++) {
data_0[i * data_width + j] *= (i < window_y.length) ? (wy_scale * window_y[i]): 0.0;
}
}
dbg_data[1] = debugStrip3(data_0);
int long_width = 2 * (2 * transform_size-1);
if (dbg_data[0] != null) {
(new showDoubleFloatArrays()).showArrays(
dbg_data,
long_width,
dbg_data[0].length/long_width,
true,
"Strip",
dbg_titles);
}
System.out.println("getMaxXCm(), ixcenter = "+ixcenter);
for (int dy = 0; dy < data_height; dy++) {
if ((dy & 1) != 0) System.out.print(" ");
......@@ -937,7 +980,6 @@ public class Correlation2d {
}
System.out.println();
}
double s0=0.0, sx=0.0, sx2 = 0.0;
int x0 = center + ixcenter; // index of the argmax, starting with 0
for (int dy = 0; dy < data_height; dy++) {
......@@ -993,6 +1035,7 @@ public class Correlation2d {
* @param blur full width of transition from top value to zero
* @param normalize: false - no normalization, [0] = 1.0 (blur permitting),
* true - sum of zero element and twice each other == 1.0
* @param notch: true - make it a notch filter
* @param scale multiply each value
* @return half-window array [ihwidth]
*/
......@@ -1002,6 +1045,7 @@ public class Correlation2d {
double hwidth,
double blur,
boolean normalize,
boolean notch,
double scale) {
double [] wnd = new double [ihwidth];
for (int i = 0; i < ihwidth; i++) {
......@@ -1012,6 +1056,9 @@ public class Correlation2d {
else if (i > hwidth + blur/2) wnd[i] = 0.0;
else wnd[i] = 0.5*(1.0 - Math.sin(Math.PI * (i-hwidth)/blur));
}
if (notch) {
wnd[i] = 1.0 - wnd[i];
}
}
if (normalize) {
double s = 0.0;
......@@ -1256,6 +1303,32 @@ public class Correlation2d {
return padded_strip;
}
// Full size/resolution.but on a larger rectangle
public double [] debugStrip3(
double [] strip) {
if (strip == null) return null;
int center = transform_size - 1;
int width = 2 * center + 1;// 2* transform_siza-1
int long_width = 2 * width;
int height = strip.length/width;
int long_height = 2 * height - 1;
double [] padded_strip = new double [long_height * long_width];
for (int row = 0; row < long_height; row++) {
int srow = (row >= height)? (row - height) : (height - row);
int odd = srow & 1;
for (int j = 0; j<width; j++) {
int j1 = transform_size / 2 + ((j - odd) >> 1);
if ((j1 < 0) || (j1 >- width)) {
padded_strip[row * width + j] = Double.NaN;
} else {
padded_strip[row * width + j] = strip[srow * width + j1];
}
}
}
return padded_strip;
}
public double [] mismatchPairsCM( // returns x-xcenter, y, strength (sign same as disparity)
ImageDttParameters imgdtt_params,
double [][] corrs,
......
......@@ -592,6 +592,8 @@ private Panel panel1,
addButton("Reset GT", panelClt4, color_stop);
addButton("Ground truth 0", panelClt4, color_configure);
addButton("Ground truth", panelClt4, color_conf_process);
addButton("Show biscan", panelClt4, color_configure);
addButton("Poles GT", panelClt4, color_process);
addButton("ML export", panelClt4, color_conf_process);
addButton("Rig planes", panelClt4, color_conf_process);
......@@ -4615,8 +4617,19 @@ private Panel panel1,
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
enhanceByRig(true);
return;
/* ======================================================================== */
} else if (label.equals("Show biscan")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
showBiScan();
return;
/* ======================================================================== */
} else if (label.equals("Poles GT")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
processPoles();
return;
/* ======================================================================== */
} else if (label.equals("CLT planes")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
......@@ -5047,6 +5060,8 @@ private Panel panel1,
return true;
}
public boolean rigPlanes() {
if ((QUAD_CLT == null) || (QUAD_CLT.tp == null) || (QUAD_CLT.tp.clt_3d_passes == null)) {
String msg = "DSI data is not available. Please run \"CLT 3D\" first";
......@@ -5069,6 +5084,70 @@ private Panel panel1,
return true;
}
public boolean showBiScan() {
if ((QUAD_CLT == null) ||
(QUAD_CLT.tp == null) ||
(QUAD_CLT.tp.clt_3d_passes == null) ||
(TWO_QUAD_CLT == null) ||
(TWO_QUAD_CLT.biCamDSI_persistent== null) ||
(TWO_QUAD_CLT.biCamDSI_persistent.biScans== null)) {
String msg = "Data is not available. Please run \"Ground truth\" first";
IJ.showMessage("Error",msg);
System.out.println(msg);
return false;
}
TWO_QUAD_CLT.showBiScan(
QUAD_CLT, // QuadCLT quadCLT_main, // tiles should be set
CLT_PARAMETERS, // EyesisCorrectionParameters.CLTParameters clt_parameters,
DEBUG_LEVEL); // final int debugLevel) // throws Exception
return true;
}
public boolean processPoles() {
long startTime=System.nanoTime();
if ((QUAD_CLT == null) ||
(QUAD_CLT.tp == null) ||
(QUAD_CLT.tp.clt_3d_passes == null) ||
(TWO_QUAD_CLT == null) ||
(TWO_QUAD_CLT.biCamDSI_persistent== null) ||
(TWO_QUAD_CLT.biCamDSI_persistent.biScans== null)) {
String msg = "Data is not available. Please run \"Ground truth\" first";
IJ.showMessage("Error",msg);
System.out.println(msg);
return false;
}
String configPath=getSaveCongigPath();
if (configPath.equals("ABORT")) return false;
if (DEBUG_LEVEL > -2){
System.out.println("++++++++++++++ Enhancing single-camera DSI by the dual-camera rig using planes ++++++++++++++");
}
TWO_QUAD_CLT.processPoles( // actually there is no sense to process multiple image sets. Combine with other processing?
// QUAD_CLT, // QuadCLT quadCLT_main,
// QUAD_CLT_AUX, // QuadCLT quadCLT_aux,
TWO_QUAD_CLT.biCamDSI_persistent, // BiCamDSI biCamDSI,
CLT_PARAMETERS, // EyesisCorrectionParameters.DCTParameters dct_parameters,
THREADS_MAX, //final int threadsMax, // maximal number of threads to launch
UPDATE_STATUS, //final boolean updateStatus,
DEBUG_LEVEL);
if (configPath!=null) {
saveTimestampedProperties( // save config again
configPath, // full path or null
null, // use as default directory if path==null
true,
PROPERTIES);
}
System.out.println("enhanceByRig(): Processing finished at "+
IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+" sec, --- Free memory="+
Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
return true;
}
//resetGroundTruthByRig()
public boolean resetGroundTruth() {
if ((QUAD_CLT == null) || (QUAD_CLT.tp == null)) return false;
......
......@@ -7188,6 +7188,7 @@ public class ImageDtt {
* @param ml hwidth Optional to output data for ML: half width of the output tile (0 -> 1x1, 1-> 3x3, 2->5x5). Used only if center_corr != null
* @param ml_center_corr Optional to output data for ML: output array [(2*hwidth+1)*(2*hwidth+1)] or null
* @param tcorr_combo if not null then tcorr_combo will contain full 2d correlation for debugging (now 15x15 in line scan order)
* @param notch_mode - detect vertical poles, use a notch filter for Y, normal - for X
* @param tileX debug tile X
* @param tileY debug tile X
* @param debugLevel debug level
......@@ -7204,9 +7205,11 @@ public class ImageDtt {
final int ml_hwidth,
final double [] ml_center_corr,
final double [][] tcorr_combo,
final boolean notch_mode,
final int tileX, // only used in debug output
final int tileY,
final int debugLevel) {
int strip_hight = notch_mode? clt_parameters.img_dtt.corr_strip_notch : clt_parameters.img_dtt.corr_strip_hight;
double [] result = {Double.NaN, 0.0, Double.NaN, Double.NaN};
double [] inter_cam_corr = corr2d.correlateInterCamerasFD(
clt_data_tile_main, // double [][][][] clt_data_tile_main,
......@@ -7217,7 +7220,7 @@ public class ImageDtt {
double [] stripe_inter = corr2d. scaleRotateInterpoateSingleCorrelation(
inter_cam_corr, // double [] corr,
clt_parameters.img_dtt.corr_strip_hight, // int hwidth,
strip_hight, // int hwidth,
Correlation2d.PAIR_HORIZONTAL, // int dir, // 0 - hor, 1 - vert, 2 - parallel to row = col (main) diagonal (0->3), 3 -2->1
1, // int ss,
(debugLevel > 0)); // boolean debug
......@@ -7240,6 +7243,7 @@ public class ImageDtt {
// First get integer correlation center, relative to the center
// TODO: multiply/acummulate by Y window?
int [] ixy = corr2d.getMaxXYInt( // find integer pair or null if below threshold
stripe_inter, // double [] data,
true, // boolean axis_only, for strip it is always true
......@@ -7259,19 +7263,39 @@ public class ImageDtt {
if (Double.isNaN(strength)) {
System.out.println("BUG: 1. strength should not be NaN");
}
corr_stat = corr2d.getMaxXCm( // get fractional center as a "center of mass" inside circle/square from the integer max
stripe_inter, // double [] data, // [data_size * data_size]
ixy[0], // int ixcenter, // integer center x
// corr_wndy, // double [] window_y, // (half) window function in y-direction(perpendicular to disparity: for row0 ==1
// corr_wndx, // double [] window_x, // half of a window function in x (disparity) direction
(debugLevel > 0)); // boolean debug);
//getMaxXCmNotch if
if (notch_mode) {
corr_stat = corr2d.getMaxXCmNotch( // get fractional center as a "center of mass" inside circle/square from the integer max
stripe_inter, // double [] data, // [data_size * data_size]
ixy[0], // int ixcenter, // integer center x
// corr_wndy, // double [] window_y, // (half) window function in y-direction(perpendicular to disparity: for row0 ==1
// corr_wndx, // double [] window_x, // half of a window function in x (disparity) direction
(debugLevel > 0)); // boolean debug);
} else {
corr_stat = corr2d.getMaxXCm( // get fractional center as a "center of mass" inside circle/square from the integer max
stripe_inter, // double [] data, // [data_size * data_size]
ixy[0], // int ixcenter, // integer center x
// corr_wndy, // double [] window_y, // (half) window function in y-direction(perpendicular to disparity: for row0 ==1
// corr_wndx, // double [] window_x, // half of a window function in x (disparity) direction
(debugLevel > 0)); // boolean debug);
}
}
if (corr_stat != null) {
if (debugLevel > 0){
System.out.println(String.format("Tile X/Y = %d/%d corr_stat= {%f, %f, %f} ",tileX, tileY,corr_stat[0],corr_stat[1],corr_stat[2]));
System.out.println("notch_mode ="+notch_mode);
}
disparity = -corr_stat[0];
result[INDEX_DISP] = disparity;
double eff_radius = corr_stat[2] * clt_parameters.img_dtt.cm_max_normalization;
strength = corr_stat[1]/(eff_radius * eff_radius); // total mass by square effective radius
result[INDEX_STRENGTH] = strength;
// see if strength is enough to proceed with LMA/poly (otherwise keep disp/strength
if (strength > clt_parameters.img_dtt.min_poly_strength) {
if ((strength > clt_parameters.img_dtt.min_poly_strength) && !notch_mode) { // for now notch mode is only for CM
// create LMA instance, calculate LMA composite argmax
// Create 2 groups: ortho & diag
Correlations2dLMA lma = corr2d.corrLMA(
......@@ -7705,6 +7729,7 @@ public class ImageDtt {
public double [][][][][][][] clt_bi_quad(
final EyesisCorrectionParameters.CLTParameters clt_parameters,
final double fatzero, // May use correlation fat zero from 2 different parameters - fat_zero and rig.ml_fatzero
final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
final int [][] tile_op, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
final double [][][] image_data_main, // first index - number of image in a quad
......@@ -7786,7 +7811,7 @@ public class ImageDtt {
}
}
if (globalDebugLevel > 0) {
if (globalDebugLevel > -2) {
System.out.println("clt_aberrations_quad_corr(): width="+width+" height="+height+" transform_size="+clt_parameters.transform_size+
" debug_tileX="+debug_tileX+" debug_tileY="+debug_tileY+" globalDebugLevel="+globalDebugLevel);
}
......@@ -8182,6 +8207,7 @@ public class ImageDtt {
ml_hwidth, // final int ml_hwidth,
ml_data_inter, // final double [] ml_center_corr,
tcorr_combo, // double [][] tcorr_combo,
notch_mode, // final boolean notch_mode,
tileX, // final int tileX, // only used in debug output
tileY, // final int tileY,
tile_lma_debug_level); // final int debugLevel)
......@@ -8262,6 +8288,7 @@ public class ImageDtt {
ml_hwidth, // final int ml_hwidth,
ml_data_dbg1, // final double [] ml_center_corr,
null, // double [][] tcorr_combo,
false, // final boolean notch_mode,
tileX, // final int tileX, // only used in debug output
tileY, // final int tileY,
tile_lma_debug_level); // final int debugLevel)
......@@ -8640,6 +8667,7 @@ public class ImageDtt {
0, // ml_hwidth, // final int ml_hwidth,
null, // ml_data_inter, // final double [] ml_center_corr,
null, // tcorr_combo, // double [][] tcorr_combo,
false, // final boolean notch_mode,
tileX, // final int tileX, // only used in debug output
tileY, // final int tileY,
tile_lma_debug_level); // final int debugLevel)
......
......@@ -74,6 +74,12 @@ public class ImageDttParameters {
public double cnvx_weight = 0.5; // relative weight of non-convex (border) cell
public boolean cnvx_add3x3 = true; // always select 3x3 cells around integer maximum
// pole window will be inverted
public int corr_strip_notch = 11; // number of rows to calculate for vertical poles
public double corr_notch_hwidth = 2.0; // 6.0; // 50% window cutoff height
public double corr_notch_blur = 2.0; // 5.0; // 100% to 0 % vertical transition range
// Used for common interpolated stripes
public int corr_wndy_size = 2; // 9; // number of rows to calculate CM disparity
public double corr_wndy_hwidth = 1.0; // 6.0; // 50% window cutoff height
......@@ -100,6 +106,8 @@ public class ImageDttParameters {
public int lma_num_iter = 20; //
public int lma_debug_level = 3; //
public boolean corr_var_cam = true; // New correlation mode compatible with 8 subcameras
public double cm_max_normalization = 0.55; // fraction of correlation maximum radius, being squared multiplied by maximum to have the same total mass
public void dialogQuestions(GenericJTabbedDialog gd) {
gd.addCheckbox ("Enable ImageDtt correlation debug layers", this.corr_mode_debug,
......@@ -178,10 +186,19 @@ public class ImageDttParameters {
"Create selection mask for quadratic approximation inside square around initial maximum position, specify distance from the center");
gd.addNumericField("Relative weight of non-convex (border) cell", this.cnvx_weight, 6,8,"",
"Weight of the bi-convex points is 1.0, this value specifies reduced weight of the border (non-bi-convex) points");
gd.addCheckbox ("Always select 3x3 cells around integer maximum", this.cnvx_add3x3,
gd.addCheckbox ("Always select 3x3 cells around integer maximum", this.cnvx_add3x3,
"Add 3x3 cells selection around the original argmax, regardless of bi-convex property");
gd.addMessage("Window for pole detection mode");
gd.addNumericField("Strip height for pole detection", this.corr_strip_notch, 0, 3, "half-pix",
"Number of rows to combine/interpolate correlation results. Rows are twice denser than pixels correponding to largest baseline disparity");
gd.addNumericField("50% correlation window cutoff height for poles (0 in the center)",this.corr_notch_hwidth, 3, 6, "half-pix",
"Correlation window height argument for 50% value");
gd.addNumericField("0% to 100 % transition range for poles", this.corr_notch_blur, 3,6,"half-pix",
"Transition range, shifted sine is used");
gd.addMessage("Window for niormal correlations");
gd.addNumericField("Number of rows to calculate CM disparity", this.corr_wndy_size, 0, 3, "",
"Number of rows to calculate maximum. Normally should be equal to the previous parameter");
......@@ -233,6 +250,9 @@ public class ImageDttParameters {
gd.addCheckbox ("Use new correlation methods compatible with x8 camera", this.corr_var_cam,
"Debug feature to compare old/new methods");
gd.addNumericField("Normalization for the CM correlation strength", this.cm_max_normalization, 6, 8, "",
"Fraction of correlation maximum radius, being squared multiplied by maximum to have the same total mass. ~= 0.5, the lower the value, the higher strength reported by the CM");
// public double cm_max_normalization = 0.55; //
}
public void dialogAnswers(GenericJTabbedDialog gd) {
......@@ -285,6 +305,10 @@ public class ImageDttParameters {
this.cnvx_weight = gd.getNextNumber();
this.cnvx_add3x3 = gd.getNextBoolean();
this.corr_strip_notch= (int) gd.getNextNumber();
this.corr_notch_hwidth= gd.getNextNumber();
this.corr_notch_blur= gd.getNextNumber();
this.corr_wndy_size= (int) gd.getNextNumber();
this.corr_wndy_hwidth = gd.getNextNumber();
......@@ -314,6 +338,7 @@ public class ImageDttParameters {
this.lma_num_iter= (int) gd.getNextNumber();
this.lma_debug_level= (int) gd.getNextNumber();
this.corr_var_cam = gd.getNextBoolean();
this.cm_max_normalization= gd.getNextNumber();
}
......@@ -366,6 +391,11 @@ public class ImageDttParameters {
properties.setProperty(prefix+"cnvx_weight", this.cnvx_weight +"");
properties.setProperty(prefix+"cnvx_add3x3", this.cnvx_add3x3 +"");
properties.setProperty(prefix+"corr_strip_notch", this.corr_strip_notch +"");
properties.setProperty(prefix+"corr_notch_hwidth", this.corr_notch_hwidth +"");
properties.setProperty(prefix+"corr_notch_blur", this.corr_notch_blur +"");
properties.setProperty(prefix+"corr_wndy_size", this.corr_wndy_size +"");
properties.setProperty(prefix+"corr_wndy_hwidth", this.corr_wndy_hwidth +"");
properties.setProperty(prefix+"corr_wndy_blur", this.corr_wndy_blur +"");
......@@ -395,6 +425,9 @@ public class ImageDttParameters {
properties.setProperty(prefix+"lma_num_iter", this.lma_num_iter +"");
properties.setProperty(prefix+"lma_debug_level", this.lma_debug_level +"");
properties.setProperty(prefix+"corr_var_cam", this.corr_var_cam +"");
properties.setProperty(prefix+"cm_max_normalization", this.cm_max_normalization +"");
}
public void getProperties(String prefix,Properties properties){
......@@ -447,6 +480,12 @@ public class ImageDttParameters {
if (properties.getProperty(prefix+"cnvx_weight")!=null) this.cnvx_weight=Double.parseDouble(properties.getProperty(prefix+"cnvx_weight"));
if (properties.getProperty(prefix+"cnvx_add3x3")!=null) this.cnvx_add3x3=Boolean.parseBoolean(properties.getProperty(prefix+"cnvx_add3x3"));
if (properties.getProperty(prefix+"corr_strip_notch")!=null) this.corr_strip_notch=Integer.parseInt(properties.getProperty(prefix+"corr_strip_notch"));
if (properties.getProperty(prefix+"corr_notch_hwidth")!=null) this.corr_notch_hwidth=Double.parseDouble(properties.getProperty(prefix+"corr_notch_hwidth"));
if (properties.getProperty(prefix+"corr_notch_blur")!=null) this.corr_notch_blur=Double.parseDouble(properties.getProperty(prefix+"corr_notch_blur"));
if (properties.getProperty(prefix+"corr_wndy_size")!=null) this.corr_wndy_size=Integer.parseInt(properties.getProperty(prefix+"corr_wndy_size"));
if (properties.getProperty(prefix+"corr_wndy_hwidth")!=null) this.corr_wndy_hwidth=Double.parseDouble(properties.getProperty(prefix+"corr_wndy_hwidth"));
......@@ -478,6 +517,7 @@ public class ImageDttParameters {
if (properties.getProperty(prefix+"lma_debug_level")!=null) this.lma_debug_level=Integer.parseInt(properties.getProperty(prefix+"lma_debug_level"));
if (properties.getProperty(prefix+"corr_var_cam")!=null) this.corr_var_cam=Boolean.parseBoolean(properties.getProperty(prefix+"corr_var_cam"));
if (properties.getProperty(prefix+"cm_max_normalization")!=null) this.cm_max_normalization=Double.parseDouble(properties.getProperty(prefix+"cm_max_normalization"));
}
@Override
......@@ -530,6 +570,10 @@ public class ImageDttParameters {
idp.cnvx_weight= this.cnvx_weight;
idp.cnvx_add3x3= this.cnvx_add3x3;
idp.corr_strip_notch= this.corr_strip_notch;
idp.corr_notch_hwidth= this.corr_notch_hwidth;
idp.corr_notch_blur= this.corr_notch_blur;
idp.corr_wndy_size= this.corr_wndy_size;
idp.corr_wndy_hwidth = this.corr_wndy_hwidth;
......@@ -559,6 +603,8 @@ public class ImageDttParameters {
idp.lma_debug_level = this.lma_debug_level;
idp.corr_var_cam = this.corr_var_cam;
idp.cm_max_normalization= this.cm_max_normalization;
return idp;
}
}
......@@ -32,7 +32,7 @@ public class TwoQuadCLT {
public long startTime; // start of batch processing
public long startSetTime; // start of set processing
public long startStepTime; // start of step processing
BiCamDSI biCamDSI_persistent; // may be removed later to save memory, now to be able to continue
public void processCLTQuadCorrs(
QuadCLT quadCLT_main,
......@@ -222,6 +222,7 @@ public class TwoQuadCLT {
rgbParameters, // EyesisCorrectionParameters.RGBParameters rgbParameters,
scaleExposures_main, // double [] scaleExposures_main, // probably not needed here - restores brightness of the final image
scaleExposures_aux, // double [] scaleExposures_aux, // probably not needed here - restores brightness of the final image
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
// final boolean apply_corr, // calculate and apply additional fine geometry correction
// final boolean infinity_corr, // calculate and apply geometry correction at infinity
threadsMax, // final int threadsMax, // maximal number of threads to launch
......@@ -260,8 +261,7 @@ public class TwoQuadCLT {
EyesisCorrectionParameters.RGBParameters rgbParameters,
double [] scaleExposures_main, // probably not needed here - restores brightness of the final image
double [] scaleExposures_aux, // probably not needed here - restores brightness of the final image
// final boolean apply_corr, // calculate and apply additional fine geometry correction
// final boolean infinity_corr, // calculate and apply geometry correction at infinity
boolean notch_mode, // use pole-detection mode for inter-camera correlation
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
......@@ -339,6 +339,7 @@ public class TwoQuadCLT {
image_dtt.clt_bi_quad (
clt_parameters, // final EyesisCorrectionParameters.CLTParameters clt_parameters,
clt_parameters.fat_zero, // final double fatzero, // May use correlation fat zero from 2 different parameters - fat_zero and rig.ml_fatzero
notch_mode, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
tile_op_main, // final int [][] tile_op_main, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
// tile_op_aux, // final int [][] tile_op_aux, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
disparity_array_main, // final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
......@@ -863,6 +864,7 @@ public class TwoQuadCLT {
0.0, // double disparity,
null, // ArrayList<Integer> tile_list, // or null. If non-null - do not remeasure members of the list
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -1015,6 +1017,7 @@ if (debugLevel > -100) return true; // temporarily !
disparity, // double disparity,
tile_list, // ArrayList<Integer> tile_list, // or null. If non-null - do not remeasure members of the list
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -1048,6 +1051,7 @@ if (debugLevel > -100) return true; // temporarily !
null, // tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -1082,6 +1086,7 @@ if (debugLevel > -100) return true; // temporarily !
null, // tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -1133,6 +1138,7 @@ if (debugLevel > -100) return true; // temporarily !
tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -1180,7 +1186,17 @@ if (debugLevel > -100) return true; // temporarily !
return true;
}
public void processPoles(
// QuadCLT quadCLT_main, // tiles should be set
// QuadCLT quadCLT_aux,
BiCamDSI biCamDSI,
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)// throws Exception
{
System.out.println("**** Nothing here yet ****");
}
// improve DSI acquired for a single camera by use of a pair
// Run this after "CLT 3D"
......@@ -1204,6 +1220,7 @@ if (debugLevel > -100) return true; // temporarily !
}
double [][] rig_disparity_strength = quadCLT_main.getGroundTruthByRig();
if (rig_disparity_strength == null) {
if (use_planes) {
rig_disparity_strength = groundTruthByRigPlanes(
......@@ -1450,6 +1467,7 @@ if (debugLevel > -100) return true; // temporarily !
image_dtt.clt_bi_quad (
clt_parameters, // final EyesisCorrectionParameters.CLTParameters clt_parameters,
clt_parameters.fat_zero, // final double fatzero, // May use correlation fat zero from 2 different parameters - fat_zero and rig.ml_fatzero
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
tile_op, // final int [][] tile_op_main, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
disparity_array, // final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
quadCLT_main.image_data, // final double [][][] image_data_main, // first index - number of image in a quad
......@@ -1599,6 +1617,7 @@ if (debugLevel > -100) return true; // temporarily !
0, // double disparity,
null, // ArrayList<Integer> tile_list, // or null. If non-null - do not remeasure members of the list
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -1642,6 +1661,7 @@ if (debugLevel > -100) return true; // temporarily !
trusted_infinity, // tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -1749,6 +1769,7 @@ if (debugLevel > -100) return true; // temporarily !
trusted_near, // tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -1814,7 +1835,7 @@ if (debugLevel > -100) return true; // temporarily !
}
}
if (clt_parameters.show_map && (debugLevel > 0) && clt_parameters.rig.rig_mode_debug){
if (clt_parameters.show_map && (debugLevel > -3) && clt_parameters.rig.rig_mode_debug){
(new showDoubleFloatArrays()).showArrays(
disparity_bimap,
tilesX,
......@@ -1837,10 +1858,99 @@ if (debugLevel > -100) return true; // temporarily !
tilesX,
disparity_bimap[0].length/tilesX,
true,
quadCLT_main.image_name+"-DSI-ALL-TRUSTED"+clt_parameters.disparity,
quadCLT_main.image_name+"-DSI-ALL-TRUSTED",
ImageDtt.BIDISPARITY_TITLES);
}
// just testing - copy and run in pole detection mode (TODO: Remove)
if (debugLevel > -100) return disparity_bimap;
// need to re-measure
double [][] disparity_bimap_poles = measureNewRigDisparity(
quadCLT_main, // QuadCLT quadCLT_main, // tiles should be set
quadCLT_aux, // QuadCLT quadCLT_aux,
disparity_bimap[ImageDtt.BI_TARGET_INDEX], // double [] disparity, // Double.NaN - skip, ohers - measure
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
true, // boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // +4); // final int debugLevel);
(new showDoubleFloatArrays()).showArrays(
disparity_bimap_poles,
tilesX,
disparity_bimap[0].length/tilesX,
true,
quadCLT_main.image_name+"-INITIAL-POLES",
ImageDtt.BIDISPARITY_TITLES);
for (int i = 0; i < scale_bad.length; i++) scale_bad[i] = 1.0;
prev_bimap = null;
for (int nref = 0; nref < clt_parameters.rig.num_near_refine; nref++) {
// refine infinity using inter correlation
double [][] disparity_bimap_new = refineRigSel(
quadCLT_main, // QuadCLT quadCLT_main, // tiles should be set
quadCLT_aux, // QuadCLT quadCLT_aux,
disparity_bimap_poles, // double [][] src_bimap, // current state of measurements (or null for new measurement)
prev_bimap, // double [][] prev_bimap, // previous state of measurements or null
scale_bad, // double [] scale_bad,
refine_inter, // int refine_mode, // 0 - by main, 1 - by aux, 2 - by inter
false, // boolean keep_inf, // keep expected disparity 0.0 if it was so
0.0, // clt_parameters.rig.refine_min_strength , // double refine_min_strength, // do not refine weaker tiles
clt_parameters.rig.refine_tolerance , // double refine_tolerance, // do not refine if absolute disparity below
trusted_near, // tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
true, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
prev_bimap = disparity_bimap_poles;
disparity_bimap_poles = disparity_bimap_new;
trusted_near = getTrustedDisparity(
quadCLT_main, // QuadCLT quadCLT_main, // tiles should be set
quadCLT_aux, // QuadCLT quadCLT_aux,
clt_parameters.rig.min_trusted_strength, // double min_combo_strength, // check correlation strength combined for all 3 correlations
clt_parameters.grow_disp_trust, // double max_trusted_disparity, // 4.0 -> change to rig_trust
clt_parameters.rig.trusted_tolerance, // double trusted_tolerance,
trusted_near, // null, // boolean [] was_trusted,
disparity_bimap_poles ); // double [][] bimap // current state of measurements
if (debugLevel > -2) {
System.out.println("enhanceByRig(): refined (poles) "+num_new[0]+" tiles");
}
if (num_new[0] < clt_parameters.rig.min_new) break;
}
if (clt_parameters.show_map && (debugLevel > -2) && clt_parameters.rig.rig_mode_debug){
if (scale_bad!= null) {
int num_bad = 0, num_trusted = 0;
for (int nTile = 0; nTile < scale_bad.length; nTile++) {
if (!trusted_near[nTile]) scale_bad[nTile] = Double.NaN;
else {
if (scale_bad[nTile] < 1.0) num_bad++;
scale_bad[nTile] = -scale_bad[nTile];
num_trusted ++;
}
}
System.out.println("num_trusted = "+num_trusted+", num_bad = "+num_bad);
(new showDoubleFloatArrays()).showArrays(
scale_bad,
tilesX,
disparity_bimap_poles[0].length/tilesX,
quadCLT_main.image_name+"-NEAR-SCALE_BAD_POLES"+clt_parameters.disparity);
}
(new showDoubleFloatArrays()).showArrays(
disparity_bimap_poles,
tilesX,
disparity_bimap_poles[0].length/tilesX,
true,
quadCLT_main.image_name+"-POLES-REFINED-TRUSTED",
ImageDtt.BIDISPARITY_TITLES);
}
// END OF just testing - copy and run in pole detection mode (TODO: Remove)
return disparity_bimap;
}
......@@ -1853,7 +1963,8 @@ if (debugLevel > -100) return true; // temporarily !
final boolean updateStatus,
final int debugLevel) // throws Exception
{
final int num_full_cycles = 3; // Number of full low-texture cycles that include growing flat LT and trimmin weak FG over BG
final int num_tries_strongest_by_fittest = 5;
final int num_full_cycles = clt_parameters.rig.pf_en_trim_fg? 3 : 1; // Number of full low-texture cycles that include growing flat LT and trimmin weak FG over BG
final int num_cross_gaps_cycles = 20; // maximalnumger of adding new tiles cycles while "crossing the gaps)
final int min_cross_gaps_new = 20; // minimal number of the new added tiles
final int refine_inter = 2; // 3; // 3 - dx, 2 - disparity
......@@ -1948,6 +2059,7 @@ if (debugLevel > -100) return true; // temporarily !
*/
num_added_tiles = last_scan.suggestNewScan(
null, // final double [][] disparityStrength,
clt_parameters.rig.pf_trusted_strength, // final double trusted_strength, // trusted correlation strength
clt_parameters.rig.pf_strength_rfloor, // final double strength_rfloor, // strength floor - relative to trusted
clt_parameters.rig.pf_discard_cond, // final boolean discard_cond, // consider conditionally trusted tiles (not promoted to trusted) as empty
......@@ -1969,6 +2081,13 @@ if (debugLevel > -100) return true; // temporarily !
clt_parameters.rig.pf_rwsigma_narrow, // final double rwsigma_narrow, // = used to determine initial tilt
clt_parameters.rig.pf_new_diff, // final double new_diff, // minimal difference between the new suggested and the already tried/measured one
true, // final boolean remove_all_tried, // remove from suggested - not only disabled, but all tried
0.0, // final double center_weight, // use center tile too (0.0 - do not use)
clt_parameters.rig.pf_use_alt, // final boolean use_alt, // use tiles from other scans if they fit better
clt_parameters.rig.pf_goal_fraction_rms,// final double goal_fraction_rms, // Try to make rms to be this fraction of maximal acceptable by removing outliers
clt_parameters.rig.pf_boost_low_density,// NOT USED HERE, MAY BE 0, // final double boost_low_density, // 0 - strength is proportional to 1/density, 1.0 - same as remaining tiles
null, // final double [] smooth_strength, // optionally fill strength array when used for smoothing DSI
0, // final int fourq_min, // each of the 4 corners should have at least this number of tiles.
0, // final int fourq_gap, // symmetrical vertical and horizontal center areas that do not belong to any corner
clt_parameters.tileX, // final int dbg_x,
clt_parameters.tileY, // final int dbg_y,
debugLevel); // final int debugLevel);
......@@ -1980,7 +2099,7 @@ if (debugLevel > -100) return true; // temporarily !
//num_cycle < num_cross_gaps_cycles;
boolean last_cycle = (num_added_tiles < min_cross_gaps_new) || (num_cycle >= (num_cross_gaps_cycles-1));
if (clt_parameters.show_map && (debugLevel > -2) && clt_parameters.rig.rig_mode_debug){
if (last_cycle || (num_cycle < 2 * dxy.length))
if (last_cycle) // || (num_cycle < 2 * dxy.length))
biCamDSI.getLastBiScan().showScan(
quadCLT_main.image_name+"-BISCAN_SUGGESTED"+num_fcycle+"-"+num_cycle);
}
......@@ -2039,6 +2158,7 @@ if (debugLevel > -100) return true; // temporarily !
// suggest again, after trimming
int num_added_tiles_trimmed = last_scan.suggestNewScan(
null, // final double [][] disparityStrength,
clt_parameters.rig.pf_trusted_strength, // final double trusted_strength, // trusted correlation strength
clt_parameters.rig.pf_strength_rfloor, // final double strength_rfloor, // strength floor - relative to trusted
clt_parameters.rig.pf_discard_cond, // final boolean discard_cond, // consider conditionally trusted tiles (not promoted to trusted) as empty
......@@ -2060,6 +2180,13 @@ if (debugLevel > -100) return true; // temporarily !
clt_parameters.rig.pf_rwsigma_narrow, // final double rwsigma_narrow, // = used to determine initial tilt
clt_parameters.rig.pf_new_diff, // final double new_diff, // minimal difference between the new suggested and the already tried/measured one
true, // final boolean remove_all_tried, // remove from suggested - not only disabled, but all tried
0.0, // final double center_weight, // use center tile too (0.0 - do not use)
clt_parameters.rig.pf_use_alt, // final boolean use_alt, // use tiles from other scans if they fit better
clt_parameters.rig.pf_goal_fraction_rms,// final double goal_fraction_rms, // Try to make rms to be this fraction of maximal acceptable by removing outliers
clt_parameters.rig.pf_boost_low_density,// NOT USED HERE, MAY BE 0, // final double boost_low_density, // 0 - strength is proportional to 1/density, 1.0 - same as remaining tiles
null, // final double [] smooth_strength, // optionally fill strength array when used for smoothing DSI
0, // final int fourq_min, // each of the 4 corners should have at least this number of tiles.
0, // final int fourq_gap, // symmetrical vertical and horizontal center areas that do not belong to any corner
clt_parameters.tileX, // final int dbg_x,
clt_parameters.tileY, // final int dbg_y,
debugLevel); // final int debugLevel);
......@@ -2084,6 +2211,7 @@ if (debugLevel > -100) return true; // temporarily !
quadCLT_aux, // QuadCLT quadCLT_aux,
target_disparity, // double [] disparity, // Double.NaN - skip, ohers - measure
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -2127,6 +2255,7 @@ if (debugLevel > -100) return true; // temporarily !
trusted_measurements, // tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -2191,7 +2320,7 @@ if (debugLevel > -100) return true; // temporarily !
double afloor = clt_parameters.rig.pf_trusted_strength * clt_parameters.rig.pf_strength_rfloor;
// replace strongest by fittest
for (int nfit = 0; nfit < 5; nfit++) {
for (int nfit = 0; nfit < num_tries_strongest_by_fittest; nfit++) {
int num_replaced = biCamDSI.getLastBiScan().copyFittestEnabled(
afloor, // final double str_floor, // absolute strength floor
clt_parameters.rig.pf_disp_afloor, // final double pf_disp_afloor, // = 0.1; // When selecting the best fit from the alternative disparities, divide by difference increased by this
......@@ -2224,10 +2353,267 @@ if (debugLevel > -100) return true; // temporarily !
false, // boolean only_trusted,
true); // boolean only_enabled,
biCamDSI_persistent = biCamDSI; // save for pole detection
return rig_disparity_strength;
}
public boolean showBiScan(
QuadCLT quadCLT_main, // tiles should be set
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int debugLevel) // throws Exception
{
if ((quadCLT_main == null) ||
(quadCLT_main.tp == null) ||
(quadCLT_main.tp.clt_3d_passes == null) ||
(biCamDSI_persistent== null) ||
(biCamDSI_persistent.biScans== null)) {
String msg = "Data is not available. Please run \"Ground truth\" first";
IJ.showMessage("Error",msg);
System.out.println(msg);
return false;
}
int scan_index = biCamDSI_persistent.biScans.size()-1;
boolean show_smooth = true;
boolean keep_unreliable = false;
boolean keep_weak = false;
boolean keep_strong = false;
double center_weight = 1.0;
// from clt_parameters.rig
double trusted_strength = clt_parameters.rig.pf_trusted_strength;
double cond_rtrusted = clt_parameters.rig.pf_cond_rtrusted;
double strength_rfloor = clt_parameters.rig.pf_strength_rfloor;
double strength_pow = clt_parameters.rig.pf_strength_pow;
int smpl_radius = clt_parameters.rig.pf_smpl_radius;
int smpl_num = clt_parameters.rig.pf_smpl_num;
int smpl_num_narrow = clt_parameters.rig.pf_smpl_num_narrow;
double smpl_fract = clt_parameters.rig.pf_smpl_fract;
double max_adiff = clt_parameters.rig.pf_max_adiff;
double max_rdiff = clt_parameters.rig.pf_max_rdiff;
double max_atilt = clt_parameters.rig.pf_max_atilt;
double max_rtilt = clt_parameters.rig.pf_max_rtilt;
double smpl_arms = clt_parameters.rig.pf_smpl_arms;
double smpl_rrms = clt_parameters.rig.pf_smpl_rrms;
double damp_tilt = clt_parameters.rig.pf_damp_tilt;
double rwsigma = clt_parameters.rig.pf_rwsigma;
double rwsigma_narrow = clt_parameters.rig.pf_rwsigma_narrow;
boolean use_alt = clt_parameters.rig.pf_use_alt;
double goal_fraction_rms= clt_parameters.rig.pf_goal_fraction_rms; // Try to make rms to be this fraction of maximal acceptable by removing outliers
double boost_low_density= clt_parameters.rig.pf_boost_low_density; // Strength assigned to fake tiles from neighbors (the lower - the higher)
int fourq_min = clt_parameters.rig.pf_fourq_min;
int fourq_gap = clt_parameters.rig.pf_fourq_gap;
double min_disparity = 0.0;
GenericJTabbedDialog gd = new GenericJTabbedDialog("Set CLT parameters",800,900);
gd.addNumericField("Scan index (0..."+(biCamDSI_persistent.biScans.size()-1), scan_index, 0, 2, "", "Display scan by index");
gd.addCheckbox ("Show smooth disparity/strength for the selected scan", show_smooth, "Unchecked - just as is");
gd.addCheckbox ("Keep unreliable tiles", keep_unreliable, "Unchecked - overwrite with smooth data");
gd.addCheckbox ("Keep weak (but trusted) tiles", keep_weak, "Unchecked - overwrite with smooth data");
gd.addCheckbox ("Keep strng trusted tiles", keep_strong, "Unchecked - overwrite with smooth data");
gd.addNumericField("Center weight - relative weight of the existing tile ", center_weight, 4,6,"",
"0.0 - suggest new disparity over existing tiles without ant regard to the original value, 1.0 - same influence as any other tile");
gd.addNumericField("Minimal disparity to apply filter", min_disparity, 4,6,"pix",
"Farther objects will not be filtered");
gd.addMessage ("Parameters that are copied from the CLT parameters");
gd.addNumericField("Strength sufficient without neighbors", trusted_strength, 4,6,"",
"Unconditionally trusted tile. Other stength values are referenceds as fraction of this value (after strength floor subtraction)");
gd.addNumericField("Strength sufficient with neighbors support, fraction of the trusted strength", cond_rtrusted, 4,6,"",
"Strength that may be valid for the tile if there are neighbors in the same possibly tilted plane of the DSI (floor corrected)");
gd.addNumericField("Fraction of trusted strength to subtract", strength_rfloor, 4,6,"",
"Strength floor to subtract from all strength values");
gd.addNumericField("Raise strength-floor to this power", strength_pow, 4,6,"",
"Currently just 1.0 - lenear");
gd.addNumericField("How far to extend around known tiles (probably should increase this value up to?", smpl_radius, 0,3,"tiles",
"Process a aquare centered at the current tile withthe side of twice this value plus 1 (2*pf_smpl_radius + 1)");
gd.addNumericField("Number after remaining in the sample square after removing worst fitting tiles", smpl_num, 0,3,"",
"When fitting planes the outliers are removed until the number of remaining tiles equals this value");
gd.addNumericField("Number of remaining tiles when using narrow selection", smpl_num_narrow, 0,3,"",
"Number of remaining tiles during initial palne fitting to the center pixels (it is later extended to include farther tiles)");
gd.addNumericField("Fraction of the reamining tiles of all non-zero tiles?", smpl_fract, 4,6,"",
"This value is combined to the previous one (absilute). Maximal of absolute and relative times number of all non-empty tiles is used");
gd.addNumericField("Maximal absolute disparity difference between the plane and tiles that fit", max_adiff, 4,6,"pix",
"Maximal absolute disparity difference for fitting. Combined with the next one (relative) ");
gd.addNumericField("Maximal relative (to center disparity) difference between the plane and tiles that fit",max_rdiff, 4,6,"pix/pix",
"This value is multipled by the tile disparity and added to the maximal absolute difference");
gd.addNumericField("Maximal absolute tile tilt in DSI space", max_atilt, 4,6,"pix/tile",
"Maximal disparity difference betweeing neighbor tiles for the tilted plane. Combined with the relative one (next), min of both limits applies");
gd.addNumericField("Maximal relative (per pixel of disparity) tile tilt in DSI space", max_rtilt, 4,6,"1/tile",
"Maximal relative (to center disparity) tilt. Near tiles (larger disparity may have larger differnce.");
gd.addNumericField("Maximal absolute RMS of the remaining tiles in a sample", smpl_arms, 4,6,"pix",
"After removing outliers RMS of the remaining tiles must be less than this value");
gd.addNumericField("Maximal relative (to center disparity) RMS of the remaining tiles in a sample", smpl_rrms, 4,6,"pix/pix",
"Relative RMS times disparity is added to the absolute one");
gd.addNumericField("Tilt cost for damping insufficient plane data", damp_tilt, 4,6,"",
"Regularisation to handle co-linear and even single-point planes, forcing fronto-parallel for single point, and minimal tilt for co-linear set");
gd.addNumericField("Influence of far neighbors is reduced as a Gaussian with this sigma", rwsigma, 4,6,"",
"Sigma is relative to selection radius (square half-side)");
gd.addNumericField("Weight function Gaussian sigma (relative to radius) for initial plane fitting", rwsigma_narrow, 4,6,"",
"Weight function Gaussian sigma (relative to selection radius) for initial plane fitting. May be ~=1/radius");
gd.addCheckbox ("When fitting planes, look for alternative measure tiles",use_alt, "Unchecked - only use the latest (current) tile");
gd.addNumericField("Try to make rms to be this fraction of maximal acceptable by removing outliers", goal_fraction_rms, 4,6,"pix",
"When removing outliers to fit planes, stop removing when the RMS of the remaining drops below this fraction of the maxium allowed RMS (should be < 1.0");
gd.addNumericField("Strength assigned to fake tiles from neighbors (the lower - the higher)", boost_low_density, 4,6,"pix",
"Returned strength assigned to the tiles increases with this value - seems to be a bug");
gd.addNumericField("Each of the 4 corners should have at least this number of tiles", fourq_min, 0,3,"",
"Apply (>0) only for filling gaps, not during expansion. It requires that every of the 4 corners of the sample square has this number of tiles for a plane");
gd.addNumericField("Four corners center gap half-width (1 - 1 tile, 2 - 3 tiles, 3 - 5 tiles, ...", fourq_gap, 0,3,"",
"Specifies corners of the sample square that should have tiles remain, after removing centre columns and center rows");
gd.showDialog();
if (gd.wasCanceled()) return false;
scan_index = (int) gd.getNextNumber();
show_smooth = gd.getNextBoolean();
keep_unreliable = gd.getNextBoolean();
keep_weak = gd.getNextBoolean();
keep_strong = gd.getNextBoolean();
center_weight = gd.getNextNumber();
min_disparity = gd.getNextNumber();
// from clt_parameters.rig
trusted_strength = gd.getNextNumber();
cond_rtrusted = gd.getNextNumber();
strength_rfloor = gd.getNextNumber();
strength_pow = gd.getNextNumber();
smpl_radius = (int) gd.getNextNumber();
smpl_num = (int) gd.getNextNumber();
smpl_num_narrow = (int) gd.getNextNumber();
smpl_fract = gd.getNextNumber();
max_adiff = gd.getNextNumber();
max_rdiff = gd.getNextNumber();
max_atilt = gd.getNextNumber();
max_rtilt = gd.getNextNumber();
smpl_arms = gd.getNextNumber();
smpl_rrms = gd.getNextNumber();
damp_tilt = gd.getNextNumber();
rwsigma = gd.getNextNumber();
rwsigma_narrow = gd.getNextNumber();
use_alt = gd.getNextBoolean();
goal_fraction_rms= gd.getNextNumber();
boost_low_density= gd.getNextNumber();
fourq_min= (int) gd.getNextNumber();
fourq_gap= (int) gd.getNextNumber();
System.out.println(" === showBiScan( parameters : =====");
System.out.println(" scan_index= "+scan_index);
System.out.println(" show_smooth= "+show_smooth);
System.out.println(" keep_unreliable= "+keep_unreliable);
System.out.println(" keep_weak= "+keep_weak);
System.out.println(" keep_strong= "+keep_strong);
System.out.println(" center_weight= "+center_weight);
System.out.println(" min_disparity= "+min_disparity);
System.out.println(" trusted_strength= "+trusted_strength);
System.out.println(" cond_rtrusted= "+cond_rtrusted);
System.out.println(" strength_rfloor= "+strength_rfloor);
System.out.println(" strength_pow= "+strength_pow);
System.out.println(" smpl_radius= "+smpl_radius);
System.out.println(" smpl_num= "+smpl_num);
System.out.println(" smpl_num_narrow= "+smpl_num_narrow);
System.out.println(" smpl_fract= "+smpl_fract);
System.out.println(" max_adiff= "+max_adiff);
System.out.println(" max_rdiff= "+max_rdiff);
System.out.println(" max_atilt= "+max_atilt);
System.out.println(" max_rtilt= "+max_rtilt);
System.out.println(" smpl_arms= "+smpl_arms);
System.out.println(" smpl_rrms= "+smpl_rrms);
System.out.println(" damp_tilt= "+damp_tilt);
System.out.println(" rwsigma= "+rwsigma);
System.out.println(" rwsigma_narrow= "+rwsigma_narrow);
System.out.println(" use_alt= "+use_alt);
System.out.println("goal_fraction_rms= "+goal_fraction_rms);
System.out.println("boost_low_density= "+boost_low_density);
System.out.println(" fourq_min= "+fourq_min);
System.out.println(" fourq_gap= "+fourq_gap);
BiScan biScan = biCamDSI_persistent.biScans.get(scan_index);
double [][] ds = null;
if (show_smooth) {
// find strongest
biCamDSI_persistent.getLastBiScan().copyLastStrongestEnabled(
clt_parameters.rig.pf_last_priority); // final boolean last_priority)
double afloor = trusted_strength * strength_rfloor;
int num_tries_strongest_by_fittest = 5;
// replace strongest by fittest
for (int nfit = 0; nfit < num_tries_strongest_by_fittest; nfit++) {
int num_replaced = biCamDSI_persistent.getLastBiScan().copyFittestEnabled(
afloor, // final double str_floor, // absolute strength floor
clt_parameters.rig.pf_disp_afloor, // final double pf_disp_afloor, // = 0.1; // When selecting the best fit from the alternative disparities, divide by difference increased by this
clt_parameters.rig.pf_disp_rfloor); // final double pf_disp_rfloor) // = 0.02; // Increase pf_disp_afloor for large disparities
if ((debugLevel > -2) && clt_parameters.rig.rig_mode_debug){
System.out.println("groundTruthByRigPlanes(): Replacing strongest by fittest: ntry = "+nfit+", replaced "+num_replaced+" tiles");
}
if (num_replaced == 0) {
break;
}
}
biScan.calcTrusted( // finds strong trusted and validates week ones if they fit planes
trusted_strength, // final double trusted_strength, // trusted correlation strength
strength_rfloor, // final double strength_rfloor, // strength floor - relative to trusted
cond_rtrusted, // final double cond_rtrusted, // minimal strength to consider - fraction of trusted
strength_pow, // final double strength_pow, // raise strength-floor to this power
smpl_radius, // final int smpl_radius,
smpl_num, // final int smpl_num, // = 3; // Number after removing worst (should be >1)
smpl_fract, // final double smpl_fract, // Number of friends among all neighbors
max_adiff, // final double max_adiff, // Maximal absolute difference betweenthe center tile and friends
max_rdiff, // final double max_rdiff, // Maximal relative difference between the center tile and friends
max_atilt, // final double max_atilt, // = 2.0; // pix per tile
max_rtilt, // final double max_rtilt, // = 0.2; // (pix / disparity) per tile
smpl_arms, // final double smpl_arms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
smpl_rrms, // final double smpl_rrms, // = 0.005; // Maximal RMS/disparity in addition to smplRms
damp_tilt, // final double damp_tilt, // = 0.001; // Tilt cost for damping insufficient plane data
rwsigma, // final double rwsigma, // = 0.7; // influence of far neighbors diminish as a Gaussian with this sigma
clt_parameters.tileX, // final int dbg_x,
clt_parameters.tileY, // final int dbg_y,
debugLevel); // final int debugLevel);
ds = biScan.getFilteredDisparityStrength(
null, // final double [][] disparityStrength,
min_disparity, // final double min_disparity, // keep original disparity far tiles
trusted_strength, // final double trusted_strength, // trusted correlation strength
strength_rfloor, // final double strength_rfloor, // strength floor - relative to trusted
!keep_unreliable, // final boolean discard_unreliable,// replace v
!keep_weak, // final boolean discard_weak, // consider weak trusted tiles (not promoted to trusted) as empty
!keep_strong, // final boolean discard_strong, // suggest new disparitieas even for strong tiles
strength_pow, // final double strength_pow, // raise strength-floor to this power
null, // final double [] smpl_radius_array, // space-variant radius
smpl_radius, // final int smpl_radius,
smpl_num, // final int smpl_num, // = 3; // Number after removing worst (should be >1)
smpl_fract, // final double smpl_fract, // Number of friends among all neighbors
smpl_num_narrow, // final int smpl_num_narrow, // = 3; // Number after removing worst (should be >1)
max_adiff, // final double max_adiff, // Maximal absolute difference betweenthe center tile and friends
max_rdiff, // final double max_rdiff, // Maximal relative difference between the center tile and friends
max_atilt, // final double max_atilt, // = 2.0; // pix per tile
max_rtilt, // final double max_rtilt, // = 0.2; // (pix / disparity) per tile
smpl_arms, // final double smpl_arms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
smpl_rrms, // final double smpl_rrms, // = 0.005; // Maximal RMS/disparity in addition to smplRms
damp_tilt, // final double damp_tilt, // = 0.001; // Tilt cost for damping insufficient plane data
rwsigma, // final double rwsigma, // = 0.7; // influence of far neighbors diminish as a Gaussian with this sigma
rwsigma_narrow, // final double rwsigma_narrow, // = used to determine initial tilt
center_weight, // final double center_weight, // use center tile too (0.0 - do not use)
use_alt, // final boolean use_alt, // use tiles from other scans if they fit better
goal_fraction_rms, // final double goal_fraction_rms, // Try to make rms to be this fraction of maximal acceptable by removing outliers
boost_low_density, //final double boost_low_density, // 0 - strength is proportional to 1/density, 1.0 - same as remaining tiles
fourq_min, // final int fourq_min, // each of the 4 corners should have at least this number of tiles.
fourq_gap, // final int fourq_gap, // symmetrical vertical and horizontal center areas that do not belong to any corner
clt_parameters.tileX, // final int dbg_x,
clt_parameters.tileY, // final int dbg_y,
debugLevel+2); // final int debugLevel
}
biScan.showScan("BiScan-"+scan_index,ds);
return true;
}
public double [][] groundTruthByRig(
......@@ -2305,6 +2691,8 @@ if (debugLevel > -100) return true; // temporarily !
0, // double disparity,
null, // ArrayList<Integer> tile_list, // or null. If non-null - do not remeasure members of the list
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -2348,6 +2736,7 @@ if (debugLevel > -100) return true; // temporarily !
trusted_infinity, // tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -2454,6 +2843,7 @@ if (debugLevel > -100) return true; // temporarily !
trusted_near, // tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -2723,6 +3113,7 @@ if (debugLevel > -100) return true; // temporarily !
quadCLT_main, // QuadCLT quadCLT_main, // tiles should be set
quadCLT_aux, // QuadCLT quadCLT_aux,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -2759,6 +3150,7 @@ if (debugLevel > -100) return true; // temporarily !
trusted_lt, // null, // trusted_lt, // tile_list, // ArrayList<Integer> tile_list, // or null
num_new, // int [] num_new,
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -3125,6 +3517,7 @@ if (debugLevel > -100) return true; // temporarily !
null, // double [][] ml_data, // data for ML - 10 layers - 4 center areas (3x3, 5x5,..) per camera-per direction, 1 - composite, and 1 with just 1 data (target disparity)
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
clt_parameters.fat_zero, // double fatzero,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -3149,6 +3542,7 @@ if (debugLevel > -100) return true; // temporarily !
QuadCLT quadCLT_main, // tiles should be set
QuadCLT quadCLT_aux,
EyesisCorrectionParameters.CLTParameters clt_parameters,
boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
......@@ -3175,6 +3569,7 @@ if (debugLevel > -100) return true; // temporarily !
null, // double [][] ml_data, // data for ML - 10 layers - 4 center areas (3x3, 5x5,..) per camera-per direction, 1 - composite, and 1 with just 1 data (target disparity)
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
clt_parameters.fat_zero, // double fatzero,
notch_mode, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel);
......@@ -3272,6 +3667,8 @@ if (debugLevel > -100) return true; // temporarily !
ArrayList<Integer> tile_list, // or null
int [] num_new,
EyesisCorrectionParameters.CLTParameters clt_parameters,
boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
......@@ -3293,6 +3690,7 @@ if (debugLevel > -100) return true; // temporarily !
selection,
num_new,
clt_parameters,
notch_mode, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
......@@ -3311,6 +3709,7 @@ if (debugLevel > -100) return true; // temporarily !
boolean [] selection,
int [] num_new,
EyesisCorrectionParameters.CLTParameters clt_parameters,
final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
......@@ -3360,6 +3759,7 @@ if (debugLevel > -100) return true; // temporarily !
null, // double [][] ml_data, // data for ML - 10 layers - 4 center areas (3x3, 5x5,..) per camera-per direction, 1 - composite, and 1 with just 1 data (target disparity)
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
clt_parameters.fat_zero, // double fatzero,
notch_mode, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, //final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel)
......@@ -3406,6 +3806,7 @@ if (debugLevel > -100) return true; // temporarily !
double disparity,
ArrayList<Integer> tile_list, // or null. If non-null - do not remeasure members of the list
EyesisCorrectionParameters.CLTParameters clt_parameters,
boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
......@@ -3441,6 +3842,7 @@ if (debugLevel > -100) return true; // temporarily !
null, // double [][] ml_data, // data for ML - 10 layers - 4 center areas (3x3, 5x5,..) per camera-per direction, 1 - composite, and 1 with just 1 data (target disparity)
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
clt_parameters.fat_zero, // double fatzero,
notch_mode, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, //final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel)
......@@ -3493,6 +3895,7 @@ if (debugLevel > -100) return true; // temporarily !
QuadCLT quadCLT_aux,
double [] disparity, // Double.NaN - skip, ohers - measure
EyesisCorrectionParameters.CLTParameters clt_parameters,
boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
......@@ -3519,9 +3922,10 @@ if (debugLevel > -100) return true; // temporarily !
null, // double [][] ml_data, // data for ML - 10 layers - 4 center areas (3x3, 5x5,..) per camera-per direction, 1 - composite, and 1 with just 1 data (target disparity)
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
clt_parameters.fat_zero, // double fatzero,
notch_mode, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, //final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel)
debugLevel); // final int debugLevel)
return disparity_bimap;
}
......@@ -3642,6 +4046,7 @@ if (debugLevel > -100) return true; // temporarily !
double [][] ml_data, // data for ML - 10 layers - 4 center areas (3x3, 5x5,..) per camera-per direction, 1 - composite, and 1 with just 1 data (target disparity)
EyesisCorrectionParameters.CLTParameters clt_parameters,
double fatzero,
boolean notch_mode, // use pole-detection mode for inter-camera correlation
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel){
......@@ -3652,6 +4057,7 @@ if (debugLevel > -100) return true; // temporarily !
image_dtt.clt_bi_quad (
clt_parameters, // final EyesisCorrectionParameters.CLTParameters clt_parameters,
fatzero, // final double fatzero, // May use correlation fat zero from 2 different parameters - fat_zero and rig.ml_fatzero
notch_mode, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
tile_op, // final int [][] tile_op_main, // [tilesY][tilesX] - what to do - 0 - nothing for this tile
disparity_array, // final double [][] disparity_array, // [tilesY][tilesX] - individual per-tile expected disparity
quadCLT_main.image_data, // final double [][][] image_data_main, // first index - number of image in a quad
......@@ -3753,6 +4159,7 @@ if (debugLevel > -100) return true; // temporarily !
ml_data, // double [][] ml_data, // data for ML - 10 layers - 4 center areas (3x3, 5x5,..) per camera-per direction, 1 - composite, and 1 with just 1 data (target disparity)
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
fatzero, // double fatzero,
false, // final boolean notch_mode, // use notch filter for inter-camera correlation to detect poles
threadsMax, // maximal number of threads to launch // final int threadsMax, // maximal number of threads to launch
updateStatus, // final boolean updateStatus,
debugLevel); // final int debugLevel)
......
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