Commit 5fc78264 authored by Andrey Filippov's avatar Andrey Filippov

improving initial plane detection

parent 88f25973
...@@ -534,6 +534,10 @@ public class CLTPass3d{ ...@@ -534,6 +534,10 @@ public class CLTPass3d{
double strength_floor, double strength_floor,
double strength_pow, double strength_pow,
double stBlurSigma, double stBlurSigma,
boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
int smplSide, // = 2; // Sample size (side of a square)
int smplNum, // = 3; // Number after removing worst
double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
int measSel) int measSel)
{ {
this.superTiles = new SuperTiles( this.superTiles = new SuperTiles(
...@@ -546,15 +550,29 @@ public class CLTPass3d{ ...@@ -546,15 +550,29 @@ public class CLTPass3d{
strength_floor, strength_floor,
strength_pow, strength_pow,
stBlurSigma, stBlurSigma,
smplMode, // = true; // Use sample mode (false - regular tile mode)
smplSide, // = 2; // Sample size (side of a square)
smplNum, // = 3; // Number after removing worst
smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
measSel); measSel);
return this.superTiles; return this.superTiles;
} }
public double [] showDisparityHistogram(int measSel) public double [] showDisparityHistogram(
boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
int smplSide, // = 2; // Sample size (side of a square)
int smplNum, // = 3; // Number after removing worst
double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
int measSel)
{ {
if (this.superTiles == null){ if (this.superTiles == null){
return null; return null;
} }
return this.superTiles.showDisparityHistogram(measSel); return this.superTiles.showDisparityHistogram(
smplMode, // = true; // Use sample mode (false - regular tile mode)
smplSide, // = 2; // Sample size (side of a square)
smplNum, // = 3; // Number after removing worst
smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
measSel);
} }
public double [] showDisparityHistogram() public double [] showDisparityHistogram()
......
...@@ -2123,8 +2123,16 @@ public class EyesisCorrectionParameters { ...@@ -2123,8 +2123,16 @@ public class EyesisCorrectionParameters {
public double stUseDisp = 0.15; // Use background disparity from supertiles if tile strength is less public double stUseDisp = 0.15; // Use background disparity from supertiles if tile strength is less
public double stStrengthScale = 50.0; // Multiply st strength if used instead of regular strength public double stStrengthScale = 50.0; // Multiply st strength if used instead of regular strength
public boolean stSmplMode = true; // Use sample mode (false - regular tile mode)
public int stSmplSide = 2; // Sample size (side of a square)
public int stSmplNum = 3; // Number after removing worst
public double stSmplRms = 0.1; // Maximal RMS of the remaining tiles in a sample
public int stMeasSel = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert public int stMeasSel = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
public double stSmallDiff = 0.4; // Consider merging initial planes if disparity difference below
public double stHighMix = 0.4; // Consider merging initial planes if jumps between ratio above
public double outlayerStrength = 0.3; // Outlayer tiles weaker than this may be replaced from neighbors public double outlayerStrength = 0.3; // Outlayer tiles weaker than this may be replaced from neighbors
public double outlayerDiff = 0.4; // Replace weak outlayer tiles that do not have neighbors within this disparity difference public double outlayerDiff = 0.4; // Replace weak outlayer tiles that do not have neighbors within this disparity difference
...@@ -2214,6 +2222,7 @@ public class EyesisCorrectionParameters { ...@@ -2214,6 +2222,7 @@ public class EyesisCorrectionParameters {
public boolean show_flaps_dirs = false; // show 'flaps-dirs' public boolean show_flaps_dirs = false; // show 'flaps-dirs'
public boolean show_first_clusters = false; // show 'first_N_clusters' public boolean show_first_clusters = false; // show 'first_N_clusters'
public boolean show_planes = false; // show planes public boolean show_planes = false; // show planes
public double [] vertical_xyz = {0.0,1.0,0.0}; // real world up unit vector in camera CS (x - right, y - up, z - to camera};
public CLTParameters(){} public CLTParameters(){}
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
...@@ -2414,7 +2423,16 @@ public class EyesisCorrectionParameters { ...@@ -2414,7 +2423,16 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"stMinBgFract", this.stMinBgFract +""); properties.setProperty(prefix+"stMinBgFract", this.stMinBgFract +"");
properties.setProperty(prefix+"stUseDisp", this.stUseDisp +""); properties.setProperty(prefix+"stUseDisp", this.stUseDisp +"");
properties.setProperty(prefix+"stStrengthScale", this.stStrengthScale +""); properties.setProperty(prefix+"stStrengthScale", this.stStrengthScale +"");
properties.setProperty(prefix+"stSmplMode", this.stSmplMode+"");
properties.setProperty(prefix+"stSmplSide", this.stSmplSide+"");
properties.setProperty(prefix+"stSmplNum", this.stSmplNum+"");
properties.setProperty(prefix+"stSmplRms", this.stSmplRms +"");
properties.setProperty(prefix+"stMeasSel", this.stMeasSel+""); properties.setProperty(prefix+"stMeasSel", this.stMeasSel+"");
properties.setProperty(prefix+"stSmallDiff", this.stSmallDiff +"");
properties.setProperty(prefix+"stHighMix", this.stHighMix +"");
properties.setProperty(prefix+"outlayerStrength", this.outlayerStrength +""); properties.setProperty(prefix+"outlayerStrength", this.outlayerStrength +"");
properties.setProperty(prefix+"outlayerDiff", this.outlayerDiff +""); properties.setProperty(prefix+"outlayerDiff", this.outlayerDiff +"");
...@@ -2494,7 +2512,11 @@ public class EyesisCorrectionParameters { ...@@ -2494,7 +2512,11 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"show_flaps_dirs", this.show_flaps_dirs+""); properties.setProperty(prefix+"show_flaps_dirs", this.show_flaps_dirs+"");
properties.setProperty(prefix+"show_first_clusters", this.show_first_clusters+""); properties.setProperty(prefix+"show_first_clusters", this.show_first_clusters+"");
properties.setProperty(prefix+"show_planes", this.show_planes+""); properties.setProperty(prefix+"show_planes", this.show_planes+"");
}
properties.setProperty(prefix+"vertical_xyz.x", this.vertical_xyz[0]+"");
properties.setProperty(prefix+"vertical_xyz.y", this.vertical_xyz[1]+"");
properties.setProperty(prefix+"vertical_xyz.z", this.vertical_xyz[2]+"");
}
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"transform_size")!=null) this.transform_size=Integer.parseInt(properties.getProperty(prefix+"transform_size")); if (properties.getProperty(prefix+"transform_size")!=null) this.transform_size=Integer.parseInt(properties.getProperty(prefix+"transform_size"));
if (properties.getProperty(prefix+"clt_window")!=null) this.clt_window=Integer.parseInt(properties.getProperty(prefix+"clt_window")); if (properties.getProperty(prefix+"clt_window")!=null) this.clt_window=Integer.parseInt(properties.getProperty(prefix+"clt_window"));
...@@ -2687,7 +2709,15 @@ public class EyesisCorrectionParameters { ...@@ -2687,7 +2709,15 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"stMinBgFract")!=null) this.stMinBgFract=Double.parseDouble(properties.getProperty(prefix+"stMinBgFract")); if (properties.getProperty(prefix+"stMinBgFract")!=null) this.stMinBgFract=Double.parseDouble(properties.getProperty(prefix+"stMinBgFract"));
if (properties.getProperty(prefix+"stUseDisp")!=null) this.stUseDisp=Double.parseDouble(properties.getProperty(prefix+"stUseDisp")); if (properties.getProperty(prefix+"stUseDisp")!=null) this.stUseDisp=Double.parseDouble(properties.getProperty(prefix+"stUseDisp"));
if (properties.getProperty(prefix+"stStrengthScale")!=null) this.stStrengthScale=Double.parseDouble(properties.getProperty(prefix+"stStrengthScale")); if (properties.getProperty(prefix+"stStrengthScale")!=null) this.stStrengthScale=Double.parseDouble(properties.getProperty(prefix+"stStrengthScale"));
if (properties.getProperty(prefix+"stSmplMode")!=null) this.stSmplMode=Boolean.parseBoolean(properties.getProperty(prefix+"stSmplMode"));
if (properties.getProperty(prefix+"stSmplSide")!=null) this.stSmplSide=Integer.parseInt(properties.getProperty(prefix+"stSmplSide"));
if (properties.getProperty(prefix+"stSmplNum")!=null) this.stSmplNum=Integer.parseInt(properties.getProperty(prefix+"stSmplNum"));
if (properties.getProperty(prefix+"stSmplRms")!=null) this.stSmplRms=Double.parseDouble(properties.getProperty(prefix+"stSmplRms"));
if (properties.getProperty(prefix+"stMeasSel")!=null) this.stMeasSel=Integer.parseInt(properties.getProperty(prefix+"stMeasSel")); if (properties.getProperty(prefix+"stMeasSel")!=null) this.stMeasSel=Integer.parseInt(properties.getProperty(prefix+"stMeasSel"));
if (properties.getProperty(prefix+"stSmallDiff")!=null) this.stSmallDiff=Double.parseDouble(properties.getProperty(prefix+"stSmallDiff"));
if (properties.getProperty(prefix+"stHighMix")!=null) this.stHighMix=Double.parseDouble(properties.getProperty(prefix+"stHighMix"));
if (properties.getProperty(prefix+"outlayerStrength")!=null) this.outlayerStrength=Double.parseDouble(properties.getProperty(prefix+"outlayerStrength")); if (properties.getProperty(prefix+"outlayerStrength")!=null) this.outlayerStrength=Double.parseDouble(properties.getProperty(prefix+"outlayerStrength"));
if (properties.getProperty(prefix+"outlayerDiff")!=null) this.outlayerDiff=Double.parseDouble(properties.getProperty(prefix+"outlayerDiff")); if (properties.getProperty(prefix+"outlayerDiff")!=null) this.outlayerDiff=Double.parseDouble(properties.getProperty(prefix+"outlayerDiff"));
...@@ -2767,6 +2797,12 @@ public class EyesisCorrectionParameters { ...@@ -2767,6 +2797,12 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"show_flaps_dirs")!=null) this.show_flaps_dirs=Boolean.parseBoolean(properties.getProperty(prefix+"show_flaps_dirs")); if (properties.getProperty(prefix+"show_flaps_dirs")!=null) this.show_flaps_dirs=Boolean.parseBoolean(properties.getProperty(prefix+"show_flaps_dirs"));
if (properties.getProperty(prefix+"show_first_clusters")!=null) this.show_first_clusters=Boolean.parseBoolean(properties.getProperty(prefix+"show_first_clusters")); if (properties.getProperty(prefix+"show_first_clusters")!=null) this.show_first_clusters=Boolean.parseBoolean(properties.getProperty(prefix+"show_first_clusters"));
if (properties.getProperty(prefix+"show_planes")!=null) this.show_planes=Boolean.parseBoolean(properties.getProperty(prefix+"show_planes")); if (properties.getProperty(prefix+"show_planes")!=null) this.show_planes=Boolean.parseBoolean(properties.getProperty(prefix+"show_planes"));
if (properties.getProperty(prefix+"vertical_xyz.x")!=null) this.vertical_xyz[0]=Double.parseDouble(properties.getProperty(prefix+"vertical_xyz.x"));
if (properties.getProperty(prefix+"vertical_xyz.y")!=null) this.vertical_xyz[1]=Double.parseDouble(properties.getProperty(prefix+"vertical_xyz.y"));
if (properties.getProperty(prefix+"vertical_xyz.z")!=null) this.vertical_xyz[2]=Double.parseDouble(properties.getProperty(prefix+"vertical_xyz.z"));
} }
public boolean showDialog() { public boolean showDialog() {
...@@ -2981,7 +3017,15 @@ public class EyesisCorrectionParameters { ...@@ -2981,7 +3017,15 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Minimal fraction of the disparity histogram to use as background", this.stMinBgFract, 6); gd.addNumericField("Minimal fraction of the disparity histogram to use as background", this.stMinBgFract, 6);
gd.addNumericField("Use background disparity from supertiles if tile strength is less", this.stUseDisp, 6); gd.addNumericField("Use background disparity from supertiles if tile strength is less", this.stUseDisp, 6);
gd.addNumericField("Multiply st strength if used instead of regular strength ", this.stStrengthScale, 6); gd.addNumericField("Multiply st strength if used instead of regular strength ", this.stStrengthScale, 6);
gd.addCheckbox ("Use sample mode (false - regular tile mode)", this.stSmplMode);
gd.addNumericField("Sample size (side of a square)", this.stSmplSide, 0);
gd.addNumericField("Number after removing worst", this.stSmplNum, 0);
gd.addNumericField("Maximal RMS of the remaining tiles in a sample", this.stSmplRms, 6);
gd.addNumericField("Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert",this.stMeasSel, 0); gd.addNumericField("Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert",this.stMeasSel, 0);
gd.addNumericField("Consider merging initial planes if disparity difference below", this.stSmallDiff, 6);
gd.addNumericField("Consider merging initial planes if jumps between ratio above", this.stHighMix, 6);
gd.addNumericField("Outlayer tiles weaker than this may be replaced from neighbors", this.outlayerStrength, 6); gd.addNumericField("Outlayer tiles weaker than this may be replaced from neighbors", this.outlayerStrength, 6);
gd.addNumericField("Replace weak outlayer tiles that do not have neighbors within this disparity difference", this.outlayerDiff, 6); gd.addNumericField("Replace weak outlayer tiles that do not have neighbors within this disparity difference", this.outlayerDiff, 6);
...@@ -3064,6 +3108,8 @@ public class EyesisCorrectionParameters { ...@@ -3064,6 +3108,8 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Show 'flaps-dirs'", this.show_flaps_dirs); gd.addCheckbox ("Show 'flaps-dirs'", this.show_flaps_dirs);
gd.addCheckbox ("Show 'first_N_clusters'", this.show_first_clusters); gd.addCheckbox ("Show 'first_N_clusters'", this.show_first_clusters);
gd.addCheckbox ("Show planes", this.show_planes); gd.addCheckbox ("Show planes", this.show_planes);
gd.addMessage ("Unity up vector in camera coordinate system (x - right, y - up, z - to camera): {"+
this.vertical_xyz[0]+","+this.vertical_xyz[1]+","+this.vertical_xyz[2]+"}");
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
...@@ -3264,7 +3310,16 @@ public class EyesisCorrectionParameters { ...@@ -3264,7 +3310,16 @@ public class EyesisCorrectionParameters {
this.stMinBgFract= gd.getNextNumber(); this.stMinBgFract= gd.getNextNumber();
this.stUseDisp= gd.getNextNumber(); this.stUseDisp= gd.getNextNumber();
this.stStrengthScale= gd.getNextNumber(); this.stStrengthScale= gd.getNextNumber();
this.stSmplMode= gd.getNextBoolean();
this.stSmplSide= (int) gd.getNextNumber();
this.stSmplNum= (int) gd.getNextNumber();
this.stSmplRms= gd.getNextNumber();
this.stMeasSel= (int) gd.getNextNumber(); this.stMeasSel= (int) gd.getNextNumber();
this.stSmallDiff= gd.getNextNumber();
this.stHighMix= gd.getNextNumber();
this.outlayerStrength= gd.getNextNumber(); this.outlayerStrength= gd.getNextNumber();
this.outlayerDiff= gd.getNextNumber(); this.outlayerDiff= gd.getNextNumber();
this.outlayerDiffPos= gd.getNextNumber(); this.outlayerDiffPos= gd.getNextNumber();
......
...@@ -312,6 +312,11 @@ public class GeometryCorrection { ...@@ -312,6 +312,11 @@ public class GeometryCorrection {
return SCENE_UNITS_SCALE * this.focalLength * this.disparityRadius / (disparity * 0.001*this.pixelSize); return SCENE_UNITS_SCALE * this.focalLength * this.disparityRadius / (disparity * 0.001*this.pixelSize);
} }
public double getDisparityFromZ(double z){
return (1000.0 * SCENE_UNITS_SCALE * this.focalLength * this.disparityRadius / this.pixelSize) / z;
}
public double getFOVPix(){ // get ratio of 1 pixel X/Y to Z (distance to object) public double getFOVPix(){ // get ratio of 1 pixel X/Y to Z (distance to object)
return 0.001 * this.pixelSize / this.focalLength; return 0.001 * this.pixelSize / this.focalLength;
} }
......
...@@ -369,6 +369,7 @@ public class MeasuredLayers { ...@@ -369,6 +369,7 @@ public class MeasuredLayers {
return selection; return selection;
} }
/** /**
* Get selection for the specific measurement layer and supertile X,Y coordinates * Get selection for the specific measurement layer and supertile X,Y coordinates
* in the image and combine with disparity far/near limits. Alse combined with * in the image and combine with disparity far/near limits. Alse combined with
...@@ -426,6 +427,79 @@ public class MeasuredLayers { ...@@ -426,6 +427,79 @@ public class MeasuredLayers {
return selection; return selection;
} }
/**
* Get selection when disparity/strength is already calculated. Useful when
* disparity/strength are not just measured values, by sampled over an area
* @param disparityStrength array of {disparity, strength} where each is
* a linescan data of the (2 * superTileSize) * (2 * superTileSize)
* @param sel_in optional input selection array or null - use all
* @param null_if_none return null if selection has no tiles enabled
* @return boolean array of per-tile enabled/disabled values in linescan
* order, (2 * superTileSize) * (2 * superTileSize)
*/
public boolean [] getSupertileSelection(
double [][] disparityStrength,
boolean [] sel_in,
boolean null_if_none)
{
int st2 = 2 * superTileSize;
boolean [] selection = new boolean [st2 * st2];
int num_selected = 0;
for (int i = 0; i < disparityStrength[1].length; i++){
if ( (disparityStrength[1][i] > 0.0) &&
((sel_in == null) || (sel_in[i]))){
selection[i] = true;
num_selected ++;
}
}
if (null_if_none && (num_selected == 0)) return null;
return selection;
}
/**
* Get selection when disparity/strength is already calculated. Useful when
* disparity/strength are not just measured values, by sampled over an area
* Includes low/high limits for disparity values
* @param disparityStrength array of {disparity, strength} where each is
* a linescan data of the (2 * superTileSize) * (2 * superTileSize)
* @param sel_in optional input selection array or null - use all
* @param disp_far low limit for disparity, Double.NaN - do not check
* @param disp_near high limit for disparity, Double.NaN - do not check
* @param null_if_none return null if selection has no tiles enabled
* @return boolean array of per-tile enabled/disabled values in linescan
* order, (2 * superTileSize) * (2 * superTileSize)
* @return
*/
public boolean [] getSupertileSelection(
double [][] disparityStrength,
boolean [] sel_in,
double disp_far,
double disp_near,
boolean null_if_none)
{
int st2 = 2 * superTileSize;
boolean [] selection = new boolean [st2 * st2];
int num_selected = 0;
for (int i = 0; i < disparityStrength[1].length; i++){
if ( (disparityStrength[1][i] > 0.0) &&
((sel_in == null) || (sel_in[i]))){
if ( (Double.isNaN(disp_far) || (disparityStrength[0][i] >= disp_far)) &&
(Double.isNaN(disp_near) || (disparityStrength[0][i] <= disp_near))) {
}
selection[i] = true;
num_selected ++;
}
}
if (null_if_none && (num_selected == 0)) return null;
return selection;
}
/** /**
* Get number of "true" elements in a boolean array. Null is OK, it results in 0 * Get number of "true" elements in a boolean array. Null is OK, it results in 0
...@@ -453,6 +527,19 @@ public class MeasuredLayers { ...@@ -453,6 +527,19 @@ public class MeasuredLayers {
} }
return sw; return sw;
} }
public static double getSumStrength(
double [][] disp_strength,
boolean [] selected)
{
if (disp_strength == null) return 0.0;
double sw = 0.0;
for (int i = 0; i < disp_strength[1].length; i++){
if ((selected == null) || selected[i]) {
sw += disp_strength[1][i];
}
}
return sw;
}
/** /**
* Get disparity and correlation strength for the specific measurement layer and * Get disparity and correlation strength for the specific measurement layer and
...@@ -510,4 +597,153 @@ public class MeasuredLayers { ...@@ -510,4 +597,153 @@ public class MeasuredLayers {
if (null_if_none && (num_selected == 0)) return null; if (null_if_none && (num_selected == 0)) return null;
return ds; return ds;
} }
/**
* Get double-size (for overlapping) array of disparities and strengths for the supertile
* Using best (producing lowest disparity variance) subset of neighbor tiles
* @param num_layer number of measurement layer (currently 0 - composite, 1 - quad, 2 - horizontal
* and 3 - vertical piars correlation
* @param stX supertile horizontal index
* @param stY supertile vertical index
* @param sel_in input selection of the output data samples (or null)
* @param strength_floor subtract from the correlation strength (limit by 0) before using as a
* sample weight
* @param strength_pow raise correlation strength (after subtracting strength_floor) to this power
* to use as a sample weight
* @param smplSide size of the square sample side
* @param smplNum number of averaged samples (should be <= smplSide * smplSide and > 1)
* @param smplRms maximal square root of variance (in disparity pixels) to accept the result
* @param null_if_none return null if there are no usable tiles in the result
* @return a pair of arrays (disparity and strengths) in line-scan order each
*/
public double[][] getDisparityStrength (
int num_layer,
int stX,
int stY,
boolean [] sel_in,
double strength_floor,
double strength_pow,
int smplSide, // = 2; // Sample size (side of a square)
int smplNum, // = 3; // Number after removing worst (should be >1)
double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
boolean null_if_none)
{
if ((layers[num_layer] == null) && null_if_none){
return null;
}
int st2 = 2 * superTileSize;
int st_half = superTileSize/2;
double [][] ds = new double [2][st2*st2];
int num_selected = 0;
int smpl_center = smplSide /2;
int st2e = st2 + smplSide;
int smplLen = smplSide*smplSide;
double [] disp = new double [st2e * st2e];
double [] weight = new double [st2e * st2e];
int st_halfe = st_half + smpl_center;
double smlVar = smplRms * smplRms; // maximal variance (weighted average of the squared difference from the mean)
if (layers[num_layer] != null) {
for (int dy = 0; dy < st2e; dy ++){
int y = superTileSize * stY -st_halfe + dy;
if ((y >= 0) && (y < tilesY)) {
for (int dx = 0; dx < st2e; dx ++){
int x = superTileSize * stX -st_halfe + dx;
if ((x >= 0) && (x < tilesX)) {
int indx = y * tilesX + x;
int indx_ste = dy * st2e + dx;
if (layers[num_layer][indx] != null){ // apply sel_in later
disp[indx_ste] = layers[num_layer][indx].getDisparity();
double w = layers[num_layer][indx].getStrength() - strength_floor;
if (w > 0) {
if (strength_pow != 1.0) w = Math.pow(w, strength_pow);
// w *= lapWeight[dy][dx];
disp[indx_ste] = layers[num_layer][indx].getDisparity();
weight[indx_ste] = w;
num_selected ++;
}
}
}
}
}
}
}
if (null_if_none && (num_selected == 0)) return null;
// now work with disp, strength [st2e*st2de] and filter results to ds[2][st2*st2], applying sel_in
num_selected = 0;
for (int dy = 0; dy < st2; dy ++){
for (int dx = 0; dx < st2; dx ++){
int indx = dy * st2 + dx;
if (((sel_in == null) || sel_in[indx])){
int num_in_sample = 0;
boolean [] smpl_sel = new boolean [smplLen];
double [] smpl_d = new double [smplLen];
double [] smpl_w = new double [smplLen];
for (int sy = 0; sy < smplSide; sy++){
int y = dy + sy; // - smpl_center;
for (int sx = 0; sx < smplSide; sx++){
int x = dx + sx; // - smpl_center;
int indxe = y * st2e + x;
if (weight[indxe] > 0.0){
int indxs = sy * smplSide + sx;
smpl_sel[indxs] = true;
smpl_d[indxs] = disp[indxe];
smpl_w[indxs] = weight[indxe];
num_in_sample ++;
}
}
}
if (num_in_sample >= smplNum){ // try, remove worst
// calculate
double sd=0.0, sd2 = 0.0, sw = 0.0;
for (int i = 0; i < smplLen; i++) if (smpl_sel[i]) {
double dw = smpl_d[i] * smpl_w[i];
sd += dw;
sd2 += dw * smpl_d[i];
sw += smpl_w[i];
}
// remove worst, update sd2, sd and sw
while ((num_in_sample > smplNum) && (sw > 0)){ // try, remove worst
double d_mean = sd/sw;
int iworst = -1;
double dworst2 = 0.0;
for (int i = 0; i < smplLen; i++) if (smpl_sel[i]) {
double d2 = (smpl_d[i] - d_mean);
d2 *=d2;
if (d2 > dworst2) {
iworst = i;
dworst2 = d2;
}
}
if (iworst < 0){
System.out.println("**** this is a BUG in getDisparityStrength() ****");
break;
}
// remove worst sample
smpl_sel[iworst] = false;
double dw = smpl_d[iworst] * smpl_w[iworst];
sd -= dw;
sd2 -= dw * smpl_d[iworst];
sw -= smpl_w[iworst];
num_in_sample --;
}
// calculate variance of the remaining set
if (sw > 0.0) {
sd /= sw;
sd2 /= sw;
double var = sd2 - sd * sd;
if (var < smlVar) { // good, save in the result array
ds[0][indx] = sd;
ds[1][indx] = sw * lapWeight[dy][dx] /num_in_sample; // average weights, multiply by window
}
} else {
num_in_sample = 0;
System.out.println("**** this is a BUG in getDisparityStrength(), shoud not happen ? ****");
}
}
}
}
}
return ds;
}
} }
...@@ -54,6 +54,14 @@ public class SuperTiles{ ...@@ -54,6 +54,14 @@ public class SuperTiles{
double [] bgDisparity = null; double [] bgDisparity = null;
double [] bgStrength = null; double [] bgStrength = null;
int measSel = 1; // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert int measSel = 1; // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
boolean smplMode = true; // Use sample mode (false - regular tile mode)
int smplSide = 2; // Sample size (side of a square)
int smplNum = 3; // Number after removing worst
double smplRms = 0.1; // Maximal RMS of the remaining tiles in a sample
MeasuredLayers measuredLayers = null; MeasuredLayers measuredLayers = null;
CLTPass3d cltPass3d; CLTPass3d cltPass3d;
...@@ -84,6 +92,10 @@ public class SuperTiles{ ...@@ -84,6 +92,10 @@ public class SuperTiles{
double strength_floor, double strength_floor,
double strength_pow, double strength_pow,
double stBlurSigma, double stBlurSigma,
boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
int smplSide, // = 2; // Sample size (side of a square)
int smplNum, // = 3; // Number after removing worst
double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
int measSel) int measSel)
{ {
this.cltPass3d = cltPass3d; this.cltPass3d = cltPass3d;
...@@ -96,8 +108,11 @@ public class SuperTiles{ ...@@ -96,8 +108,11 @@ public class SuperTiles{
this.strength_floor = strength_floor; this.strength_floor = strength_floor;
this.strength_pow = strength_pow; this.strength_pow = strength_pow;
this.stBlurSigma = stBlurSigma; this.stBlurSigma = stBlurSigma;
this.smplMode = smplMode; // Use sample mode (false - regular tile mode)
this.smplSide = smplSide; // Sample size (side of a square)
this.smplNum = smplNum; // Number after removing worst
this.smplRms = smplRms; // Maximal RMS of the remaining tiles in a sample
this.measSel = measSel; this.measSel = measSel;
// this.step_threshold_near = this.step_threshold_far * this.step_far / step_near;
this.step_threshold_near = this.step_threshold_far * step_near / this.step_far ; this.step_threshold_near = this.step_threshold_far * step_near / this.step_far ;
this.bin_far = this.step_threshold_far / this.step_far; this.bin_far = this.step_threshold_far / this.step_far;
this.bin_near = this.step_threshold_far / this.step_far * (Math.log(this.step_near/this.step_far) + 1); this.bin_near = this.step_threshold_far / this.step_far * (Math.log(this.step_near/this.step_far) + 1);
...@@ -138,8 +153,13 @@ public class SuperTiles{ ...@@ -138,8 +153,13 @@ public class SuperTiles{
cltPass3d.getVertStrength(), // double [] strength, cltPass3d.getVertStrength(), // double [] strength,
cltPass3d.getSelected()); // boolean [] selection) // may be null cltPass3d.getSelected()); // boolean [] selection) // may be null
getDisparityHistograms(measSel); // calculate and blur supertiles (for all, not just selected?) getDisparityHistograms(
if (tileProcessor.globalDebugLevel > -1){ smplMode, // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
smplSide, // final int smplSide, // = 2; // Sample size (side of a square)
smplNum, // final int smplNum, // = 3; // Number after removing worst
smplRms, // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
measSel); // calculate and blur supertiles (for all, not just selected?)
if (tileProcessor.globalDebugLevel > 0){
System.out.println("SuperTiles(): min_disparity = "+min_disparity+", max_disparity="+max_disparity); System.out.println("SuperTiles(): min_disparity = "+min_disparity+", max_disparity="+max_disparity);
System.out.println("SuperTiles(): step_far = "+step_far+", step_near="+step_near); System.out.println("SuperTiles(): step_far = "+step_far+", step_near="+step_near);
System.out.println("SuperTiles(): numBins = "+numBins+", bin_far="+bin_far+", bin_near = "+bin_near); System.out.println("SuperTiles(): numBins = "+numBins+", bin_far="+bin_far+", bin_near = "+bin_near);
...@@ -149,7 +169,7 @@ public class SuperTiles{ ...@@ -149,7 +169,7 @@ public class SuperTiles{
} }
// //
} }
if (tileProcessor.globalDebugLevel > 0){
String [] titles = {"d0","s0","d1","s1","d2","s2","d3","s3"}; String [] titles = {"d0","s0","d1","s1","d2","s2","d3","s3"};
double [][] dbg_img = new double [titles.length][]; double [][] dbg_img = new double [titles.length][];
for (int i = 0; i < measuredLayers.getNumLayers(); i++){ for (int i = 0; i < measuredLayers.getNumLayers(); i++){
...@@ -158,8 +178,7 @@ public class SuperTiles{ ...@@ -158,8 +178,7 @@ public class SuperTiles{
} }
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(dbg_img, tileProcessor.getTilesX(), tileProcessor.getTilesY(), true, "measuredLayers",titles); sdfa_instance.showArrays(dbg_img, tileProcessor.getTilesX(), tileProcessor.getTilesY(), true, "measuredLayers",titles);
}
} }
public void initFuseCoeff( public void initFuseCoeff(
...@@ -326,29 +345,15 @@ public class SuperTiles{ ...@@ -326,29 +345,15 @@ public class SuperTiles{
System.out.println("getLapWeights: sum = "+s); System.out.println("getLapWeights: sum = "+s);
return lapWeight; return lapWeight;
} }
// updates disparityHistograms
/* /*
public double [][] getDisparityHistograms() public double [][] getDisparityHistograms(
{ final int measSel) // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
return getDisparityHistograms(cltPass3d.selected, tileProcessor.globalDebugLevel);
}
// updates disparityHistograms
public double [][] getDisparityHistograms(final boolean [] selected) // null)
{
return getDisparityHistograms(selected, tileProcessor.globalDebugLevel);
}
*/
public double [][] getDisparityHistogramsOld( // OLD!
final boolean [] selected, // or null
final int debugLevel)
{ {
if (this.disparityHistograms != null) return this.disparityHistograms; if (this.disparityHistograms != null) return this.disparityHistograms;
/// final double step_disparity = step_near; // TODO: implement // final double step_disparity = step_near; // TODO: implement
final int tilesX = tileProcessor.getTilesX(); final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY(); final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.superTileSize; final int superTileSize = tileProcessor.superTileSize;
final double [] disparity = cltPass3d.getDisparity();
final double [] strength = cltPass3d.getStrength();
final int stilesX = (tilesX + superTileSize -1)/superTileSize; final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize; final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY; final int nStiles = stilesX * stilesY;
...@@ -356,9 +361,6 @@ public class SuperTiles{ ...@@ -356,9 +361,6 @@ public class SuperTiles{
final double [] strengthHist = new double [nStiles]; final double [] strengthHist = new double [nStiles];
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax); final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
final int st_start = - superTileSize/2;
final int superTileSize2 = 2 * superTileSize;
final double [][] lapWeight = getLapWeights();
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
public void run() { public void run() {
...@@ -367,22 +369,21 @@ public class SuperTiles{ ...@@ -367,22 +369,21 @@ public class SuperTiles{
int stileX = nsTile % stilesX; int stileX = nsTile % stilesX;
double sw = 0.0; // sum weights double sw = 0.0; // sum weights
double [] hist = new double [numBins]; double [] hist = new double [numBins];
int tY0 = stileY * superTileSize + st_start; for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++) {
int tX0 = stileX * superTileSize + st_start; if ((measSel & (1 << nl)) != 0) {
for (int tY = 0; tY < superTileSize2; tY++){ double [][] disp_strength = measuredLayers.getDisparityStrength(
int tileY = tY0 +tY; nl, // int num_layer,
if ((tileY >= 0) && (tileY < tilesY)) { stileX, // int stX,
for (int tX = 0; tX < superTileSize2; tX++){ stileY, // int stY,
int tileX = tX0 +tX; null, // boolean [] sel_in,
if ((tileX >= 0) && (tileX < tilesX)) { strength_floor, // double strength_floor,
int indx = tileY*tilesX + tileX; strength_pow, // double strength_pow,
double d = disparity[indx]; true); // boolean null_if_none);
if (!Double.isNaN(d) && ((selected == null) || selected[indx])){ if (disp_strength != null) {
double w = strength[indx] - strength_floor; for (int indx = 0; indx < disp_strength[1].length; indx++) {
if (w > 0.0){ double w = disp_strength[1][indx];
if (strength_pow != 1.0) w = Math.pow(w, strength_pow); if ( w > 0.0){
w *= lapWeight[tY][tX]; double d = disp_strength[0][indx];
// ignore too near/ too far
int bin = disparityToBin(d); int bin = disparityToBin(d);
if ((bin >= 0) && (bin < numBins)){ // maybe collect below min and above max somewhere? if ((bin >= 0) && (bin < numBins)){ // maybe collect below min and above max somewhere?
hist[bin] += w; // +1] hist[bin] += w; // +1]
...@@ -393,7 +394,6 @@ public class SuperTiles{ ...@@ -393,7 +394,6 @@ public class SuperTiles{
} }
} }
} }
}
strengthHist[nsTile] = sw / superTileSize / superTileSize; // average strength per tile in the super-tile strengthHist[nsTile] = sw / superTileSize / superTileSize; // average strength per tile in the super-tile
if (sw > 0){ if (sw > 0){
for (int i = 0; i<numBins; i++){ for (int i = 0; i<numBins; i++){
...@@ -411,17 +411,32 @@ public class SuperTiles{ ...@@ -411,17 +411,32 @@ public class SuperTiles{
this.disparityHistograms = dispHist; this.disparityHistograms = dispHist;
this.stStrength = strengthHist; this.stStrength = strengthHist;
if (this.stBlurSigma > 0.0) { if (this.stBlurSigma > 0.0) {
blurDisparityHistogram(debugLevel); blurDisparityHistogram(0); // debugLevel);
} }
return this.disparityHistograms; // dispHist; return this.disparityHistograms; // dispHist;
} }
*/
public double [][] getDisparityHistograms( public double [][] getDisparityHistograms(
final int measSel) // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
// final int debugLevel) final int smplSide, // = 2; // Sample size (side of a square)
final int smplNum, // = 3; // Number after removing worst
final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
final int measSel) //
{ {
if (this.disparityHistograms != null) return this.disparityHistograms; if ((this.disparityHistograms != null) &&
// final double step_disparity = step_near; // TODO: implement (smplMode == this.smplMode) &&
(smplSide == this.smplSide) &&
(smplNum == this.smplNum) &&
(smplRms == this.smplRms) &&
(measSel == this.measSel)){
return this.disparityHistograms;
}
this.smplMode = smplMode; // Use sample mode (false - regular tile mode)
this.smplSide = smplSide; // Sample size (side of a square)
this.smplNum = smplNum; // Number after removing worst
this.smplRms = smplRms; // Maximal RMS of the remaining tiles in a sample
this.measSel = measSel;
final int tilesX = tileProcessor.getTilesX(); final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY(); final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.superTileSize; final int superTileSize = tileProcessor.superTileSize;
...@@ -442,14 +457,29 @@ public class SuperTiles{ ...@@ -442,14 +457,29 @@ public class SuperTiles{
double [] hist = new double [numBins]; double [] hist = new double [numBins];
for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++) { for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++) {
if ((measSel & (1 << nl)) != 0) { if ((measSel & (1 << nl)) != 0) {
double [][] disp_strength = measuredLayers.getDisparityStrength( double [][] disp_strength;
if (smplMode) {
disp_strength = measuredLayers.getDisparityStrength(
nl, // int num_layer, nl, // int num_layer,
stileX, // int stX, stileX, // int stX,
stileY, // int stY, stileY, // int stY,
null, // boolean [] sel_in, null, // boolean [] sel_in,
strength_floor, // double strength_floor, strength_floor, // double strength_floor,
strength_pow, // double strength_pow, strength_pow, // double strength_pow,
smplSide, // int smplSide, // = 2; // Sample size (side of a square)
smplNum, //int smplNum, // = 3; // Number after removing worst (should be >1)
smplRms, //double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
true); // boolean null_if_none); true); // boolean null_if_none);
} else {
disp_strength = measuredLayers.getDisparityStrength(
nl, // int num_layer,
stileX, // int stX,
stileY, // int stY,
null, // boolean [] sel_in,
strength_floor, // double strength_floor,
strength_pow, // double strength_pow,
true); // boolean null_if_none);
}
if (disp_strength != null) { if (disp_strength != null) {
for (int indx = 0; indx < disp_strength[1].length; indx++) { for (int indx = 0; indx < disp_strength[1].length; indx++) {
double w = disp_strength[1][indx]; double w = disp_strength[1][indx];
...@@ -491,7 +521,6 @@ public class SuperTiles{ ...@@ -491,7 +521,6 @@ public class SuperTiles{
public void blurDisparityHistogram( // in-place public void blurDisparityHistogram( // in-place
final int debugLevel) final int debugLevel)
{ {
...@@ -520,7 +549,12 @@ public class SuperTiles{ ...@@ -520,7 +549,12 @@ public class SuperTiles{
public double [][][] getMaxMinMax(){ public double [][][] getMaxMinMax(){
// first find all integer maximums, and if the top is flat - use the middle. If not flat - use 2-nd degree polynomial // first find all integer maximums, and if the top is flat - use the middle. If not flat - use 2-nd degree polynomial
if (disparityHistograms == null) getDisparityHistograms(this.measSel); if (disparityHistograms == null) getDisparityHistograms(
this.smplMode, // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
this.smplSide, // final int smplSide, // = 2; // Sample size (side of a square)
this.smplNum, // final int smplNum, // = 3; // Number after removing worst
this.smplRms, // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
this.measSel);
final int globalDebugLevel = tileProcessor.globalDebugLevel; final int globalDebugLevel = tileProcessor.globalDebugLevel;
maxMinMax = new double [disparityHistograms.length][][]; maxMinMax = new double [disparityHistograms.length][][];
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax); final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
...@@ -649,15 +683,31 @@ public class SuperTiles{ ...@@ -649,15 +683,31 @@ public class SuperTiles{
} }
public double [] showDisparityHistogram() public double [] showDisparityHistogram()
{ {
return showDisparityHistogram(this.measSel); if (disparityHistograms == null){
getDisparityHistograms(
this.smplMode, // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
this.smplSide, // final int smplSide, // = 2; // Sample size (side of a square)
this.smplNum, // final int smplNum, // = 3; // Number after removing worst
this.smplRms, // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
this.measSel); // calculate and blur with the current settings, specified at instantiation
}
return showDisparityHistogram(disparityHistograms);
} }
public double [] showDisparityHistogram( public double [] showDisparityHistogram(
final int measSel) // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
int smplSide, // = 2; // Sample size (side of a square)
int smplNum, // = 3; // Number after removing worst
double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
int measSel) // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
{ {
if (disparityHistograms == null){ getDisparityHistograms( // will recalculate if does not exist or some parameters changed
getDisparityHistograms(measSel); // calculate and blur with the current settings, specified at instantiation smplMode, // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
} smplSide, // final int smplSide, // = 2; // Sample size (side of a square)
smplNum, // final int smplNum, // = 3; // Number after removing worst
smplRms, // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
measSel); // calculate and blur with the current settings, specified at instantiation
return showDisparityHistogram(disparityHistograms); return showDisparityHistogram(disparityHistograms);
} }
...@@ -1444,7 +1494,7 @@ public class SuperTiles{ ...@@ -1444,7 +1494,7 @@ public class SuperTiles{
for (int i = 0; i < dbg_img[2].length; i++){ for (int i = 0; i < dbg_img[2].length; i++){
dbg_img[2][i] = sel_all[i]?1.0:0.0; dbg_img[2][i] = sel_all[i]?1.0:0.0;
} }
sdfa_instance.showArrays(dbg_img, superTileSize2, superTileSize2, true, "disp_str_sel"); sdfa_instance.showArrays(dbg_img, superTileSize2, superTileSize2, true, "p2_disp_str_sel");
} }
} }
...@@ -1630,6 +1680,11 @@ public class SuperTiles{ ...@@ -1630,6 +1680,11 @@ public class SuperTiles{
final boolean plPreferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue) final boolean plPreferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
final GeometryCorrection geometryCorrection, final GeometryCorrection geometryCorrection,
final boolean correct_distortions, final boolean correct_distortions,
final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
final int smplSide, // = 2; // Sample size (side of a square)
final int smplNum, // = 3; // Number after removing worst
final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
final int debugLevel, final int debugLevel,
final int dbg_X, final int dbg_X,
final int dbg_Y) final int dbg_Y)
...@@ -1680,6 +1735,8 @@ public class SuperTiles{ ...@@ -1680,6 +1735,8 @@ public class SuperTiles{
dbg_img[9] = cltPass3d.getStrength(); dbg_img[9] = cltPass3d.getStrength();
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(dbg_img, tileProcessor.getTilesX(), tileProcessor.getTilesY(), true, "measuredLayers",titles); sdfa_instance.showArrays(dbg_img, tileProcessor.getTilesX(), tileProcessor.getTilesY(), true, "measuredLayers",titles);
} }
// if (maxMinMax == null) // if (maxMinMax == null)
getMaxMinMax(); getMaxMinMax();
...@@ -1706,11 +1763,12 @@ public class SuperTiles{ ...@@ -1706,11 +1763,12 @@ public class SuperTiles{
for (int i = 0; i < dflt_select.length; i++){ for (int i = 0; i < dflt_select.length; i++){
if (dflt_select[i] != null) tile_sel[i] = dflt_select[i].clone(); if (dflt_select[i] != null) tile_sel[i] = dflt_select[i].clone();
} }
int dl1 = (nsTile == debug_stile) ? 3 : 0; // int dl1 = (nsTile == debug_stile) ? 3 : 0;
int dl = (nsTile == debug_stile) ? 3 : 0; int dl = (nsTile == debug_stile) ? 4 : 0;
boolean OK = pd0.getPlaneFromMeas( double [][][] disp_strength = pd0.getPlaneFromMeas(
tile_sel, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified) tile_sel, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified)
null,
min_disp, // double disp_far, // minimal disparity to select (or NaN) min_disp, // double disp_far, // minimal disparity to select (or NaN)
Double.NaN, // double disp_near, // maximal disparity to select (or NaN) Double.NaN, // double disp_near, // maximal disparity to select (or NaN)
0.0, // plDispNorm, // double dispNorm, // Normalize disparities to the average if above 0.0, // plDispNorm, // double dispNorm, // Normalize disparities to the average if above
...@@ -1718,10 +1776,15 @@ public class SuperTiles{ ...@@ -1718,10 +1776,15 @@ public class SuperTiles{
plMinPoints, // int min_tiles, plMinPoints, // int min_tiles,
strength_floor, // strength_floor, //
strength_pow, // double strength_pow, strength_pow, // double strength_pow,
smplMode,
smplSide,
smplNum,
smplRms,
dl); // int debugLevel) dl); // int debugLevel)
if (OK){ // there are some non-zero tiles, process them (all points, not clustered by disparity value) if (disp_strength != null){ // there are some non-zero tiles, process them (all points, not clustered by disparity value)
boolean OK;
TilePlanes.PlaneData pd0_full = pd0.clone(); // TilePlanes.PlaneData pd0_full = pd0.clone(); //
ArrayList<TilePlanes.PlaneData> st_planes = new ArrayList<TilePlanes.PlaneData>(); ArrayList<TilePlanes.PlaneData> st_planes = new ArrayList<TilePlanes.PlaneData>();
// now try to remove outliers // now try to remove outliers
...@@ -1733,6 +1796,7 @@ public class SuperTiles{ ...@@ -1733,6 +1796,7 @@ public class SuperTiles{
pd0); pd0);
if (pd0.getValue() > targetV) { if (pd0.getValue() > targetV) {
OK = pd0.removeOutliers( // getPlaneFromMeas should already have run OK = pd0.removeOutliers( // getPlaneFromMeas should already have run
disp_strength,
targetV, // double targetEigen, // target eigenvalue for primary axis (is disparity-dependent, so is non-constant) targetV, // double targetEigen, // target eigenvalue for primary axis (is disparity-dependent, so is non-constant)
max_outliers, // int maxRemoved, // maximal number of tiles to remove (not a constant) max_outliers, // int maxRemoved, // maximal number of tiles to remove (not a constant)
dl); // int debugLevel) dl); // int debugLevel)
...@@ -1769,8 +1833,8 @@ public class SuperTiles{ ...@@ -1769,8 +1833,8 @@ public class SuperTiles{
double [][] mm = maxMinMax[nsTile]; double [][] mm = maxMinMax[nsTile];
if (mm == null){ if (mm == null){
double [][][] dbg_min_max = maxMinMax; // double [][][] dbg_min_max = maxMinMax;
System.out.println("maxMinMax["+nsTile+"] == null"); // System.out.println("maxMinMax["+nsTile+"] == null");
} }
if ((mm!= null) && (mm.length > 1)) { // multiple maximums - separate into multiple selections // null pointer if ((mm!= null) && (mm.length > 1)) { // multiple maximums - separate into multiple selections // null pointer
...@@ -1789,8 +1853,9 @@ public class SuperTiles{ ...@@ -1789,8 +1853,9 @@ public class SuperTiles{
TilePlanes.PlaneData pd = pd0_full.clone(); TilePlanes.PlaneData pd = pd0_full.clone();
OK = pd.getPlaneFromMeas( OK = (pd.getPlaneFromMeas(
null, // tile_sel, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified) null, // tile_sel, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified)
disp_strength,
far_near[0], // double disp_far, // minimal disparity to select (or NaN) far_near[0], // double disp_far, // minimal disparity to select (or NaN)
far_near[1], // double disp_near, // maximal disparity to select (or NaN) far_near[1], // double disp_near, // maximal disparity to select (or NaN)
0.0, // plDispNorm, // double dispNorm, // Normalize disparities to the average if above 0.0, // plDispNorm, // double dispNorm, // Normalize disparities to the average if above
...@@ -1798,7 +1863,11 @@ public class SuperTiles{ ...@@ -1798,7 +1863,11 @@ public class SuperTiles{
plMinPoints, // int min_tiles, plMinPoints, // int min_tiles,
strength_floor, // strength_floor, //
strength_pow, // double strength_pow, strength_pow, // double strength_pow,
dl); // int debugLevel) smplMode,
smplSide,
smplNum,
smplRms,
dl) != null); // int debugLevel)
if (OK) { if (OK) {
if (dl > 0) { if (dl > 0) {
if (swc_common > 1.0) { if (swc_common > 1.0) {
...@@ -1824,6 +1893,7 @@ public class SuperTiles{ ...@@ -1824,6 +1893,7 @@ public class SuperTiles{
} }
if (pd.getValues()[0] > targetV) { if (pd.getValues()[0] > targetV) {
OK = pd.removeOutliers( // getPlaneFromMeas should already have run OK = pd.removeOutliers( // getPlaneFromMeas should already have run
disp_strength,
targetV, // double targetEigen, // target eigenvalue for primary axis (is disparity-dependent, so is non-constant) targetV, // double targetEigen, // target eigenvalue for primary axis (is disparity-dependent, so is non-constant)
max_outliers, // int maxRemoved, // maximal number of tiles to remove (not a constant) max_outliers, // int maxRemoved, // maximal number of tiles to remove (not a constant)
dl); // int debugLevel) dl); // int debugLevel)
...@@ -1869,6 +1939,532 @@ public class SuperTiles{ ...@@ -1869,6 +1939,532 @@ public class SuperTiles{
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
} }
public int [][] getTransMatrix(
boolean [][][] selections ) // for each plane should have the same non-null ml
{
int num_ml = measuredLayers.getNumLayers();
int num_p = selections.length;
int superTileSize = tileProcessor.getSuperTileSize();
int st2 = 2 * superTileSize;
int [][] trans_mat = new int [num_p][num_p];
for (int ml = 0; ml < num_ml; ml++) if (selections[0][ml] != null){
for (int y = 0; y < st2; y++){
for (int x = 0; x < (st2 - 1); x++){
int indx1 = y * st2 + x;
int indx2 = y * st2 + x + 1;
for (int np1 = 0; np1 < num_p; np1++){
for (int np2 = 0; np2 < num_p; np2++){
if (selections[np1][ml][indx1] && selections[np2][ml][indx2]){
trans_mat[np1][np2]++;
}
}
}
}
}
for (int x = 0; x < st2; x++){
for (int y = 0; y < (st2 - 1); y++){
int indx1 = y * st2 + x;
int indx2 = y * st2 + x + st2;
for (int np1 = 0; np1 < num_p; np1++){
for (int np2 = 0; np2 < num_p; np2++){
if (selections[np1][ml][indx1] && selections[np2][ml][indx2]){
trans_mat[np1][np2]++;
}
}
}
}
}
}
return trans_mat;
}
public double [][] getTransRel(
int [][] trans_matrix)
{
double [][] trans_rel = new double [trans_matrix.length][trans_matrix.length];
for (int i = 0; i < trans_matrix.length; i++){
for (int j = 0; j < trans_matrix[i].length; j++){
if ((trans_matrix[i][i] + trans_matrix[j][j]) > 0){
trans_rel[i][j] = (trans_matrix[i][j] + trans_matrix[j][i]);
trans_rel[i][j] /= (trans_matrix[i][i] + trans_matrix[j][j]);
}
}
}
return trans_rel;
}
public String [] showSupertileSeparationTitles(
double [][][] disp_strength,
boolean [][][] selections)
{
int num_ml = disp_strength.length;
int num_p = selections.length;
int num_pm = num_ml * num_p;
String [] titles = new String [num_pm + 3 * num_ml];
for (int np = 0; np < num_p; np++){
for (int ml = 0; ml < num_ml; ml++){
titles [np * num_ml + ml] = "p"+np+"_l"+ml;
}
}
for (int ml = 0; ml < num_ml; ml++){
titles [num_pm + 0 * num_ml + ml] = "sel_"+ml;
titles [num_pm + 1 * num_ml + ml] = "disp_"+ml;
titles [num_pm + 2 * num_ml + ml] = "strn_"+ml;
}
return titles;
}
public double [][] showSUpertileSeparation(
double [][][] disp_strength,
boolean [][][] selections)
{
int superTileSize = tileProcessor.getSuperTileSize();
int num_ml = disp_strength.length;
int num_p = selections.length;
int num_pm = num_ml * num_p;
double [][] data = new double [num_pm + 3 * num_ml][]; // 4* superTileSize*superTileSize];
for (int np = 0; np < num_p; np++) if (selections [np] != null){
for (int ml = 0; ml < num_ml; ml++) if ((disp_strength[ml]!=null) && (selections[np][ml] != null)){
int nd = np * num_ml + ml;
data[nd] = new double[4 * superTileSize * superTileSize];
for (int i = 0; i < data[nd].length; i++){
if (selections[np][ml][i] && (disp_strength[ml][1][i] > 0.0)){
data[nd][i] = disp_strength[ml][0][i];
} else {
data[nd][i] = Double.NaN;
}
}
}
}
for (int ml = 0; ml < num_ml; ml++) if (disp_strength[ml]!=null){
int nd = num_pm + 0 * num_ml + ml;
data [nd] = new double [4* superTileSize*superTileSize];
for (int i = 0; i < data[nd].length; i++){
data [nd][i] = Double.NaN;
for (int np = 0; np < num_p; np++) if ((selections [np] != null) && selections [np][ml][i]){
data [nd][i] = np + 1;
break;
}
}
data [num_pm + 1 * num_ml + ml] = disp_strength[ml][0];
data [num_pm + 2 * num_ml + ml] = disp_strength[ml][1];
}
return data;
}
public void processPlanes4(
final boolean [] selected, // or null
final double min_disp,
final int stMeasSel, // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
final double plDispNorm,
final int plMinPoints, // = 5; // Minimal number of points for plane detection
final double plTargetEigen, // = 0.1; // Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below
final double plFractOutliers, // = 0.3; // Maximal fraction of outliers to remove
final int plMaxOutliers, // = 20; // Maximal number of outliers to remove
final boolean plPreferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
final GeometryCorrection geometryCorrection,
final boolean correct_distortions,
final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
final int smplSide, // = 2; // Sample size (side of a square)
final int smplNum, // = 3; // Number after removing worst
final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
final double smallDiff, // = 0.4; // Consider merging initial planes if disparity difference below
final double highMix, //stHighMix = 0.4; // Consider merging initial planes if jumps between ratio above
final double [] vertical_xyz, // real world up unit vector in camera CS (x - right, y - up, z - to camera};
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
if (maxMinMax == null) getMaxMinMax();
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
this.planes = new TilePlanes.PlaneData[nStiles][];
final int debug_stile = (debugLevel > -1)? (dbg_Y * stilesX + dbg_X):-1;
// final boolean [][] dflt_select = {{}, null, null, null, null}; // use layer 0 (combo) only
final boolean [][] dflt_select = new boolean [measuredLayers.getNumLayers()][];
for (int i = 0; i < dflt_select.length; i++){
if ((stMeasSel & (1 << i)) !=0){
dflt_select[i] = new boolean[0];
} else {
dflt_select[i] = null;
}
}
// TODO: Remove when promoting PlaneData
final TilePlanes tpl = new TilePlanes(tileSize,superTileSize, geometryCorrection);
// final double [] disparity = cltPass3d.getDisparity();
// final double [] strength = cltPass3d.getStrength();
measuredLayers.setLayer (
0, // int num_layer,
cltPass3d.getDisparity(), // double [] disparity,
cltPass3d.getStrength(), // double [] strength,
null); // boolean [] selection) // may be null
if (debugLevel > -1) {
String [] titles = {"d0","s0","d1","s1","d2","s2","d3","s3","s","d"};
double [][] dbg_img = new double [titles.length][];
for (int i = 0; i < measuredLayers.getNumLayers(); i++){
dbg_img[2 * i] = measuredLayers.getDisparity(i);
dbg_img[2 * i + 1] = measuredLayers.getStrength(i);
}
dbg_img[8] = cltPass3d.getDisparity();
dbg_img[9] = cltPass3d.getStrength();
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(dbg_img, tileProcessor.getTilesX(), tileProcessor.getTilesY(), true, "measuredLayers",titles);
}
// if (maxMinMax == null)
getMaxMinMax();
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nsTile = ai.getAndIncrement(); nsTile < nStiles; nsTile = ai.getAndIncrement()) {
if (nsTile == debug_stile){
System.out.println("processPlanes4(): nsTile="+nsTile);
}
int stileY = nsTile / stilesX;
int stileX = nsTile % stilesX;
int [] sTiles = {stileX, stileY};
planes[nsTile] = null;
// first make a plane from all tiles
TilePlanes.PlaneData pd0 = tpl.new PlaneData (
sTiles, // int [] sTileXY,
tileSize, // int tileSize,
geometryCorrection, // GeometryCorrection geometryCorrection,
measuredLayers, // MeasuredLayers measuredLayers,
plPreferDisparity); // boolean preferDisparity)
boolean [][] tile_sel = dflt_select.clone();
for (int i = 0; i < dflt_select.length; i++){
if (dflt_select[i] != null) tile_sel[i] = dflt_select[i].clone();
}
int dl1 = (nsTile == debug_stile) ? 3 : 0;
int dl = (nsTile == debug_stile) ? 3 : 0;
ArrayList<TilePlanes.PlaneData> st_planes = new ArrayList<TilePlanes.PlaneData>();
double[][][] disp_strength = new double[measuredLayers.getNumLayers()][][];
for (int ml = 0; ml < disp_strength.length; ml++) if ((stMeasSel & ( 1 << ml)) != 0){
if (smplMode) {
disp_strength[ml] = measuredLayers.getDisparityStrength(
ml, // int num_layer,
stileX, // int stX,
stileY, // int stY,
null, // boolean [] sel_in,
strength_floor, // double strength_floor,
strength_pow, // double strength_pow,
smplSide, // int smplSide, // = 2; // Sample size (side of a square)
smplNum, //int smplNum, // = 3; // Number after removing worst (should be >1)
smplRms, //double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
true); // boolean null_if_none);
} else {
disp_strength[ml] = measuredLayers.getDisparityStrength(
ml, // int num_layer,
stileX, // int stX,
stileY, // int stY,
null, // boolean [] sel_in,
strength_floor, // double strength_floor,
strength_pow, // double strength_pow,
true); // boolean null_if_none);
}
}
boolean OK;
double [][] mm = maxMinMax[nsTile];
if (mm == null){
// double [][][] dbg_min_max = maxMinMax;
// System.out.println("maxMinMax["+nsTile+"] == null");
continue;
}
double [][] max_only = new double [(mm.length + 1)/2][2];
for (int i = 0; i < max_only.length; i++){
max_only[i] = mm[2 * i];
}
boolean [][][] plane_sels = null;
int num_ml = disp_strength.length;
// int num_p = max_only.length;
int num_tiles = 4 * superTileSize * superTileSize;
int [] num_sel;
for (int iter = 0; iter < 2; iter ++){
int num_p = max_only.length;
plane_sels = new boolean[num_p][num_ml][];
num_sel = new int [num_p];
for (int np = 0; np < num_p; np++) {
for (int ml = 0; ml < num_ml; ml++) if (disp_strength[ml] != null) {
plane_sels[np][ml] = new boolean[num_tiles];
}
}
// compare closest to be able to use tilted planes later
for (int ml = 0; ml < num_ml; ml++) if (disp_strength[ml] != null) {
for (int indx = 0; indx < num_tiles; indx++) if (disp_strength[ml][1][indx] > 0.0){
int best_plane = -1;
double best_d2 = Double.NaN;
for (int np = 0; np < num_p; np++) {
double d2 = max_only[np][0] - disp_strength[ml][0][indx];
// add disp_norm correction here?
d2 *= d2;
if (!(d2 >= best_d2)){
best_d2 = d2;
best_plane = np;
}
}
if (best_plane >= 0){ // compare to max diff here too
plane_sels[best_plane][ml][indx] = true; // so far exclusive
}
}
}
// recalculate average disparities for each plane and show number of tiles in each in debug mode
for (int np = 0; np < num_p; np++) {
double sd = 0.0, sw = 0.0;
int nt = 0;
for (int ml = 0; ml < num_ml; ml++) if (disp_strength[ml] != null) {
for (int indx = 0; indx < num_tiles; indx++) if (plane_sels[np][ml][indx]){
double w = disp_strength[ml][1][indx];
sd += w * disp_strength[ml][0][indx];
sw += w;
num_sel[np]++;
}
}
if (sw > 0) {
sd /= sw;
}
if (dl > 0) {
System.out.println("plane num_sel["+np+"] = "+num_sel[np]+" disp "+max_only[np][0]+"->"+sd+
", weight "+max_only[np][1]+"->"+sw);
}
max_only[np][0] = sd;
max_only[np][1] = sw;
}
// calculate transitions matrix (to find candidates for merge
int [][] trans_mat = getTransMatrix(plane_sels);
double [][] rel_trans = getTransRel(trans_mat);
if (dl > 0) {
System.out.println("trans_mat = ");
for (int i = 0; i < trans_mat.length; i++){
System.out.print(i+": ");
for (int j = 0; j < trans_mat[i].length; j++){
System.out.print(trans_mat[i][j]+" ");
}
System.out.println();
}
System.out.println("rel_trans = ");
for (int i = 0; i < rel_trans.length; i++){
System.out.print(i+": ");
for (int j = 0; j < rel_trans[i].length; j++){
System.out.print(rel_trans[i][j]+" ");
}
System.out.println();
}
}
if ((iter > 0 ) && (num_p > 1)){ // remove /join bad
int windx = 0;
int remove_indx = -1;
for (int i = 1; i < num_p; i++) if (num_sel[i] < num_sel[windx]) windx = i;
if (num_sel[windx] < plMinPoints) {
if (debugLevel > 0){
System.out.println ("processPlanes(): stileX = "+stileX+" stileY="+stileY+
": removing plane "+windx+" with "+num_sel[windx]+" tiles ( <"+plMinPoints+")");
}
remove_indx = windx;
}
if (remove_indx < 0) {
// find candidates for merge
windx = -1;
for (int i = 0; i < (num_p - 1); i++) {
if (((max_only[i+1][0] - max_only[i][0]) < smallDiff) && // close enough to consider merging
(rel_trans[i][i+1] > highMix)) {
if ((windx < 0) || (rel_trans[i][i+1] > rel_trans[windx][windx+1])) windx = i;
}
}
if (windx >=0 ) {
if (debugLevel > 0){
System.out.println ("processPlanes(): stileX = "+stileX+" stileY="+stileY+
": merging plane "+windx+" with " + (windx + 1)+": "+
num_sel[windx] + " and "+num_sel[windx+1]+" tiles, "+
" rel_trans="+rel_trans[windx][windx + 1]+ " ( > " + highMix+"),"+
" diff="+ (max_only[windx + 1][0]- max_only[windx][0]) + " ( < " + smallDiff+" ),"+
" disp1 = "+max_only[windx][0]+" disp2 = "+max_only[windx + 1][0]);
}
double sum_w = max_only[windx][1] + max_only[windx + 1][1];
max_only[windx+1][0] = (max_only[windx][0]*max_only[windx][1] + max_only[windx+1][0]*max_only[windx+1][1]) / sum_w;
max_only[windx+1][1] = sum_w;
remove_indx = windx;
}
}
if (remove_indx >= 0){
double [][] max_only_copy = max_only.clone();
for (int i = 0; i < max_only.length; i++) max_only_copy[i] = max_only[i];
max_only = new double [max_only.length - 1][];
int indx = 0;
for (int i = 0; i < max_only_copy.length; i++) if (i != remove_indx) max_only[indx++] =max_only_copy[i];
iter = 0;
continue; // restart from 0
}
// Show other candidates for merge
if (debugLevel > 0){
double max_sep = 0.2;
if (iter > 0) {
for (int i = 0; i < (num_p-1); i++){
if (rel_trans[i][i+1] > max_sep) {
System.out.println("processPlanes4() stileX = "+stileX+" stileY="+stileY+" lowplane = "+i+
" num_sel1 = "+num_sel[i] + " num_sel2 = "+num_sel[i+1] +
" rel_trans="+rel_trans[i][i+1]+
" diff="+ (max_only[i+1][0]- max_only[i][0]) +
" disp1 = "+max_only[i][0]+" disp2 = "+max_only[i+1][0]);
}
}
}
}
}
}
if (dl > 2) {
String [] dbg_titles = showSupertileSeparationTitles( disp_strength, plane_sels);
double [][] dbg_img = showSUpertileSeparation(disp_strength, plane_sels);
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(dbg_img, 2 * superTileSize, 2* superTileSize, true, "initial_separation"+nsTile,dbg_titles);
}
if (dl > 2) {
double [] world_hor = {0.0, 1.0, 0.0};
double sd = 0.0, sw = 0.0;
for (int i = 0; i < max_only.length; i++){
sd += max_only[i][0] * max_only[i][1];
sw += max_only[i][1];
}
if (sw > 0) {
System.out.println("Horizontally tilted disparity for stileX = "+stileX+" stileY="+stileY+", average disparity "+(sd/sw));
double [][][] hor_disp_strength = pd0.getDisparityToPlane(
world_hor, // double [] world_normal_xyz,
sd / sw, // average disparity // double disp_center,
null, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified)
disp_strength, // double [][][] disp_str, // calculate just once if null
1); // int debugLevel);
String [] dbg_titles = showSupertileSeparationTitles( hor_disp_strength, plane_sels);
double [][] dbg_img = showSUpertileSeparation(hor_disp_strength, plane_sels);
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(dbg_img, 2 * superTileSize, 2* superTileSize, true, "hor_separation"+nsTile,dbg_titles);
}
}
for (int m = 0; m < max_only.length; m++) {
// TilePlanes.PlaneData pd = pd0_full.clone();
TilePlanes.PlaneData pd = pd0.clone();
OK = (pd.getPlaneFromMeas(
plane_sels[m], // tile_sel, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified)
disp_strength,
Double.NaN, // double disp_far, // minimal disparity to select (or NaN)
Double.NaN, // double disp_near, // maximal disparity to select (or NaN)
0.0, // plDispNorm, // double dispNorm, // Normalize disparities to the average if above
0.0, // double min_weight,
plMinPoints, // int min_tiles,
strength_floor, //
strength_pow, // double strength_pow,
// update !
smplMode,
smplSide,
smplNum,
smplRms,
dl) != null); // int debugLevel)
if (OK) {
if (dl > 0) {
if (pd.getWeight() > 1.0) {
System.out.println("Processing subplane["+nsTile+"]["+m+"]"+
", stileX="+stileX+
", stileY="+stileY+
", numPoints="+ pd.getNumPoints()+
", swc = "+pd.getWeight()+
", center=["+pd.getZxy()[0]+","+pd.getZxy()[1]+","+pd.getZxy()[2]+"]"+
", eig_val = {"+pd.getValues()[0]+","+pd.getValues()[1]+","+pd.getValues()[2]+"}"+
", eig_vect[0] = {"+pd.getVector()[0]+","+pd.getVector()[1]+","+pd.getVector()[2]+"}");
}
}
// now try to remove outliers
int max_outliers = (int) Math.round(pd.getNumPoints() * plFractOutliers);
if (max_outliers > plMaxOutliers) max_outliers = plMaxOutliers;
double targetV = plTargetEigen;
double z0 = pd.getZxy()[0];
if ((plDispNorm > 0.0) && (z0 > plDispNorm)) {
double dd = (plDispNorm + z0)/ plDispNorm; // > 1
targetV *= dd * dd; // > original
}
if (pd.getValues()[0] > targetV) {
OK = pd.removeOutliers( // getPlaneFromMeas should already have run
disp_strength,
targetV, // double targetEigen, // target eigenvalue for primary axis (is disparity-dependent, so is non-constant)
max_outliers, // int maxRemoved, // maximal number of tiles to remove (not a constant)
dl); // int debugLevel)
if (!OK) {
continue;
}
if (dl > 0) {
if (pd.getWeight() > 1.0) {
System.out.println("Removed outliers["+nsTile+"]["+m+"]"+
", stileX="+stileX+
", stileY="+stileY+
", numPoints="+ pd.getNumPoints()+
", swc = "+pd.getWeight()+
", center=["+pd.getZxy()[0]+","+pd.getZxy()[1]+","+pd.getZxy()[2]+"]"+
", eig_val = {"+pd.getValues()[0]+","+pd.getValues()[1]+","+pd.getValues()[2]+"}"+
", eig_vect[0] = {"+pd.getVector()[0]+","+pd.getVector()[1]+","+pd.getVector()[2]+"}");
}
}
}
double [] norm_xyz = pd.getWorldXYZ(
correct_distortions);
st_planes.add(pd);
if (dl > 0) {
System.out.println("World normal["+nsTile+"]["+m+"] = {"+
norm_xyz[0]+", "+norm_xyz[1]+", "+norm_xyz[2]+"}");
}
}
}
if (st_planes.size() > 0){
st_planes.add(0, st_planes.get(0)); // insert dummy at pos 0;
planes[nsTile] = st_planes.toArray(new TilePlanes.PlaneData[0] );
planes[nsTile][0] = null; // remove dummy
if (dl >0){
System.out.println("processPlanes4(): nsTile="+nsTile);
}
}
// }
}
}
};
}
ImageDtt.startAndJoin(threads);
}
public int [] getShowPlanesWidthHeight() public int [] getShowPlanesWidthHeight()
{ {
final int tilesX = tileProcessor.getTilesX(); final int tilesX = tileProcessor.getTilesX();
...@@ -2054,6 +2650,7 @@ public class SuperTiles{ ...@@ -2054,6 +2650,7 @@ public class SuperTiles{
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
public void run() { public void run() {
TilePlanes.PlaneData [] dbg_planes = null;
for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) { for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) {
int sty0 = nsTile0 / stilesX; int sty0 = nsTile0 / stilesX;
int stx0 = nsTile0 % stilesX; int stx0 = nsTile0 % stilesX;
...@@ -2061,6 +2658,7 @@ public class SuperTiles{ ...@@ -2061,6 +2658,7 @@ public class SuperTiles{
if ( planes[nsTile0] != null) { if ( planes[nsTile0] != null) {
if (dl > 0){ if (dl > 0){
System.out.println("matchPlanes(): nsTile0 ="+nsTile0); System.out.println("matchPlanes(): nsTile0 ="+nsTile0);
dbg_planes = planes[nsTile0];
} }
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
// planes[nsTile0][np0].initNeibBest(); // // planes[nsTile0][np0].initNeibBest(); //
...@@ -2107,6 +2705,10 @@ public class SuperTiles{ ...@@ -2107,6 +2705,10 @@ public class SuperTiles{
} }
} }
} }
if (dl > 0){
System.out.println("matchPlanes(): nsTile0 ="+nsTile0+ " Done.");
}
} }
} }
} }
...@@ -2153,6 +2755,10 @@ public class SuperTiles{ ...@@ -2153,6 +2755,10 @@ public class SuperTiles{
} }
} }
} }
if (dl>0) {
System.out.println("matchPlanes() nsTile0="+nsTile0);
}
} }
} }
}; };
...@@ -3031,6 +3637,10 @@ public class SuperTiles{ ...@@ -3031,6 +3637,10 @@ public class SuperTiles{
int np0_min = (new_planes[nsTile0].length > 1) ? 1:0; // Modify if overall plane will be removed int np0_min = (new_planes[nsTile0].length > 1) ? 1:0; // Modify if overall plane will be removed
for (int np0 = np0_min; np0 < new_planes[nsTile0].length; np0 ++){ for (int np0 = np0_min; np0 < new_planes[nsTile0].length; np0 ++){
TilePlanes.PlaneData this_new_plane = new_planes[nsTile0][np0]; TilePlanes.PlaneData this_new_plane = new_planes[nsTile0][np0];
if (this_new_plane == null){
System.out.println("Bug? new_planes["+nsTile0+"]["+np0+"] == null");
continue;
}
if (dl > 0) dbg_img[ 0] = this_new_plane.getPlaneDisparity(false); if (dl > 0) dbg_img[ 0] = this_new_plane.getPlaneDisparity(false);
if (dl > 0) dbg_img[ 1] = measured_planes[nsTile0][np0].getPlaneDisparity(false); if (dl > 0) dbg_img[ 1] = measured_planes[nsTile0][np0].getPlaneDisparity(false);
...@@ -3324,6 +3934,10 @@ public class SuperTiles{ ...@@ -3324,6 +3934,10 @@ public class SuperTiles{
* correlation strength as weight * correlation strength as weight
* @param strength_pow raise correlation strength (after subtracting strength_floor) to * @param strength_pow raise correlation strength (after subtracting strength_floor) to
* this power before using as weight * this power before using as weight
* @param smplMode use square sample mode, false - single-tile samples
* @param smplSide size of the square sample side
* @param smplNum number of averaged samples (should be <= smplSide * smplSide and > 1)
* @param smplRms maximal square root of variance (in disparity pixels) to accept the result
* @param debugLevel debug level * @param debugLevel debug level
* @param dbg_X supertile horizontal index to show debug information * @param dbg_X supertile horizontal index to show debug information
* @param dbg_Y supertile vertical index to show debug information * @param dbg_Y supertile vertical index to show debug information
...@@ -3356,6 +3970,12 @@ public class SuperTiles{ ...@@ -3356,6 +3970,12 @@ public class SuperTiles{
final int maxOutliers, // = 20; // Maximal number of outliers to remove final int maxOutliers, // = 20; // Maximal number of outliers to remove
final double strength_floor, final double strength_floor,
final double strength_pow, final double strength_pow,
final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
final int smplSide, // = 2; // Sample size (side of a square)
final int smplNum, // = 3; // Number after removing worst
final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
final int debugLevel, final int debugLevel,
final int dbg_X, final int dbg_X,
final int dbg_Y) final int dbg_Y)
...@@ -3375,6 +3995,7 @@ public class SuperTiles{ ...@@ -3375,6 +3995,7 @@ public class SuperTiles{
public void run() { public void run() {
double [][] dbg_img = null; double [][] dbg_img = null;
String [] dbg_titles = null; String [] dbg_titles = null;
TilePlanes.PlaneData[][] dbg_planes = planes;
int numThread = ai_numThread.getAndIncrement(); // unique number of thread to write to rslt_diffs[numThread] int numThread = ai_numThread.getAndIncrement(); // unique number of thread to write to rslt_diffs[numThread]
for (int nsTile = ai.getAndIncrement(); nsTile < planes.length; nsTile = ai.getAndIncrement()) { for (int nsTile = ai.getAndIncrement(); nsTile < planes.length; nsTile = ai.getAndIncrement()) {
int sty = nsTile / stilesX; int sty = nsTile / stilesX;
...@@ -3435,9 +4056,9 @@ public class SuperTiles{ ...@@ -3435,9 +4056,9 @@ public class SuperTiles{
} }
} }
// now work on the pairs in bpd, null them out in case of failure // now works on the pairs in bpd, null them out in case of failure
for (int np = 0; np < bpd.length; np++){ for (int np = 0; np < bpd.length; np++){
if (dl > 1) { if ((dl > 1) && (bpd[np] !=null)) {
int ss2 = 2 * superTileSize; int ss2 = 2 * superTileSize;
dbg_img = new double [dbg_titles.length][]; dbg_img = new double [dbg_titles.length][];
for (int ni = 0; ni < num_bplanes ; ni++) { for (int ni = 0; ni < num_bplanes ; ni++) {
...@@ -3504,6 +4125,10 @@ public class SuperTiles{ ...@@ -3504,6 +4125,10 @@ public class SuperTiles{
other_diff, other_diff,
non_exclusive, // boolean non_exclusive, non_exclusive, // boolean non_exclusive,
use_other_planes, // boolean use_other_planes, use_other_planes, // boolean use_other_planes,
smplMode,
smplSide,
smplNum,
smplRms,
measSel, // int measSel, // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert measSel, // int measSel, // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
allow_parallel, //boolean allow_parallel, allow_parallel, //boolean allow_parallel,
dl); // int debugLevel) dl); // int debugLevel)
...@@ -3527,8 +4152,9 @@ public class SuperTiles{ ...@@ -3527,8 +4152,9 @@ public class SuperTiles{
} }
for (int npip = 0; npip < bpd[np].length; npip++) { for (int npip = 0; npip < bpd[np].length; npip++) {
OK = bpd[np][npip].getPlaneFromMeas( double [][][] disp_strength = bpd[np][npip].getPlaneFromMeas(
null, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified) null, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified)
null,
disp_far, // double disp_far, // minimal disparity to select (or NaN) disp_far, // double disp_far, // minimal disparity to select (or NaN)
disp_near, // double disp_near, // maximal disparity to select (or NaN) disp_near, // double disp_near, // maximal disparity to select (or NaN)
dispNorm, // double dispNorm, // Normalize disparities to the average if above dispNorm, // double dispNorm, // Normalize disparities to the average if above
...@@ -3536,8 +4162,13 @@ public class SuperTiles{ ...@@ -3536,8 +4162,13 @@ public class SuperTiles{
min_tiles, // int min_tiles, min_tiles, // int min_tiles,
strength_floor, // double strength_floor, strength_floor, // double strength_floor,
strength_pow, // double strength_pow, strength_pow, // double strength_pow,
// OK?
smplMode,
smplSide,
smplNum,
smplRms,
dl); // int debugLevel) dl); // int debugLevel)
if (!OK) break; if (disp_strength == null) break;
// remove outliers //removeOutliers // remove outliers //removeOutliers
// now try to remove outliers // now try to remove outliers
int max_outliers = (int) Math.round(bpd[np][npip].getNumPoints() * fractOutliers); int max_outliers = (int) Math.round(bpd[np][npip].getNumPoints() * fractOutliers);
...@@ -3548,6 +4179,7 @@ public class SuperTiles{ ...@@ -3548,6 +4179,7 @@ public class SuperTiles{
bpd[np][npip]); bpd[np][npip]);
if (bpd[np][npip].getValue() > targetV) { if (bpd[np][npip].getValue() > targetV) {
OK = bpd[np][npip].removeOutliers( // getPlaneFromMeas should already have run OK = bpd[np][npip].removeOutliers( // getPlaneFromMeas should already have run
disp_strength,
targetV, // double targetEigen, // target eigenvalue for primary axis (is disparity-dependent, so is non-constant) targetV, // double targetEigen, // target eigenvalue for primary axis (is disparity-dependent, so is non-constant)
max_outliers, // int maxRemoved, // maximal number of tiles to remove (not a constant) max_outliers, // int maxRemoved, // maximal number of tiles to remove (not a constant)
dl); // int debugLevel) dl); // int debugLevel)
...@@ -3596,12 +4228,11 @@ public class SuperTiles{ ...@@ -3596,12 +4228,11 @@ public class SuperTiles{
if (npairs > 0){ if (npairs > 0){
TilePlanes.PlaneData[] old_planes = planes[nsTile]; TilePlanes.PlaneData[] old_planes = planes[nsTile];
planes[nsTile] = new TilePlanes.PlaneData[old_planes.length + npairs + np_start]; int old_len = old_planes.length - LOWEST_PLANE(old_planes.length);
planes[nsTile] = new TilePlanes.PlaneData[old_len + npairs + np_start];
int npr = 0; int npr = 0;
if (np_start > 0){ for (int np = LOWEST_PLANE(old_planes.length); np < np_start; np++) {
// planes[nsTile][npr++] = old_planes[0]; planes[nsTile][npr++] = null; // see if there will be any conflicts, fix or replace with old_planes[0];
planes[nsTile][npr++] = null; // see if there will be any conflicts, fis or replace with old_planes[0];
} }
for (int np = 0; np < bpd.length; np++){ for (int np = 0; np < bpd.length; np++){
if (bpd[np] != null) { if (bpd[np] != null) {
......
...@@ -77,6 +77,12 @@ public class TilePlanes { ...@@ -77,6 +77,12 @@ public class TilePlanes {
int min_tiles = 10; int min_tiles = 10;
double dispNorm = 5.0; // Normalize disparities to the average if above double dispNorm = 5.0; // Normalize disparities to the average if above
boolean smplMode = true; // Use sample mode (false - regular tile mode)
int smplSide = 2; // Sample size (side of a square)
int smplNum = 3; // Number after removing worst
double smplRms = 0.1; // Maximal RMS of the remaining tiles in a sample
boolean preferDisparity = false; boolean preferDisparity = false;
public PlaneData clone(){ public PlaneData clone(){
...@@ -89,13 +95,16 @@ public class TilePlanes { ...@@ -89,13 +95,16 @@ public class TilePlanes {
pd.num_points = this.num_points; pd.num_points = this.num_points;
pd.weight = this.weight; pd.weight = this.weight;
if (this.plane_sel != null) pd.plane_sel = this.plane_sel.clone(); if (this.plane_sel != null) pd.plane_sel = this.plane_sel.clone();
if (this.zxy != null) pd.zxy = this.zxy.clone();
if (this.values != null) pd.values = this.values.clone(); if (this.values != null) pd.values = this.values.clone();
if (this.zxy != null) pd.zxy = this.zxy.clone();
// World calculations should be invalidated during cloning?
/*
if (this.center_xyz != null) pd.center_xyz = this.center_xyz.clone(); if (this.center_xyz != null) pd.center_xyz = this.center_xyz.clone();
if (this.world_xyz != null) pd.world_xyz = this.world_xyz.clone(); if (this.world_xyz != null) pd.world_xyz = this.world_xyz.clone();
if (this.world_v1 != null) pd.world_v1 = this.world_v1.clone(); if (this.world_v1 != null) pd.world_v1 = this.world_v1.clone();
if (this.world_v2 != null) pd.world_v2 = this.world_v2.clone(); if (this.world_v2 != null) pd.world_v2 = this.world_v2.clone();
// if (this.daxy != null) pd.daxy = this.daxy.clone(); */
if (this.vectors != null) { if (this.vectors != null) {
pd.vectors = new double[3][]; pd.vectors = new double[3][];
pd.vectors[0] = this.vectors[0].clone(); pd.vectors[0] = this.vectors[0].clone();
...@@ -115,6 +124,11 @@ public class TilePlanes { ...@@ -115,6 +124,11 @@ public class TilePlanes {
pd.min_tiles = this.min_tiles; pd.min_tiles = this.min_tiles;
pd.dispNorm = this.dispNorm; pd.dispNorm = this.dispNorm;
pd.smplMode = this.smplMode;
pd.smplSide = this.smplSide;
pd.smplNum = this.smplNum;
pd.smplRms = this.smplRms;
pd.preferDisparity = this.preferDisparity; pd.preferDisparity = this.preferDisparity;
copyNeib(this,pd); copyNeib(this,pd);
...@@ -288,6 +302,10 @@ public class TilePlanes { ...@@ -288,6 +302,10 @@ public class TilePlanes {
* *
* @param non_exclusive allow the same tile data to belong to multiple PD instances * @param non_exclusive allow the same tile data to belong to multiple PD instances
* @param use_other_planes allow the same tile not included in this PD to be used * @param use_other_planes allow the same tile not included in this PD to be used
* @param smplMode use square sample mode, false - single-tile samples
* @param smplSide size of the square sample side
* @param smplNum number of averaged samples (should be <= smplSide * smplSide and > 1)
* @param smplRms maximal square root of variance (in disparity pixels) to accept the result
* @param measSel (with use_other_planes) select measurements for supertiles : * @param measSel (with use_other_planes) select measurements for supertiles :
* +1 - combo, +2 - quad +4 - hor +8 - vert * +1 - combo, +2 - quad +4 - hor +8 - vert
* @param allow_parallel allow parallel shift of each plane before adding more data * @param allow_parallel allow parallel shift of each plane before adding more data
...@@ -302,6 +320,10 @@ public class TilePlanes { ...@@ -302,6 +320,10 @@ public class TilePlanes {
double other_diff, double other_diff,
boolean non_exclusive, boolean non_exclusive,
boolean use_other_planes, boolean use_other_planes,
boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
int smplSide, // = 2; // Sample size (side of a square)
int smplNum, // = 3; // Number after removing worst
double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
int measSel, // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert int measSel, // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
boolean allow_parallel, boolean allow_parallel,
int debugLevel) int debugLevel)
...@@ -332,6 +354,19 @@ public class TilePlanes { ...@@ -332,6 +354,19 @@ public class TilePlanes {
// split exclusively, calculate rms for each, then add others if RMS is not increased // split exclusively, calculate rms for each, then add others if RMS is not increased
for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++){ for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++){
if ((measuredSelection[nl] != null) && ((measSel & (1 << nl)) !=0)) { if ((measuredSelection[nl] != null) && ((measSel & (1 << nl)) !=0)) {
if (smplMode) {
disp_strength[nl] = measuredLayers.getDisparityStrength( // expensive to calculate (improve removing outlayers
nl, // int num_layer,
getSTileXY()[0], // int stX,
getSTileXY()[1], // int stY,
(single_plane ? null : measuredSelection[nl]), // boolean [] sel_in,
strength_floor,
measured_strength_pow, //
smplSide, // = 2; // Sample size (side of a square)
smplNum, // = 3; // Number after removing worst
smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
true); // boolean null_if_none)
} else {
disp_strength[nl] = measuredLayers.getDisparityStrength( disp_strength[nl] = measuredLayers.getDisparityStrength(
nl, // int num_layer, nl, // int num_layer,
getSTileXY()[0], // int stX, getSTileXY()[0], // int stX,
...@@ -340,6 +375,7 @@ public class TilePlanes { ...@@ -340,6 +375,7 @@ public class TilePlanes {
strength_floor, // double strength_floor, strength_floor, // double strength_floor,
measured_strength_pow, // double strength_pow, measured_strength_pow, // double strength_pow,
true); // boolean null_if_none); true); // boolean null_if_none);
}
if (disp_strength[nl] != null) { if (disp_strength[nl] != null) {
for (int indx = 0; indx < disp_strength[nl][1].length; indx++){ for (int indx = 0; indx < disp_strength[nl][1].length; indx++){
double w = disp_strength[nl][1][indx]; double w = disp_strength[nl][1][indx];
...@@ -381,7 +417,6 @@ public class TilePlanes { ...@@ -381,7 +417,6 @@ public class TilePlanes {
if (allow_parallel && (non_exclusive || use_other_planes)){ if (allow_parallel && (non_exclusive || use_other_planes)){
for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++){ for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++){
if (disp_strength[nl] != null) { if (disp_strength[nl] != null) {
//disp_strength[nl] = measuredLayers.getDisparityStrength(
for (int indx = 0; indx < disp_strength[nl][1].length; indx++){ for (int indx = 0; indx < disp_strength[nl][1].length; indx++){
double w = disp_strength[nl][1][indx]; double w = disp_strength[nl][1][indx];
if (w > 0.0){ if (w > 0.0){
...@@ -410,7 +445,6 @@ public class TilePlanes { ...@@ -410,7 +445,6 @@ public class TilePlanes {
for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++){ for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++){
if ((measuredSelection[nl] != null) && ((measSel & (1 << nl)) !=0)) { if ((measuredSelection[nl] != null) && ((measSel & (1 << nl)) !=0)) {
if (disp_strength[nl] != null) { if (disp_strength[nl] != null) {
//disp_strength[nl] = measuredLayers.getDisparityStrength(
for (int indx = 0; indx < disp_strength[nl][1].length; indx++){ for (int indx = 0; indx < disp_strength[nl][1].length; indx++){
double w = disp_strength[nl][1][indx]; double w = disp_strength[nl][1][indx];
if (w > 0.0){ if (w > 0.0){
...@@ -444,6 +478,29 @@ public class TilePlanes { ...@@ -444,6 +478,29 @@ public class TilePlanes {
for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++){ for (int nl = 0; nl < measuredLayers.getNumLayers(); nl ++){
if ((measuredSelection[nl] != null) && ((measSel & (1 << nl)) !=0)) { if ((measuredSelection[nl] != null) && ((measSel & (1 << nl)) !=0)) {
// recalculate for all measure tiles, not just selected in the original PD // recalculate for all measure tiles, not just selected in the original PD
if (smplMode) {
disp_strength[nl] = measuredLayers.getDisparityStrength( // expensive to calculate (improve removing outlayers
nl, // int num_layer,
getSTileXY()[0], // int stX,
getSTileXY()[1], // int stY,
null, // boolean [] sel_in,
strength_floor,
measured_strength_pow, //
smplSide, // = 2; // Sample size (side of a square)
smplNum, // = 3; // Number after removing worst
smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
true); // boolean null_if_none)
} else {
disp_strength[nl] = measuredLayers.getDisparityStrength(
nl, // int num_layer,
getSTileXY()[0], // int stX,
getSTileXY()[1], // int stY,
null, // boolean [] sel_in,
strength_floor, // double strength_floor,
measured_strength_pow, // double strength_pow,
true); // boolean null_if_none);
}
/*
disp_strength[nl] = measuredLayers.getDisparityStrength( disp_strength[nl] = measuredLayers.getDisparityStrength(
nl, // int num_layer, nl, // int num_layer,
getSTileXY()[0], // int stX, getSTileXY()[0], // int stX,
...@@ -452,6 +509,7 @@ public class TilePlanes { ...@@ -452,6 +509,7 @@ public class TilePlanes {
strength_floor, // double strength_floor, strength_floor, // double strength_floor,
measured_strength_pow, // double strength_pow, measured_strength_pow, // double strength_pow,
true); // boolean null_if_none); true); // boolean null_if_none);
*/
//disp_strength[nl] = measuredLayers.getDisparityStrength( //disp_strength[nl] = measuredLayers.getDisparityStrength(
for (int indx = 0; indx < disp_strength[nl][1].length; indx++){ for (int indx = 0; indx < disp_strength[nl][1].length; indx++){
double w = disp_strength[nl][1][indx]; double w = disp_strength[nl][1][indx];
...@@ -495,10 +553,82 @@ public class TilePlanes { ...@@ -495,10 +553,82 @@ public class TilePlanes {
return true; return true;
} }
/**
* Tilt disparity values around the supertile center (this.zxy) so constant disparity in the output
* corresponds to the real world plane parallel to the provided one. Used to discriminate tiles by
* the effective disparity value (disparity in the center of the supertile of the parallel plane)
* @param world_normal_xyz real world 3d vector of the plane normal (0.0, 1.0, 0.0 - horizontal)
* @param disp_center dispariy in at the center of the supertile (to rotate around)
* @param tile_sel multi-layer tile selection (or null to use all available tiles)
* @param disp_str multi-layer disparity/strength array
* @param debugLevel
* @return same
*/
public double [][][] getDisparityToPlane(
double [] world_normal_xyz,
double disp_center,
boolean [][] tile_sel, // null - do not use, {} use all (will be modified)
double [][][] disp_str, // calculate just once if null
int debugLevel)
{
final int stSize2 = 2* stSize;
invalidateCalculated();
double [] px_py = getCenterPxPy();
// find world coordinates of the center of tile intersection with the plane
Matrix st_xyz = new Matrix(geometryCorrection.getWorldCoordinates(
px_py[0],
px_py[1],
disp_center,
this.correctDistortions),3);
Matrix normal_row = new Matrix(world_normal_xyz,1); // 1x3
double [][][] eff_disp_str = disp_str.clone();
for (int ml = 0; ml < disp_str.length; ml++) {
if (disp_str[ml] != null){
eff_disp_str[ml] = new double [2][];
eff_disp_str[ml][0] = new double [disp_str[ml][0].length];
eff_disp_str[ml][1] = disp_str[ml][1]; // keep same strengths
}
}
double n_by_w = normal_row.times(st_xyz).get(0, 0);
System.out.println("st_xyz = {"+st_xyz.get(0, 0)+","+st_xyz.get(1, 0)+","+st_xyz.get(2, 0)+"}"+" ="+n_by_w);
for (int ml = 0; ml < disp_str.length; ml++) if (disp_str[ml] != null){
for (int dy = 0; dy < stSize2; dy ++ ){
double y = (dy - stSize + 0.5) * tileSize;
for (int dx = 0; dx < stSize2; dx ++ ){
double x = (dx - stSize + 0.5) * tileSize;
int indx = dy * stSize2 + dx;
if ((disp_str[ml][1][indx] > 0) && ((tile_sel == null) || ((tile_sel[ml] != null) && tile_sel[ml][indx]))){ // do not bother with zero-strength
// Find world coordinates of a measured tile
Matrix w_xyz = new Matrix(geometryCorrection.getWorldCoordinates(
px_py[0] + x,
px_py[1] + y,
disp_str[ml][0][indx],
this.correctDistortions),3);
// now find intersection of the view line (0,0,0) to world_xyz with a plane through wxyz perpendicular to world_normal_xyz
// then calculate disparity from z of that point
// inner product of transposed
double n_by_p = normal_row.times(w_xyz).get(0, 0);
double z = st_xyz.get(2, 0)*n_by_p / n_by_w;
if (disp_str[ml][1][indx] > 0){ // do not bother with zero-strength
System.out.println("dy = "+dy+", dx=" + dx+ " {"+w_xyz.get(0, 0)+","+w_xyz.get(1, 0)+","+w_xyz.get(2, 0)+"}"+" z="+z+" n_by_p = "+n_by_p
+" disp = "+disp_str[ml][0][indx]+" px = "+(px_py[0] + x)+" py = "+(px_py[1] + y));
}
// convert z to disparity
eff_disp_str[ml][0][indx] = geometryCorrection.getDisparityFromZ (-z);
}
}
}
}
return eff_disp_str;
}
/** /**
* Remove outliers from the set of tiles contributing to a single plane ellipsoid * Remove outliers from the set of tiles contributing to a single plane ellipsoid
* Should run after getPlaneFromMeas as some parameter4s will be copied from that run * Should run after getPlaneFromMeas as some parameter4s will be copied from that run
* @param disp_str - pre-calculated array or null (will be calculated). disp_str
* has the same format as the output of getPlaneFromMeas - [measurement layer][2][tile index],
* so it can be used for input.
* @param targetEigen Target value for the lowest eigenvalue (thickness of the ellipsoid) * @param targetEigen Target value for the lowest eigenvalue (thickness of the ellipsoid)
* @param maxRemoved maximal number of tiles to be removed * @param maxRemoved maximal number of tiles to be removed
* @param debugLevel debug level * @param debugLevel debug level
...@@ -506,12 +636,45 @@ public class TilePlanes { ...@@ -506,12 +636,45 @@ public class TilePlanes {
*/ */
public boolean removeOutliers( // getPlaneFromMeas should already have run public boolean removeOutliers( // getPlaneFromMeas should already have run
double [][][] disp_str, // calculate just once when removing outliers (null - OK, will generate it)
double targetEigen, // target eigenvalue for primary axis (is disparity-dependent, so is non-constant) double targetEigen, // target eigenvalue for primary axis (is disparity-dependent, so is non-constant)
int maxRemoved, // maximal number of tiles to remove (not a constant) int maxRemoved, // maximal number of tiles to remove (not a constant)
int debugLevel) int debugLevel)
{ {
int stSize2 = 2 * stSize; int stSize2 = 2 * stSize;
if (maxRemoved > (getNumPoints() - this.min_tiles)) maxRemoved = getNumPoints() - this.min_tiles; if (maxRemoved > (getNumPoints() - this.min_tiles)) maxRemoved = getNumPoints() - this.min_tiles;
boolean need_disp_str = false;
if (disp_str == null) {
disp_str = new double [measuredSelection.length][][];
for (int nl = 0; nl < measuredSelection.length; nl++){
if (measuredSelection[nl] != null){
if (smplMode) {
if (need_disp_str) {
disp_str[nl] = measuredLayers.getDisparityStrength( // expensive to calculate (improve removing outlayers
nl, // int num_layer,
sTileXY[0], // int stX,
sTileXY[1], // int stY,
null, // measuredSelection[nl], // boolean [] sel_in,
strength_floor,
measured_strength_pow, //
smplSide, // = 2; // Sample size (side of a square)
smplNum, // = 3; // Number after removing worst
smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
true); // boolean null_if_none)
}
} else {
disp_str[nl] = measuredLayers.getDisparityStrength(
nl, // int num_layer,
sTileXY[0], // int stX,
sTileXY[1], // int stY,
null, // measuredSelection[nl], // boolean [] sel_in,
strength_floor, //
measured_strength_pow, //
true); // boolean null_if_none)
}
}
}
}
int numRemoved = 0; int numRemoved = 0;
boolean no_bugs = true; boolean no_bugs = true;
for (; (getValue() > targetEigen) && (numRemoved < maxRemoved); numRemoved++){ for (; (getValue() > targetEigen) && (numRemoved < maxRemoved); numRemoved++){
...@@ -520,14 +683,16 @@ public class TilePlanes { ...@@ -520,14 +683,16 @@ public class TilePlanes {
} }
// make a plane and find the worst (largest disparity difference) tile // make a plane and find the worst (largest disparity difference) tile
// z = -(x*Vx + y*Vy)/Vz // z = -(x*Vx + y*Vy)/Vz
double [][][] disp_str = new double [measuredSelection.length][][];
// double [][][] disp_str = new double [measuredSelection.length][][];
double worst_d2 = 0.0; double worst_d2 = 0.0;
int [] worst_layer_index = {-1,-1}; int [] worst_layer_index = {-1,-1};
double [] v = getVector(); double [] v = getVector();
double [] zxy0 = getZxy(); double [] zxy0 = getZxy();
for (int nl = 0; nl < measuredSelection.length; nl++){ for (int nl = 0; nl < measuredSelection.length; nl++){
if (measuredSelection[nl] != null){ if (measuredSelection[nl] != null){
// already calculated, but not masked by selection!
/*
disp_str[nl] = measuredLayers.getDisparityStrength( disp_str[nl] = measuredLayers.getDisparityStrength(
nl, // int num_layer, nl, // int num_layer,
sTileXY[0], // int stX, sTileXY[0], // int stX,
...@@ -536,10 +701,11 @@ public class TilePlanes { ...@@ -536,10 +701,11 @@ public class TilePlanes {
strength_floor, // strength_floor, //
measured_strength_pow, // measured_strength_pow, //
true); // boolean null_if_none) true); // boolean null_if_none)
*/
if (disp_str[nl] != null) { if (disp_str[nl] != null) {
for (int indx = 0; indx < disp_str[nl][0].length; indx++){ for (int indx = 0; indx < disp_str[nl][0].length; indx++){
double w = disp_str[nl][1][indx]; double w = disp_str[nl][1][indx];
if (w > 0.0){ if (measuredSelection[nl][indx] && (w > 0.0)){
double x = ((indx % stSize2) - stSize) - zxy0[1]; double x = ((indx % stSize2) - stSize) - zxy0[1];
double y = ((indx / stSize2) - stSize) - zxy0[2]; double y = ((indx / stSize2) - stSize) - zxy0[2];
double d = disp_str[nl][0][indx]; double d = disp_str[nl][0][indx];
...@@ -566,8 +732,9 @@ public class TilePlanes { ...@@ -566,8 +732,9 @@ public class TilePlanes {
System.out.println("removePlaneOutliers() worst_layer="+worst_layer_index[0]+", worst_index="+worst_layer_index[1]); System.out.println("removePlaneOutliers() worst_layer="+worst_layer_index[0]+", worst_index="+worst_layer_index[1]);
} }
boolean OK = getPlaneFromMeas( boolean OK = (getPlaneFromMeas(
null, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified) measuredSelection, // null, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified)
disp_str,
Double.NaN, // double disp_far, // minimal disparity to select (or NaN) Double.NaN, // double disp_far, // minimal disparity to select (or NaN)
Double.NaN, // double disp_near, // maximal disparity to select (or NaN) Double.NaN, // double disp_near, // maximal disparity to select (or NaN)
this.dispNorm, // double dispNorm, // Normalize disparities to the average if above this.dispNorm, // double dispNorm, // Normalize disparities to the average if above
...@@ -575,12 +742,17 @@ public class TilePlanes { ...@@ -575,12 +742,17 @@ public class TilePlanes {
this.min_tiles, // int min_tiles, this.min_tiles, // int min_tiles,
strength_floor, strength_floor,
measured_strength_pow, // double strength_pow, measured_strength_pow, // double strength_pow,
debugLevel); smplMode,
smplSide,
smplNum,
smplRms,
debugLevel-1) != null);
if (!OK){ // restore last selection, re-run getPlaneFromMeas if (!OK){ // restore last selection, re-run getPlaneFromMeas
measuredSelection[worst_layer_index[0]][worst_layer_index[1]] = true; measuredSelection[worst_layer_index[0]][worst_layer_index[1]] = true;
OK = getPlaneFromMeas( OK = (getPlaneFromMeas(
null, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified) measuredSelection, // null, // boolean [][] tile_sel, // null - do not use, {} use all (will be modified)
disp_str,
Double.NaN, // double disp_far, // minimal disparity to select (or NaN) Double.NaN, // double disp_far, // minimal disparity to select (or NaN)
Double.NaN, // double disp_near, // maximal disparity to select (or NaN) Double.NaN, // double disp_near, // maximal disparity to select (or NaN)
this.dispNorm, // double dispNorm, // Normalize disparities to the average if above this.dispNorm, // double dispNorm, // Normalize disparities to the average if above
...@@ -588,7 +760,11 @@ public class TilePlanes { ...@@ -588,7 +760,11 @@ public class TilePlanes {
this.min_tiles, // int min_tiles, this.min_tiles, // int min_tiles,
strength_floor, strength_floor,
measured_strength_pow, // double strength_pow, measured_strength_pow, // double strength_pow,
debugLevel); smplMode,
smplSide,
smplNum,
smplRms,
debugLevel-1) != null);
if (!OK) { if (!OK) {
System.out.println("This is a BUG in removePlaneOutliers() - run with previous selection and failed"); System.out.println("This is a BUG in removePlaneOutliers() - run with previous selection and failed");
no_bugs = false; no_bugs = false;
...@@ -605,8 +781,10 @@ public class TilePlanes { ...@@ -605,8 +781,10 @@ public class TilePlanes {
* match number of measurement layers. each element can be either: * match number of measurement layers. each element can be either:
* a) boolean array 4* superTileSize * superTileSize length * a) boolean array 4* superTileSize * superTileSize length
* b) zero-length array - it will be calculated from all measurement * b) zero-length array - it will be calculated from all measurement
* data on that layer matching optional diaparity limits * data on that layer matching optional disparity limits
* c) null - this measuremen5t layer will not be used * c) null - this measuremen5t layer will not be used
* @param disp_str - pre-calculated array or null (will be calculated). disp_str
* has the same format as the output [measurement layer][2][tile index]
* @param disp_far optional low limit for tile disparity (NaN - do not check) * @param disp_far optional low limit for tile disparity (NaN - do not check)
* @param disp_near optional high limit for tile disparity (NaN - do not check) * @param disp_near optional high limit for tile disparity (NaN - do not check)
* @param dispNorm reduce scale of the disparity differences for ellipsoids with * @param dispNorm reduce scale of the disparity differences for ellipsoids with
...@@ -614,11 +792,17 @@ public class TilePlanes { ...@@ -614,11 +792,17 @@ public class TilePlanes {
* @param min_weight minimal total weight of the ellipsoid do process * @param min_weight minimal total weight of the ellipsoid do process
* @param min_tiles minimal number of tiles used for calculation * @param min_tiles minimal number of tiles used for calculation
* @param strength_pow raise correlation strength to this power * @param strength_pow raise correlation strength to this power
* @param smplMode use square sample mode, false - single-tile samples
* @param smplSide size of the square sample side
* @param smplNum number of averaged samples (should be <= smplSide * smplSide and > 1)
* @param smplRms maximal square root of variance (in disparity pixels) to accept the result
*
* @param debugLevel debug level * @param debugLevel debug level
* @return true if OK, false if failed * @return per measurement layer disparity/strengths, or null if failed
*/ */
public boolean getPlaneFromMeas( public double [][][] getPlaneFromMeas(
boolean [][] tile_sel, // null - do not use, {} use all (will be modified) boolean [][] tile_sel, // null - do not use, {} use all (will be modified)
double [][][] disp_str, // calculate just once when removing outlayers
double disp_far, // minimal disparity to select (or NaN) double disp_far, // minimal disparity to select (or NaN)
double disp_near, // maximal disparity to select (or NaN) double disp_near, // maximal disparity to select (or NaN)
double dispNorm, // Normalize disparities to the average if above double dispNorm, // Normalize disparities to the average if above
...@@ -626,6 +810,11 @@ public class TilePlanes { ...@@ -626,6 +810,11 @@ public class TilePlanes {
int min_tiles, int min_tiles,
double strength_floor, double strength_floor,
double strength_pow, double strength_pow,
boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
int smplSide, // = 2; // Sample size (side of a square)
int smplNum, // = 3; // Number after removing worst
double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
int debugLevel) int debugLevel)
{ {
double mindet = 1E-15; double mindet = 1E-15;
...@@ -637,18 +826,60 @@ public class TilePlanes { ...@@ -637,18 +826,60 @@ public class TilePlanes {
} else { } else {
tile_sel = this.measuredSelection; tile_sel = this.measuredSelection;
} }
double [][][] disp_str = new double [tile_sel.length][][];
this.strength_floor = strength_floor; this.strength_floor = strength_floor;
this.measured_strength_pow = strength_pow; this.measured_strength_pow = strength_pow;
this.min_weight = min_weight; this.min_weight = min_weight;
this.min_tiles = min_tiles; this.min_tiles = min_tiles;
this.dispNorm = dispNorm; this.dispNorm = dispNorm;
if (debugLevel > 3){ this.smplMode = smplMode; // = true; // Use sample mode (false - regular tile mode)
this.smplSide = smplSide; // = 2; // Sample size (side of a square)
this.smplNum = smplNum; // = 3; // Number after removing worst
this.smplRms = smplRms; // = 0.1; // Maximal RMS of the remaining tiles in a sample
if (debugLevel > 2){
System.out.println("getPlaneFromMeas()"); System.out.println("getPlaneFromMeas()");
} }
boolean need_disp_str = false;
if (disp_str == null) {
disp_str = new double [tile_sel.length][][];
need_disp_str = true;
}
for (int nl = 0; nl < tile_sel.length; nl++){ for (int nl = 0; nl < tile_sel.length; nl++){
if (tile_sel[nl] != null){ if (tile_sel[nl] != null){
if (smplMode) {
if (need_disp_str) {
disp_str[nl] = measuredLayers.getDisparityStrength( // expensive to calculate (improve removing outlayers
nl, // int num_layer,
sTileXY[0], // int stX,
sTileXY[1], // int stY,
((tile_sel[nl].length == 0)? null:tile_sel[nl]), // boolean [] sel_in,
//tile_sel[nl], // boolean [] sel_in,
strength_floor,
strength_pow, //
smplSide, // = 2; // Sample size (side of a square)
smplNum, // = 3; // Number after removing worst
smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
true); // boolean null_if_none)
}
if (disp_str[nl] == null) continue;
if (Double.isNaN(disp_far) && Double.isNaN(disp_near)){
tile_sel[nl] = measuredLayers.getSupertileSelection(
disp_str[nl],
((tile_sel[nl].length == 0)? null:tile_sel[nl]), // boolean [] sel_in,
true); // boolean null_if_none)
} else {
tile_sel[nl] = measuredLayers.getSupertileSelection(
disp_str[nl],
((tile_sel[nl].length == 0)? null:tile_sel[nl]), // boolean [] sel_in,
disp_far, // double disp_far,
disp_near, // double disp_near,
true); // boolean null_if_none)
}
sw += MeasuredLayers.getSumStrength(disp_str[nl],tile_sel[nl]);
num_tiles += MeasuredLayers.getNumSelected(tile_sel[nl]);
} else {
if (Double.isNaN(disp_far) && Double.isNaN(disp_near)){ if (Double.isNaN(disp_far) && Double.isNaN(disp_near)){
tile_sel[nl] = measuredLayers.getSupertileSelection( tile_sel[nl] = measuredLayers.getSupertileSelection(
nl, // int num_layer, nl, // int num_layer,
...@@ -681,7 +912,11 @@ public class TilePlanes { ...@@ -681,7 +912,11 @@ public class TilePlanes {
true); // boolean null_if_none) true); // boolean null_if_none)
sw += MeasuredLayers.getSumStrength(disp_str[nl]); sw += MeasuredLayers.getSumStrength(disp_str[nl]);
} }
}
if ((debugLevel > 3) && (disp_str[nl] != null)){ if ((debugLevel > 3) && (disp_str[nl] != null)){
// if ((debugLevel > 1) && (disp_str[nl] != null)){
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
double [][] dbg_img = new double [3][]; double [][] dbg_img = new double [3][];
dbg_img[0] = disp_str[nl][0]; dbg_img[0] = disp_str[nl][0];
...@@ -690,16 +925,17 @@ public class TilePlanes { ...@@ -690,16 +925,17 @@ public class TilePlanes {
for (int i = 0; i < dbg_img[2].length; i++){ for (int i = 0; i < dbg_img[2].length; i++){
dbg_img[2][i] = tile_sel[nl][i]?1.0:0.0; dbg_img[2][i] = tile_sel[nl][i]?1.0:0.0;
} }
sdfa_instance.showArrays(dbg_img, stSize2, stSize2, true, "disp_str_"+nl); sdfa_instance.showArrays(dbg_img, stSize2, stSize2, true, "disp_str_x"+sTileXY[0]+"_y"+sTileXY[1]+"_"+nl);
} }
} }
} }
this.measuredSelection = tile_sel; // it may be modified
if ((sw < min_weight) || (num_tiles < min_tiles)) { if ((sw < min_weight) || (num_tiles < min_tiles)) {
if (debugLevel > 1){ if (debugLevel > 1){
System.out.println("getPlaneFromMeas():return false"); System.out.println("getPlaneFromMeas():return false");
} }
return false; // too weak plane or too few tiles selected return null; // too weak plane or too few tiles selected
} }
...@@ -709,6 +945,7 @@ public class TilePlanes { ...@@ -709,6 +945,7 @@ public class TilePlanes {
for (int nl = 0; nl < tile_sel.length; nl++){ for (int nl = 0; nl < tile_sel.length; nl++){
if (disp_str[nl] != null) { if (disp_str[nl] != null) {
for (int indx = 0; indx < disp_str[nl][0].length; indx++){ for (int indx = 0; indx < disp_str[nl][0].length; indx++){
if (tile_sel[nl][indx]) {
double w = disp_str[nl][1][indx]; double w = disp_str[nl][1][indx];
if (w > 0.0){ if (w > 0.0){
double d = disp_str[nl][0][indx]; double d = disp_str[nl][0][indx];
...@@ -723,8 +960,9 @@ public class TilePlanes { ...@@ -723,8 +960,9 @@ public class TilePlanes {
} }
} }
} }
}
if (sw == 0.0) { if (sw == 0.0) {
return false; // return null; //
} }
swz /= sw; swz /= sw;
swx /= sw; swx /= sw;
...@@ -741,6 +979,7 @@ public class TilePlanes { ...@@ -741,6 +979,7 @@ public class TilePlanes {
for (int nl = 0; nl < tile_sel.length; nl++){ for (int nl = 0; nl < tile_sel.length; nl++){
if (disp_str[nl] != null) { if (disp_str[nl] != null) {
for (int indx = 0; indx < disp_str[nl][0].length; indx++){ for (int indx = 0; indx < disp_str[nl][0].length; indx++){
if (tile_sel[nl][indx]) {
double w = disp_str[nl][1][indx] / sw; double w = disp_str[nl][1][indx] / sw;
if (w > 0.0){ if (w > 0.0){
double d = kz * (disp_str[nl][0][indx] - swz); double d = kz * (disp_str[nl][0][indx] - swz);
...@@ -757,6 +996,7 @@ public class TilePlanes { ...@@ -757,6 +996,7 @@ public class TilePlanes {
} }
} }
} }
}
acovar [1][0] = acovar [0][1]; acovar [1][0] = acovar [0][1];
acovar [2][0] = acovar [0][2]; acovar [2][0] = acovar [0][2];
acovar [2][1] = acovar [1][2]; acovar [2][1] = acovar [1][2];
...@@ -781,7 +1021,7 @@ public class TilePlanes { ...@@ -781,7 +1021,7 @@ public class TilePlanes {
eig.getV().print(10, 6); // w,d eig.getV().print(10, 6); // w,d
} }
if ((eig.getD().get(0, 0) == 0.0) || (Math.abs(covar.det()) < mindet)) { if ((eig.getD().get(0, 0) == 0.0) || (Math.abs(covar.det()) < mindet)) {
return false; // testing with zero eigenvalue return null; // testing with zero eigenvalue
// Problem with zero eigenvalue is with derivatives and coordinate conversion // Problem with zero eigenvalue is with derivatives and coordinate conversion
} }
/* /*
...@@ -864,7 +1104,7 @@ public class TilePlanes { ...@@ -864,7 +1104,7 @@ public class TilePlanes {
} }
setPlaneSelection(plane_sel); setPlaneSelection(plane_sel);
return true; return disp_str;
} }
public double [][] initMergedValue() public double [][] initMergedValue()
......
...@@ -2754,6 +2754,10 @@ public class TileProcessor { ...@@ -2754,6 +2754,10 @@ public class TileProcessor {
clt_parameters.stFloor, // double strength_floor, clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow, clt_parameters.stPow, // double strength_pow,
0.0,// NO BLUR double stBlurSigma) 0.0,// NO BLUR double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[0] = scan_prev.showDisparityHistogram(); dbg_hist[0] = scan_prev.showDisparityHistogram();
...@@ -2766,6 +2770,10 @@ public class TileProcessor { ...@@ -2766,6 +2770,10 @@ public class TileProcessor {
clt_parameters.stFloor, // double strength_floor, clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow, clt_parameters.stPow, // double strength_pow,
clt_parameters.stSigma, // with blur double stBlurSigma) clt_parameters.stSigma, // with blur double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[1] = scan_prev.showDisparityHistogram(); dbg_hist[1] = scan_prev.showDisparityHistogram();
...@@ -2948,7 +2956,7 @@ public class TileProcessor { ...@@ -2948,7 +2956,7 @@ public class TileProcessor {
boolean show_st = clt_parameters.stShow || (debugLevel > 1); boolean show_st = clt_parameters.stShow || (debugLevel > 1);
// recalculate supertiles (may be removed later) // recalculate supertiles (may be removed later)
// if (use_supertiles || show_st) { // if (use_supertiles || show_st) {
String [] dbg_st_titles = {"raw", "blurred"+clt_parameters.stSigma,"max-min-max"}; String [] dbg_st_titles = {"raw", "sampled", "blurred"+clt_parameters.stSigma,"max-min-max"};
double [][] dbg_hist = new double[dbg_st_titles.length][]; double [][] dbg_hist = new double[dbg_st_titles.length][];
if (show_st) { // otherwise only blured version is needed if (show_st) { // otherwise only blured version is needed
scan_prev.setSuperTiles( scan_prev.setSuperTiles(
...@@ -2960,8 +2968,27 @@ public class TileProcessor { ...@@ -2960,8 +2968,27 @@ public class TileProcessor {
clt_parameters.stFloor, // double strength_floor, clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow, clt_parameters.stPow, // double strength_pow,
0.0, // NO BLUR double stBlurSigma) 0.0, // NO BLUR double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[0] = scan_prev.showDisparityHistogram(); dbg_hist[0] = scan_prev.showDisparityHistogram();
scan_prev.setSuperTiles(
clt_parameters.stStepNear, // double step_disparity,
clt_parameters.stStepFar, // double step_near,
clt_parameters.stStepThreshold, // double step_threshold,
clt_parameters.stMinDisparity, // double min_disparity,
clt_parameters.stMaxDisparity, // double max_disparity,
clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow,
0.0, // NO BLUR double stBlurSigma)
clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[1] = scan_prev.showDisparityHistogram();
} }
// SuperTiles st = // SuperTiles st =
...@@ -2974,10 +3001,14 @@ public class TileProcessor { ...@@ -2974,10 +3001,14 @@ public class TileProcessor {
clt_parameters.stFloor, // double strength_floor, clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow, clt_parameters.stPow, // double strength_pow,
clt_parameters.stSigma, // with blur double stBlurSigma) clt_parameters.stSigma, // with blur double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
if (show_st) { // otherwise only blured version is needed if (show_st) { // otherwise only blured version is needed
dbg_hist[1] = scan_prev.showDisparityHistogram(); dbg_hist[2] = scan_prev.showDisparityHistogram();
dbg_hist[2] = scan_prev.showMaxMinMax(); dbg_hist[3] = scan_prev.showMaxMinMax();
} }
...@@ -2988,11 +3019,30 @@ public class TileProcessor { ...@@ -2988,11 +3019,30 @@ public class TileProcessor {
sdfa_instance.showArrays(dbg_hist, hist_width0, hist_height0, true, "disparity_supertiles_histograms",dbg_st_titles); sdfa_instance.showArrays(dbg_hist, hist_width0, hist_height0, true, "disparity_supertiles_histograms",dbg_st_titles);
} }
if (clt_parameters.stSmplMode){ // just temporary making it last
scan_prev.setSuperTiles(
clt_parameters.stStepNear, // double step_disparity,
clt_parameters.stStepFar, // double step_near,
clt_parameters.stStepThreshold, // double step_threshold,
clt_parameters.stMinDisparity, // double min_disparity,
clt_parameters.stMaxDisparity, // double max_disparity,
clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow,
0.0, // NO BLUR double stBlurSigma)
clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
}
SuperTiles st = scan_prev.getSuperTiles(); SuperTiles st = scan_prev.getSuperTiles();
// moved here // moved here
if (clt_parameters.dbg_migrate) { if (clt_parameters.dbg_migrate) {
st.processPlanes3( st.processPlanes4(
null, // final boolean [] selected, // or null null, // final boolean [] selected, // or null
0.3, // final double min_disp, 0.3, // final double min_disp,
clt_parameters.stMeasSel, // = 1 //Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel, // = 1 //Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
...@@ -3004,10 +3054,39 @@ public class TileProcessor { ...@@ -3004,10 +3054,39 @@ public class TileProcessor {
clt_parameters.plPreferDisparity, clt_parameters.plPreferDisparity,
geometryCorrection, geometryCorrection,
clt_parameters.correct_distortions, clt_parameters.correct_distortions,
clt_parameters.stSmplMode , // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide , // final int smplSide, // = 2; // Sample size (side of a square)
clt_parameters.stSmplNum , // final int smplNum, // = 3; // Number after removing worst
clt_parameters.stSmplRms , // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
clt_parameters.stSmallDiff, // = 0.4; // Consider merging initial planes if disparity difference below
clt_parameters.stHighMix, //stHighMix = 0.4; // Consider merging initial planes if jumps between ratio above
clt_parameters.vertical_xyz,
0, // -1, // debugLevel, // final int debugLevel) 0, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
} else { } else {
st.processPlanes3(
null, // final boolean [] selected, // or null
0.3, // final double min_disp,
clt_parameters.stMeasSel, // = 1 //Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
clt_parameters.plDispNorm, // = 2.0; // Normalize disparities to the average if above
clt_parameters.plMinPoints, // = 5; // Minimal number of points for plane detection
clt_parameters.plTargetEigen, // = 0.1; // Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below
clt_parameters.plFractOutliers, // = 0.3; // Maximal fraction of outliers to remove
clt_parameters.plMaxOutliers, // = 20; // Maximal number of outliers to remove\
clt_parameters.plPreferDisparity,
geometryCorrection,
clt_parameters.correct_distortions,
// false, // clt_parameters.dbg_migrate && clt_parameters.stSmplMode , // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
clt_parameters.stSmplMode , // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide , // final int smplSide, // = 2; // Sample size (side of a square)
clt_parameters.stSmplNum , // final int smplNum, // = 3; // Number after removing worst
clt_parameters.stSmplRms , // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
0, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
/*
st.processPlanes2( st.processPlanes2(
null, // final boolean [] selected, // or null null, // final boolean [] selected, // or null
0.3, // final double min_disp, 0.3, // final double min_disp,
...@@ -3023,6 +3102,7 @@ public class TileProcessor { ...@@ -3023,6 +3102,7 @@ public class TileProcessor {
0, // -1, // debugLevel, // final int debugLevel) 0, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
*/
} }
showDoubleFloatArrays sdfa_instance = null; showDoubleFloatArrays sdfa_instance = null;
...@@ -3042,22 +3122,21 @@ public class TileProcessor { ...@@ -3042,22 +3122,21 @@ public class TileProcessor {
0, // final int debugLevel) 0, // final int debugLevel)
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
if (clt_parameters.plSplitApply) {
while (true) { while (true) {
int num_added = 0; int num_added = 0;
if (clt_parameters.plFillSquares){
num_added += st.fillSquares(); num_added += st.fillSquares();
}
if (debugLevel > -1) { if (debugLevel > -1) {
System.out.println("after fillSquares() added "+num_added); System.out.println("after fillSquares() added "+num_added);
} }
if (clt_parameters.plCutCorners){
num_added += st.cutCorners(); num_added += st.cutCorners();
}
if (debugLevel > -1) { if (debugLevel > -1) {
System.out.println("after plCutCorners() added (cumulative) "+num_added); System.out.println("after plCutCorners() added (cumulative) "+num_added);
} }
if (num_added == 0) break; if (num_added == 0) break;
} }
}
TilePlanes.PlaneData[][][] split_planes = // use original (measured planes. See if smoothed are needed here) TilePlanes.PlaneData[][][] split_planes = // use original (measured planes. See if smoothed are needed here)
st.breakPlanesToPairs( st.breakPlanesToPairs(
...@@ -3097,6 +3176,10 @@ public class TileProcessor { ...@@ -3097,6 +3176,10 @@ public class TileProcessor {
clt_parameters.plMaxOutliers, // final int maxOutliers, // = 20; // Maximal number of outliers to remove clt_parameters.plMaxOutliers, // final int maxOutliers, // = 20; // Maximal number of outliers to remove
clt_parameters.stFloor, // final double strength_floor, clt_parameters.stFloor, // final double strength_floor,
clt_parameters.stPow, // final double strength_pow, clt_parameters.stPow, // final double strength_pow,
clt_parameters.dbg_migrate && clt_parameters.stSmplMode , // final boolean smplMode, // = true; // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide , // final int smplSide, // = 2; // Sample size (side of a square)
clt_parameters.stSmplNum , // final int smplNum, // = 3; // Number after removing worst
clt_parameters.stSmplRms , // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
1, // final int debugLevel) 1, // final int debugLevel)
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
...@@ -3118,6 +3201,8 @@ public class TileProcessor { ...@@ -3118,6 +3201,8 @@ public class TileProcessor {
0, // final int debugLevel) 0, // final int debugLevel)
clt_parameters.tileX, clt_parameters.tileX,
clt_parameters.tileY); clt_parameters.tileY);
}
while (true) { while (true) {
int num_added = 0; int num_added = 0;
if (clt_parameters.plFillSquares){ if (clt_parameters.plFillSquares){
...@@ -3134,7 +3219,6 @@ public class TileProcessor { ...@@ -3134,7 +3219,6 @@ public class TileProcessor {
} }
if (num_added == 0) break; if (num_added == 0) break;
} }
}
TilePlanes.PlaneData [][] planes_mod = null; TilePlanes.PlaneData [][] planes_mod = null;
...@@ -3233,7 +3317,7 @@ public class TileProcessor { ...@@ -3233,7 +3317,7 @@ public class TileProcessor {
plane_data[indx++] = plane_data_nan[i]; plane_data[indx++] = plane_data_nan[i];
} }
plane_data[indx++] = split_lines; plane_data[indx++] = split_lines;
plane_data[indx] = plane_data[indx-2].clone(); plane_data[indx] = plane_data[indx-2].clone(); // java.lang.ArrayIndexOutOfBoundsException: -1
for (int i = 0; i < plane_data[indx].length;i++){ for (int i = 0; i < plane_data[indx].length;i++){
if (Double.isNaN(plane_data[indx][i])) plane_data[indx][i] = 0.0; if (Double.isNaN(plane_data[indx][i])) plane_data[indx][i] = 0.0;
if (plane_data[indx-1][i] > 0) plane_data[indx][i] = Double.NaN; if (plane_data[indx-1][i] > 0) plane_data[indx][i] = Double.NaN;
...@@ -3525,6 +3609,10 @@ public class TileProcessor { ...@@ -3525,6 +3609,10 @@ public class TileProcessor {
clt_parameters.stFloor, // double strength_floor, clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow, clt_parameters.stPow, // double strength_pow,
0.0, // NO BLUR double stBlurSigma) 0.0, // NO BLUR double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[0] = scan_prev.showDisparityHistogram(); dbg_hist[0] = scan_prev.showDisparityHistogram();
...@@ -3537,6 +3625,10 @@ public class TileProcessor { ...@@ -3537,6 +3625,10 @@ public class TileProcessor {
clt_parameters.stFloor, // double strength_floor, clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow, clt_parameters.stPow, // double strength_pow,
clt_parameters.stSigma, // with blur double stBlurSigma) clt_parameters.stSigma, // with blur double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[1] = scan_prev.showDisparityHistogram(); dbg_hist[1] = scan_prev.showDisparityHistogram();
...@@ -3605,13 +3697,15 @@ public class TileProcessor { ...@@ -3605,13 +3697,15 @@ public class TileProcessor {
showDoubleFloatArrays sdfa_instance = null; showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging? if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
boolean [] these_tiles = scan_prev.getSelected(); boolean [] these_tiles = scan_prev.getSelected();
double [] this_disparity = scan_prev.getDisparity(); // returns a copy of the FPGA-generated disparity combined with the target one // double [] this_disparity = scan_prev.getDisparity(); // returns a copy of the FPGA-generated disparity combined with the target one
double [] this_strength = scan_prev.getStrength(); // cloned, can be modified/ read back // double [] this_strength = scan_prev.getStrength(); // cloned, can be modified/ read back
double [] this_disparity = scan_prev.getDisparity().clone(); // returns a copy of the FPGA-generated disparity combined with the target one
double [] this_strength = scan_prev.getStrength().clone(); // cloned, can be modified/ read back
scan_prev.fixNaNDisparity( scan_prev.fixNaNDisparity(
null, // border, // boolean [] select, // which tiles to correct (null - all) null, // border, // boolean [] select, // which tiles to correct (null - all)
scan_prev.getDisparity(), // double [] disparity, this_disparity, // scan_prev.getDisparity(), // double [] disparity,
scan_prev.getStrength()); // double [] strength) this_strength); // scan_prev.getStrength()); // double [] strength)
/// dbg_orig_disparity = this_disparity.clone(); /// dbg_orig_disparity = this_disparity.clone();
...@@ -4332,6 +4426,10 @@ public class TileProcessor { ...@@ -4332,6 +4426,10 @@ public class TileProcessor {
clt_parameters.stFloor, // double strength_floor, clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow, clt_parameters.stPow, // double strength_pow,
0.0,// NO BLUR double stBlurSigma) 0.0,// NO BLUR double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[0] = scan_prev.showDisparityHistogram(); dbg_hist[0] = scan_prev.showDisparityHistogram();
...@@ -4344,6 +4442,10 @@ public class TileProcessor { ...@@ -4344,6 +4442,10 @@ public class TileProcessor {
clt_parameters.stFloor, // double strength_floor, clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow, clt_parameters.stPow, // double strength_pow,
clt_parameters.stSigma, // with blur double stBlurSigma) clt_parameters.stSigma, // with blur double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[1] = scan_prev.showDisparityHistogram(); dbg_hist[1] = scan_prev.showDisparityHistogram();
......
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