Commit 70ccd5f4 authored by Andrey Filippov's avatar Andrey Filippov

Tested inter-camera (double quad) bundle adjustment

parent 84e61b79
...@@ -36,7 +36,9 @@ public class BiQuadParameters { ...@@ -36,7 +36,9 @@ public class BiQuadParameters {
public double inf_min_strength_rig = 0.25; public double inf_min_strength_rig = 0.25;
public double inf_max_disp_main = 0.15; public double inf_max_disp_main = 0.15;
public double inf_max_disp_aux = 0.15; public double inf_max_disp_aux = 0.15;
public double inf_max_disp_rig = 0.5; // maybe even higher (2.0) to lock to initially high mismatch public double inf_max_disp_rig = 0.2; // maybe even higher (2.0) to lock to initially high mismatch
public double inf_neg_tolerance = 2.5; // increase negative disparity for infinity tolerance
public double inf_weight = 0.7; // weight of infinity measurements of all measurements
public double first_max_disp_main = 0.5; // before refinement public double first_max_disp_main = 0.5; // before refinement
public double first_max_disp_aux = 0.5; public double first_max_disp_aux = 0.5;
...@@ -86,6 +88,10 @@ public class BiQuadParameters { ...@@ -86,6 +88,10 @@ public class BiQuadParameters {
"Do not use tile for infinity adjustment if absolute value of the main camera disparity is too high"); "Do not use tile for infinity adjustment if absolute value of the main camera disparity is too high");
gd.addNumericField("Maximal absolute value of inter-camera disparity to use for infinity rig adjustment", this.inf_max_disp_rig, 3,6,"pix", gd.addNumericField("Maximal absolute value of inter-camera disparity to use for infinity rig adjustment", this.inf_max_disp_rig, 3,6,"pix",
"Do not use tile for infinity adjustment if absolute value of the inter-camera disparity is too high"); "Do not use tile for infinity adjustment if absolute value of the inter-camera disparity is too high");
gd.addNumericField("Loosen negative disparity tolerance for infinity", this.inf_neg_tolerance, 3,6,"",
"Allow farther negative than positive disparity tiles for infinity (only for main/rig pair)");
gd.addNumericField("Weight of infinity measurements in all measurements", this.inf_weight, 3,6,"",
"Set importance of infinity matching among all measurements");
gd.addNumericField("Maximal absolute value of main camera disparity difference near objects, before refinement", this.first_max_disp_main, 3,6,"pix", gd.addNumericField("Maximal absolute value of main camera disparity difference near objects, before refinement", this.first_max_disp_main, 3,6,"pix",
...@@ -143,7 +149,8 @@ public class BiQuadParameters { ...@@ -143,7 +149,8 @@ public class BiQuadParameters {
this.inf_max_disp_main= gd.getNextNumber(); this.inf_max_disp_main= gd.getNextNumber();
this.inf_max_disp_aux= gd.getNextNumber(); this.inf_max_disp_aux= gd.getNextNumber();
this.inf_max_disp_rig= gd.getNextNumber(); this.inf_max_disp_rig= gd.getNextNumber();
this.inf_neg_tolerance= gd.getNextNumber();
this.inf_weight= gd.getNextNumber();
this.first_max_disp_main= gd.getNextNumber(); this.first_max_disp_main= gd.getNextNumber();
this.first_max_disp_aux= gd.getNextNumber(); this.first_max_disp_aux= gd.getNextNumber();
this.first_max_disp_rig= gd.getNextNumber(); this.first_max_disp_rig= gd.getNextNumber();
...@@ -181,6 +188,9 @@ public class BiQuadParameters { ...@@ -181,6 +188,9 @@ public class BiQuadParameters {
properties.setProperty(prefix+"inf_max_disp_main", this.inf_max_disp_main+""); properties.setProperty(prefix+"inf_max_disp_main", this.inf_max_disp_main+"");
properties.setProperty(prefix+"inf_max_disp_aux", this.inf_max_disp_aux+""); properties.setProperty(prefix+"inf_max_disp_aux", this.inf_max_disp_aux+"");
properties.setProperty(prefix+"inf_max_disp_rig", this.inf_max_disp_rig+""); properties.setProperty(prefix+"inf_max_disp_rig", this.inf_max_disp_rig+"");
properties.setProperty(prefix+"inf_neg_tolerance", this.inf_neg_tolerance+"");
properties.setProperty(prefix+"inf_weight", this.inf_weight+"");
properties.setProperty(prefix+"first_max_disp_main", this.first_max_disp_main+""); properties.setProperty(prefix+"first_max_disp_main", this.first_max_disp_main+"");
properties.setProperty(prefix+"first_max_disp_aux", this.first_max_disp_aux+""); properties.setProperty(prefix+"first_max_disp_aux", this.first_max_disp_aux+"");
...@@ -219,6 +229,8 @@ public class BiQuadParameters { ...@@ -219,6 +229,8 @@ public class BiQuadParameters {
if (properties.getProperty(prefix+"inf_max_disp_main")!=null) this.inf_max_disp_main=Double.parseDouble(properties.getProperty(prefix+"inf_max_disp_main")); if (properties.getProperty(prefix+"inf_max_disp_main")!=null) this.inf_max_disp_main=Double.parseDouble(properties.getProperty(prefix+"inf_max_disp_main"));
if (properties.getProperty(prefix+"inf_max_disp_aux")!=null) this.inf_max_disp_aux=Double.parseDouble(properties.getProperty(prefix+"inf_max_disp_aux")); if (properties.getProperty(prefix+"inf_max_disp_aux")!=null) this.inf_max_disp_aux=Double.parseDouble(properties.getProperty(prefix+"inf_max_disp_aux"));
if (properties.getProperty(prefix+"inf_max_disp_rig")!=null) this.inf_max_disp_rig=Double.parseDouble(properties.getProperty(prefix+"inf_max_disp_rig")); if (properties.getProperty(prefix+"inf_max_disp_rig")!=null) this.inf_max_disp_rig=Double.parseDouble(properties.getProperty(prefix+"inf_max_disp_rig"));
if (properties.getProperty(prefix+"inf_neg_tolerance")!=null) this.inf_neg_tolerance=Double.parseDouble(properties.getProperty(prefix+"inf_neg_tolerance"));
if (properties.getProperty(prefix+"inf_weight")!=null) this.inf_weight=Double.parseDouble(properties.getProperty(prefix+"inf_weight"));
if (properties.getProperty(prefix+"first_max_disp_main")!=null) this.first_max_disp_main=Double.parseDouble(properties.getProperty(prefix+"first_max_disp_main")); if (properties.getProperty(prefix+"first_max_disp_main")!=null) this.first_max_disp_main=Double.parseDouble(properties.getProperty(prefix+"first_max_disp_main"));
if (properties.getProperty(prefix+"first_max_disp_aux")!=null) this.first_max_disp_aux=Double.parseDouble(properties.getProperty(prefix+"first_max_disp_aux")); if (properties.getProperty(prefix+"first_max_disp_aux")!=null) this.first_max_disp_aux=Double.parseDouble(properties.getProperty(prefix+"first_max_disp_aux"));
...@@ -257,6 +269,8 @@ public class BiQuadParameters { ...@@ -257,6 +269,8 @@ public class BiQuadParameters {
bqp.inf_max_disp_main = this.inf_max_disp_main; bqp.inf_max_disp_main = this.inf_max_disp_main;
bqp.inf_max_disp_aux = this.inf_max_disp_aux; bqp.inf_max_disp_aux = this.inf_max_disp_aux;
bqp.inf_max_disp_rig = this.inf_max_disp_rig; bqp.inf_max_disp_rig = this.inf_max_disp_rig;
bqp.inf_neg_tolerance = this.inf_neg_tolerance;
bqp.inf_weight = this.inf_weight;
bqp.first_max_disp_main= this.first_max_disp_main; bqp.first_max_disp_main= this.first_max_disp_main;
bqp.first_max_disp_aux= this.first_max_disp_aux; bqp.first_max_disp_aux= this.first_max_disp_aux;
...@@ -279,7 +293,6 @@ public class BiQuadParameters { ...@@ -279,7 +293,6 @@ public class BiQuadParameters {
bqp.rig_adjust_distance= this.rig_adjust_distance; bqp.rig_adjust_distance= this.rig_adjust_distance;
bqp.rig_adjust_forward= this.rig_adjust_forward; bqp.rig_adjust_forward= this.rig_adjust_forward;
bqp.rig_correction_scale= this.rig_correction_scale; bqp.rig_correction_scale= this.rig_correction_scale;
return bqp; return bqp;
......
...@@ -1156,7 +1156,7 @@ private Panel panel1, ...@@ -1156,7 +1156,7 @@ private Panel panel1,
String path= loadProperties(null,CORRECTION_PARAMETERS.resultsDirectory,true, PROPERTIES); String path= loadProperties(null,CORRECTION_PARAMETERS.resultsDirectory,true, PROPERTIES);
if (path != null) { if (path != null) {
getAllProperties(PROPERTIES); getAllProperties(PROPERTIES);
if (DEBUG_LEVEL > -1) System.out.println("Configuration parameters are restored from "+path); if (DEBUG_LEVEL > -3) System.out.println("Configuration parameters are restored from "+path);
} else { } else {
if (DEBUG_LEVEL > -10) System.out.println("Failed to restore configuration parameters"); if (DEBUG_LEVEL > -10) System.out.println("Failed to restore configuration parameters");
} }
...@@ -5982,7 +5982,7 @@ private Panel panel1, ...@@ -5982,7 +5982,7 @@ private Panel panel1,
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
if (DEBUG_LEVEL>0) System.out.println("Configuration parameters are saved to "+path); if (DEBUG_LEVEL> -3) System.out.println("Configuration parameters are saved to "+path);
} }
......
...@@ -30,6 +30,9 @@ import ij.IJ; ...@@ -30,6 +30,9 @@ import ij.IJ;
*/ */
public class GeometryCorrection { public class GeometryCorrection {
static final double FOCAL_LENGTH = 4.5; // nominal focal length - used as default and to convert editable parameters to pixels
static final double DISTORTION_RADIUS = 2.8512; // nominal distortion radius - half width of the sensor
static final double PIXEL_SIZE = 2.2; //um
static final String[] RIG_PAR_NAMES = {"azimuth", "tilt", "roll", "zoom", "angle", "baseline"}; static final String[] RIG_PAR_NAMES = {"azimuth", "tilt", "roll", "zoom", "angle", "baseline"};
public static String RIG_PREFIX = "rig-"; public static String RIG_PREFIX = "rig-";
static double SCENE_UNITS_SCALE = 0.001; static double SCENE_UNITS_SCALE = 0.001;
...@@ -39,9 +42,9 @@ public class GeometryCorrection { ...@@ -39,9 +42,9 @@ public class GeometryCorrection {
public int debugLevel = 0; public int debugLevel = 0;
public int pixelCorrectionWidth=2592; // virtual camera center is at (pixelCorrectionWidth/2, pixelCorrectionHeight/2) public int pixelCorrectionWidth=2592; // virtual camera center is at (pixelCorrectionWidth/2, pixelCorrectionHeight/2)
public int pixelCorrectionHeight=1936; public int pixelCorrectionHeight=1936;
public double focalLength=4.5; public double focalLength=FOCAL_LENGTH;
public double pixelSize= 2.2; //um public double pixelSize= PIXEL_SIZE; //um
public double distortionRadius= 2.8512; // mm - half width of the sensor public double distortionRadius= DISTORTION_RADIUS; // mm - half width of the sensor
public double distortionA8=0.0; //r^8 (normalized to focal length or to sensor half width?) public double distortionA8=0.0; //r^8 (normalized to focal length or to sensor half width?)
public double distortionA7=0.0; //r^7 (normalized to focal length or to sensor half width?) public double distortionA7=0.0; //r^7 (normalized to focal length or to sensor half width?)
public double distortionA6=0.0; //r^6 (normalized to focal length or to sensor half width?) public double distortionA6=0.0; //r^6 (normalized to focal length or to sensor half width?)
...@@ -127,21 +130,22 @@ public class GeometryCorrection { ...@@ -127,21 +130,22 @@ public class GeometryCorrection {
return rigOffset.clone(); return rigOffset.clone();
} }
public void rigOffestSetPar(int index, double value) { public void rigOffestSetParNorm(int index, double value) {
rigOffset.setPar(index, value); rigOffset.setParNorm(index, value);
} }
public void rigOffestSetPar(RigOffset ro, int index, double value) { public void rigOffestSetParNorm(RigOffset ro, int index, double value) {
ro. setPar(index, value); ro. setParNorm(index, value);
} }
public double rigOffestGetPar(int index) { public double rigOffestGetParNorm(int index) {
return rigOffset.getPar(index); return rigOffset.getParNorm(index);
} }
public double rigOffestGetPar(RigOffset ro, int index) { public double rigOffestGetParNorm(RigOffset ro, int index) {
return ro.getPar(index); return ro.getParNorm(index);
} }
public double [] getRigCorrection( public double [] getRigCorrection(
double infinity_importance, // of all measurements
boolean adjust_orientation, boolean adjust_orientation,
boolean adjust_zoom, boolean adjust_zoom,
boolean adjust_angle, boolean adjust_angle,
...@@ -157,6 +161,7 @@ public class GeometryCorrection { ...@@ -157,6 +161,7 @@ public class GeometryCorrection {
int debugLevel) { int debugLevel) {
if (rigOffset == null) return null; if (rigOffset == null) return null;
return rigOffset.getRigCorrection( return rigOffset.getRigCorrection(
infinity_importance, // of all measurements
adjust_orientation, // boolean adjust_orientation, adjust_orientation, // boolean adjust_orientation,
adjust_zoom, // boolean adjust_zoom, adjust_zoom, // boolean adjust_zoom,
adjust_angle, // boolean adjust_angle, adjust_angle, // boolean adjust_angle,
...@@ -230,7 +235,8 @@ public class GeometryCorrection { ...@@ -230,7 +235,8 @@ public class GeometryCorrection {
static final double ROT_AZ_SGN = -1.0; // sign of first sin for azimuth rotation static final double ROT_AZ_SGN = -1.0; // sign of first sin for azimuth rotation
static final double ROT_TL_SGN = 1.0; // sign of first sin for tilt rotation static final double ROT_TL_SGN = 1.0; // sign of first sin for tilt rotation
static final double ROT_RL_SGN = 1.0; // sign of first sin for roll rotation static final double ROT_RL_SGN = 1.0; // sign of first sin for roll rotation
public double baseline = 1256.0; // mm, distance between camera centers static final double BASELINE = 1256.0; // default baseline value
public double baseline = BASELINE; // mm, distance between camera centers
public double aux_angle = 0.0; // radians, 0 - aux camera to the right of the main, pi/2 - up public double aux_angle = 0.0; // radians, 0 - aux camera to the right of the main, pi/2 - up
// consider aux_z small enough for now, will need for SfM // consider aux_z small enough for now, will need for SfM
public double aux_z = 0.0; // mm auxiliary camera distance from the plane of the main one (positive towards the scene) public double aux_z = 0.0; // mm auxiliary camera distance from the plane of the main one (positive towards the scene)
...@@ -246,9 +252,19 @@ public class GeometryCorrection { ...@@ -246,9 +252,19 @@ public class GeometryCorrection {
double [] xy_vector = null; double [] xy_vector = null;
double [] d_vector = null; double [] d_vector = null;
int [] tile_vector = null; // just for debugging int [] tile_vector = null; // just for debugging
double [] par_scales = null; // scale vector components to have similar derivatives values
int [] full_par_index;
public RigOffset () { public RigOffset () {
System.out.println("created RigOffset"); System.out.println("created RigOffset");
par_scales = new double [VECTOR_LENGTH];
par_scales[AUX_AZIMUTH_INDEX] = 1000.0*FOCAL_LENGTH/PIXEL_SIZE;
par_scales[AUX_TILT_INDEX] = 1000.0*FOCAL_LENGTH/PIXEL_SIZE;
par_scales[AUX_ROLL_INDEX] = 1000.0*DISTORTION_RADIUS/PIXEL_SIZE;
par_scales[AUX_ZOOM_INDEX] = 1000.0*DISTORTION_RADIUS/PIXEL_SIZE;
par_scales[AUX_ANGLE_INDEX] = 1.0; // 1000.0*BASELINE/pixelSize;
par_scales[AUX_BASELINE_INDEX] = 1.0/DISTORTION_RADIUS; // pixels per disparity pixel
} }
@Override @Override
...@@ -261,10 +277,13 @@ public class GeometryCorrection { ...@@ -261,10 +277,13 @@ public class GeometryCorrection {
ro.aux_tilt = this.aux_tilt; ro.aux_tilt = this.aux_tilt;
ro.aux_roll = this.aux_roll; ro.aux_roll = this.aux_roll;
ro.aux_zoom = this.aux_zoom; ro.aux_zoom = this.aux_zoom;
ro.full_par_index = this.full_par_index.clone();
ro.par_scales = this.par_scales.clone();
return ro; return ro;
} }
public void setPar(int index, double value) { public void setParNorm(int index, double value) {
value /= par_scales[index];
switch (index) { switch (index) {
case AUX_AZIMUTH_INDEX: aux_azimuth = value; break; case AUX_AZIMUTH_INDEX: aux_azimuth = value; break;
case AUX_TILT_INDEX: aux_tilt = value; break; case AUX_TILT_INDEX: aux_tilt = value; break;
...@@ -274,14 +293,14 @@ public class GeometryCorrection { ...@@ -274,14 +293,14 @@ public class GeometryCorrection {
case AUX_BASELINE_INDEX: baseline = value; break; case AUX_BASELINE_INDEX: baseline = value; break;
} }
} }
public double getPar(int index) { public double getParNorm(int index) {
switch (index) { switch (index) {
case AUX_AZIMUTH_INDEX: return aux_azimuth; case AUX_AZIMUTH_INDEX: return aux_azimuth * par_scales[index];
case AUX_TILT_INDEX: return aux_tilt; case AUX_TILT_INDEX: return aux_tilt * par_scales[index];
case AUX_ROLL_INDEX: return aux_roll; case AUX_ROLL_INDEX: return aux_roll * par_scales[index];
case AUX_ZOOM_INDEX: return aux_zoom; case AUX_ZOOM_INDEX: return aux_zoom * par_scales[index];
case AUX_ANGLE_INDEX: return aux_angle; case AUX_ANGLE_INDEX: return aux_angle * par_scales[index];
case AUX_BASELINE_INDEX: return baseline; case AUX_BASELINE_INDEX: return baseline * par_scales[index];
} }
return Double.NaN; return Double.NaN;
} }
...@@ -307,35 +326,41 @@ public class GeometryCorrection { ...@@ -307,35 +326,41 @@ public class GeometryCorrection {
int num_pars = 0; int num_pars = 0;
for (int i = 0; i < par_select.length; i++) if (par_select[i]) num_pars++; for (int i = 0; i < par_select.length; i++) if (par_select[i]) num_pars++;
vector = new double[num_pars]; vector = new double[num_pars];
full_par_index = new int [num_pars];
int par_index = 0; int par_index = 0;
for (int i = 0; i < par_select.length; i++) if (par_select[i]) { for (int i = 0; i < par_select.length; i++) if (par_select[i]) {
switch(i) { switch(i) {
case AUX_AZIMUTH_INDEX: vector[par_index] = aux_azimuth; break; case AUX_AZIMUTH_INDEX: vector[par_index] = aux_azimuth * par_scales[i]; break;
case AUX_TILT_INDEX: vector[par_index] = aux_tilt; break; case AUX_TILT_INDEX: vector[par_index] = aux_tilt * par_scales[i]; break;
case AUX_ROLL_INDEX: vector[par_index] = aux_roll; break; case AUX_ROLL_INDEX: vector[par_index] = aux_roll * par_scales[i]; break;
case AUX_ZOOM_INDEX: vector[par_index] = aux_zoom; break; case AUX_ZOOM_INDEX: vector[par_index] = aux_zoom * par_scales[i]; break;
case AUX_ANGLE_INDEX: vector[par_index] = aux_angle; break; case AUX_ANGLE_INDEX: vector[par_index] = aux_angle * par_scales[i]; break;
case AUX_BASELINE_INDEX: vector[par_index] = baseline; break; case AUX_BASELINE_INDEX: vector[par_index] = baseline * par_scales[i]; break;
} }
full_par_index[par_index] = i;
par_index++; par_index++;
} }
//full_par_index
} }
public void commitVector(double [] v) { public void commitVector(double [] v) {
vector = v; vector = v;
int par_index = 0; int par_index = 0;
for (int i = 0; i < par_select.length; i++) if (par_select[i]) { for (int i = 0; i < par_select.length; i++) if (par_select[i]) {
switch(i) { switch(i) {
case AUX_AZIMUTH_INDEX: aux_azimuth = vector[par_index]; break; case AUX_AZIMUTH_INDEX: aux_azimuth = vector[par_index]/par_scales[i]; break;
case AUX_TILT_INDEX: aux_tilt = vector[par_index]; break; case AUX_TILT_INDEX: aux_tilt = vector[par_index]/par_scales[i]; break;
case AUX_ROLL_INDEX: aux_roll = vector[par_index]; break; case AUX_ROLL_INDEX: aux_roll = vector[par_index]/par_scales[i]; break;
case AUX_ZOOM_INDEX: aux_zoom = vector[par_index]; break; case AUX_ZOOM_INDEX: aux_zoom = vector[par_index]/par_scales[i]; break;
case AUX_ANGLE_INDEX: aux_angle = vector[par_index]; break; case AUX_ANGLE_INDEX: aux_angle = vector[par_index]/par_scales[i]; break;
case AUX_BASELINE_INDEX: baseline = vector[par_index]; break; case AUX_BASELINE_INDEX: baseline = vector[par_index]/par_scales[i]; break;
} }
par_index++; par_index++;
} }
recalcRXY();
} }
public double setupYW( public double setupYW(
double infinity_importance, // of all measurements
ArrayList<Integer> tile_list, ArrayList<Integer> tile_list,
QuadCLT qc, QuadCLT qc,
double [] strength, double [] strength,
...@@ -347,8 +372,9 @@ public class GeometryCorrection { ...@@ -347,8 +372,9 @@ public class GeometryCorrection {
xy_vector = new double[2*tile_list.size()]; xy_vector = new double[2*tile_list.size()];
d_vector = new double[tile_list.size()]; d_vector = new double[tile_list.size()];
tile_vector= new int[tile_list.size()]; tile_vector= new int[tile_list.size()];
double sum_w = 0.0; boolean [] is_inf = new boolean[tile_list.size()];
double sum2 = 0.0; double sumw_inf = 0.0,sumw_near=0.0;
double sum2_inf = 0.0,sum2_near = 0.0;
int tilesX = qc.tp.getTilesX(); int tilesX = qc.tp.getTilesX();
double tileSize = qc.tp.getTileSize(); double tileSize = qc.tp.getTileSize();
...@@ -360,22 +386,44 @@ public class GeometryCorrection { ...@@ -360,22 +386,44 @@ public class GeometryCorrection {
if (target_disparity[nTile] == 0.0) { // only for infinity tiles if (target_disparity[nTile] == 0.0) { // only for infinity tiles
y_vector[2*i + 0] = diff_x[nTile]; y_vector[2*i + 0] = diff_x[nTile];
w_vector[2*i + 0] = strength[nTile]; w_vector[2*i + 0] = strength[nTile];
sum_w += strength[nTile];
sum2 += strength[nTile]*diff_x[nTile]*diff_x[nTile];
}
y_vector[2*i + 1] = diff_y[nTile]; y_vector[2*i + 1] = diff_y[nTile];
w_vector[2*i + 1] = strength[nTile]; w_vector[2*i + 1] = strength[nTile];
sum_w += strength[nTile]; sumw_inf += 2*strength[nTile];
sum2 += strength[nTile]*diff_y[nTile]*diff_y[nTile]; sum2_inf += strength[nTile]*(diff_x[nTile]*diff_x[nTile]+diff_y[nTile]*diff_y[nTile]);
is_inf[i] = true;
} else {
y_vector[2*i + 1] = diff_y[nTile];
w_vector[2*i + 1] = strength[nTile];
sumw_near += strength[nTile];
sum2_near += strength[nTile]*diff_y[nTile]*diff_y[nTile];
}
xy_vector[2*i + 0] = (tileX + 0.5) * tileSize; xy_vector[2*i + 0] = (tileX + 0.5) * tileSize;
xy_vector[2*i + 1] = (tileY + 0.5) * tileSize; xy_vector[2*i + 1] = (tileY + 0.5) * tileSize;
d_vector[i] = target_disparity[nTile]; d_vector[i] = target_disparity[nTile];
tile_vector[i] = nTile; tile_vector[i] = nTile;
} }
if (sum_w > 0) { if (infinity_importance > 1.0) infinity_importance = 1.0;
double k = 1.0/sum_w; else if (infinity_importance < 0.0) infinity_importance =0.0;
sum2 *= k; double k_inf = 0.0, k_near = 0.0;
for (int i = 0; i < w_vector.length; i++) w_vector[i] *= k; if ((sumw_inf > 0.0) && (sumw_near > 0.0)){
k_inf = infinity_importance/sumw_inf;
k_near = (1.0 - infinity_importance)/sumw_near;
} else if (sumw_inf > 0.0){
infinity_importance = 1.0;
k_inf = infinity_importance/sumw_inf;
} else if (sumw_near > 0.0) {
infinity_importance = 0.0;
k_near = (1.0 - infinity_importance)/sumw_near;
}
double sum2 = k_inf*sum2_inf+k_near*sum2_near;
for (int i = 0; i < is_inf.length; i++) {
if (is_inf[i]) {
w_vector[2 * i + 0] *= k_inf;
w_vector[2 * i + 1] *= k_inf;
} else {
w_vector[2 * i + 1] *= k_near;
}
} }
return Math.sqrt(sum2); // RMS return Math.sqrt(sum2); // RMS
} }
...@@ -402,11 +450,10 @@ public class GeometryCorrection { ...@@ -402,11 +450,10 @@ public class GeometryCorrection {
d_vector[i >> 1]); // double disparity); d_vector[i >> 1]); // double disparity);
int npar = 0; int npar = 0;
for (int j = 0; j < VECTOR_LENGTH; j++) if (par_select[j]) { for (int j = 0; j < VECTOR_LENGTH; j++) if (par_select[j]) {
jt[npar][i + 0] = pXYderiv[0][j]; jt[npar][i + 0] = pXYderiv[0][j]/par_scales[full_par_index[npar]];
jt[npar][i + 1] = pXYderiv[1][j]; jt[npar][i + 1] = pXYderiv[1][j]/par_scales[full_par_index[npar]];
npar++; npar++;
} }
} }
return jt; return jt;
} }
...@@ -424,10 +471,10 @@ public class GeometryCorrection { ...@@ -424,10 +471,10 @@ public class GeometryCorrection {
double [][][] aux_offset_derivs_m = new double[RigOffset.VECTOR_LENGTH][][]; double [][][] aux_offset_derivs_m = new double[RigOffset.VECTOR_LENGTH][][];
for (int npar = 0; npar < RigOffset.VECTOR_LENGTH; npar++ ) { for (int npar = 0; npar < RigOffset.VECTOR_LENGTH; npar++ ) {
RigOffset ro = rigOffsetClone(); RigOffset ro = rigOffsetClone();
rigOffestSetPar(ro, npar, rigOffestGetPar(ro, npar) +delta); rigOffestSetParNorm(ro, npar, rigOffestGetParNorm(ro, npar) +delta);
aux_offset_derivs_p[npar] = ro.getAuxOffsetAndDerivatives(gc_main); aux_offset_derivs_p[npar] = ro.getAuxOffsetAndDerivatives(gc_main);
aux_rot_p[npar]= ro.getRotMatrix(); aux_rot_p[npar]= ro.getRotMatrix();
rigOffestSetPar(ro, npar, rigOffestGetPar(ro, npar) - 2 * delta); rigOffestSetParNorm(ro, npar, rigOffestGetParNorm(ro, npar) - 2 * delta);
aux_offset_derivs_m[npar] = ro.getAuxOffsetAndDerivatives(gc_main); aux_offset_derivs_m[npar] = ro.getAuxOffsetAndDerivatives(gc_main);
aux_rot_m[npar]= ro.getRotMatrix(); aux_rot_m[npar]= ro.getRotMatrix();
} }
...@@ -446,9 +493,9 @@ public class GeometryCorrection { ...@@ -446,9 +493,9 @@ public class GeometryCorrection {
d_vector[i >> 1]); // double disparity); d_vector[i >> 1]); // double disparity);
double [] xy_m = getRigAuxCoordinatesAndDerivatives( double [] xy_m = getRigAuxCoordinatesAndDerivatives(
gc_main, // GeometryCorrection gc_main, gc_main, // GeometryCorrection gc_main,
aux_rot_p[npar], // Matrix aux_rot, aux_rot_m[npar], // Matrix aux_rot,
null, // Matrix [] aux_rot_derivs, null, // Matrix [] aux_rot_derivs,
aux_offset_derivs_p[npar], // double [][] aux_offset_derivs, aux_offset_derivs_m[npar], // double [][] aux_offset_derivs,
null, // double [][] pXYderiv, // if not null, should be double[6][] null, // double [][] pXYderiv, // if not null, should be double[6][]
xy_vector[i + 0], // double px, xy_vector[i + 0], // double px,
xy_vector[i + 1], // double py, xy_vector[i + 1], // double py,
...@@ -498,6 +545,7 @@ public class GeometryCorrection { ...@@ -498,6 +545,7 @@ public class GeometryCorrection {
} }
public double [] getRigCorrection( public double [] getRigCorrection(
double infinity_importance, // of all measurements
boolean adjust_orientation, boolean adjust_orientation,
boolean adjust_zoom, boolean adjust_zoom,
boolean adjust_angle, boolean adjust_angle,
...@@ -518,7 +566,9 @@ public class GeometryCorrection { ...@@ -518,7 +566,9 @@ public class GeometryCorrection {
adjust_distance, adjust_distance,
adjust_forward); // not used adjust_forward); // not used
double rms = setupYW(tile_list, double rms = setupYW(
infinity_importance, // of all measurements
tile_list,
qc_main, qc_main,
strength, strength,
diff_x, // used only with target_disparity == 0 diff_x, // used only with target_disparity == 0
...@@ -530,7 +580,7 @@ public class GeometryCorrection { ...@@ -530,7 +580,7 @@ public class GeometryCorrection {
double [][] jt = getJacobianTransposed( // npe double [][] jt = getJacobianTransposed( // npe
qc_main.geometryCorrection, // GeometryCorrection gc_main, qc_main.geometryCorrection, // GeometryCorrection gc_main,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
if (debugLevel > -2) { if (debugLevel > 2) {
double [][] jt_delta = getJacobianTransposed( double [][] jt_delta = getJacobianTransposed(
1.0E-6, 1.0E-6,
qc_main.geometryCorrection, // GeometryCorrection gc_main, qc_main.geometryCorrection, // GeometryCorrection gc_main,
...@@ -645,6 +695,10 @@ public class GeometryCorrection { ...@@ -645,6 +695,10 @@ public class GeometryCorrection {
{ xc_pix, yc_pix}, { xc_pix, yc_pix},
{dxc_dangle, dyc_dangle}, {dxc_dangle, dyc_dangle},
{dxc_baseline, dyc_baseline}}; {dxc_baseline, dyc_baseline}};
/* double [][] rslt = {
{ -xc_pix, -yc_pix},
{-dxc_dangle, -dyc_dangle},
{-dxc_baseline, -dyc_baseline}}; */
return rslt; return rslt;
} }
...@@ -806,23 +860,23 @@ public class GeometryCorrection { ...@@ -806,23 +860,23 @@ public class GeometryCorrection {
"Directly to the right - 0°, directly up - 90°, ..."); "Directly to the right - 0°, directly up - 90°, ...");
gd.addNumericField("Auxilliary camera forward from the plane of the main one (not used)", this.aux_z, 3,6,"mm", gd.addNumericField("Auxilliary camera forward from the plane of the main one (not used)", this.aux_z, 3,6,"mm",
"Distance from the plane perpendicualr to the main camera axis to the auxiliary camera (positive for aux moved forward)"); "Distance from the plane perpendicualr to the main camera axis to the auxiliary camera (positive for aux moved forward)");
gd.addNumericField("Auxilliary camera azimuth (positive - to the right)", 1000.0*focalLength/pixelSize * this.aux_azimuth, 3,6,"pix", gd.addNumericField("Auxilliary camera azimuth (positive - to the right)", par_scales[AUX_AZIMUTH_INDEX] * this.aux_azimuth, 3,6,"pix",
"Relative to the main camera axis, shift of the center of the image in pixels"); "Relative to the main camera axis, shift of the center of the image in pixels");
gd.addNumericField("Auxilliary camera tilt (positive - looking up)", 1000.0*focalLength/pixelSize * this.aux_tilt, 3,6,"pix", gd.addNumericField("Auxilliary camera tilt (positive - looking up)", par_scales[AUX_TILT_INDEX] * this.aux_tilt, 3,6,"pix",
"Relative to the main camera, shift of the center of the image in pixels"); "Relative to the main camera, shift of the center of the image in pixels");
gd.addNumericField("Auxilliary camera roll (positive - clockwise)", 1000.0*distortionRadius/pixelSize * this.aux_roll, 3,6,"pix", gd.addNumericField("Auxilliary camera roll (positive - clockwise)", par_scales[AUX_ROLL_INDEX] * this.aux_roll, 3,6,"pix",
"Roll of a camera as a whole relative to the main camera, shift at the image half-width from the center"); "Roll of a camera as a whole relative to the main camera, shift at the image half-width from the center");
gd.addNumericField("Relative zoom - difference from 1.0 in parts parts per 1/1000", 1000.0*distortionRadius/pixelSize * this.aux_zoom, 3,6,"pix", gd.addNumericField("Relative zoom - difference from 1.0 in parts parts per 1/1000", par_scales[AUX_ZOOM_INDEX] * this.aux_zoom, 3,6,"pix",
"Zoom ratio, shift at the image half-width from the center"); "Zoom ratio, shift at the image half-width from the center");
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
this.baseline= gd.getNextNumber(); this.baseline= gd.getNextNumber();
this.aux_angle= gd.getNextNumber() * Math.PI/180; this.aux_angle= gd.getNextNumber() * Math.PI/180;
this.aux_z= gd.getNextNumber(); this.aux_z= gd.getNextNumber();
this.aux_azimuth= gd.getNextNumber()/(1000.0*focalLength/pixelSize) ; this.aux_azimuth= gd.getNextNumber()/par_scales[AUX_AZIMUTH_INDEX] ;
this.aux_tilt= gd.getNextNumber()/(1000.0*focalLength/pixelSize); this.aux_tilt= gd.getNextNumber()/par_scales[AUX_TILT_INDEX];
this.aux_roll= gd.getNextNumber()/(1000.0*distortionRadius/pixelSize); this.aux_roll= gd.getNextNumber()/par_scales[AUX_ROLL_INDEX];
this.aux_zoom= gd.getNextNumber()/(1000.0*distortionRadius/pixelSize); this.aux_zoom= gd.getNextNumber()/par_scales[AUX_ZOOM_INDEX];
recalcRXY(); recalcRXY();
return true; return true;
} }
......
...@@ -967,6 +967,7 @@ public class TwoQuadCLT { ...@@ -967,6 +967,7 @@ public class TwoQuadCLT {
disparity_bimap, // double [][] src_bimap, // current state of measurements (or null for new measurement) disparity_bimap, // double [][] src_bimap, // current state of measurements (or null for new measurement)
null, // double [][] prev_bimap, // previous state of measurements or null null, // double [][] prev_bimap, // previous state of measurements or null
2, // int refine_mode, // 0 - by main, 1 - by aux, 2 - by inter 2, // int refine_mode, // 0 - by main, 1 - by aux, 2 - by inter
// will still re-measure infinity if refine_min_strength == 0.0
true, // boolean keep_inf, // keep expected disparity 0.0 if it was so true, // boolean keep_inf, // keep expected disparity 0.0 if it was so
0.0, // double refine_min_strength, // do not refine weaker tiles 0.0, // double refine_min_strength, // do not refine weaker tiles
0.0, // double refine_tolerance, // do not refine if absolute disparity below 0.0, // double refine_tolerance, // do not refine if absolute disparity below
...@@ -986,6 +987,7 @@ public class TwoQuadCLT { ...@@ -986,6 +987,7 @@ public class TwoQuadCLT {
// do actual adjustment step, update rig parameters // do actual adjustment step, update rig parameters
quadCLT_aux.geometryCorrection.getRigCorrection( quadCLT_aux.geometryCorrection.getRigCorrection(
clt_parameters.rig.inf_weight , // double infinity_importance, // of all measurements
clt_parameters.rig.rig_adjust_orientation, // boolean adjust_orientation, clt_parameters.rig.rig_adjust_orientation, // boolean adjust_orientation,
clt_parameters.rig.rig_adjust_zoom, // boolean adjust_zoom, clt_parameters.rig.rig_adjust_zoom, // boolean adjust_zoom,
clt_parameters.rig.rig_adjust_angle, // boolean adjust_angle, clt_parameters.rig.rig_adjust_angle, // boolean adjust_angle,
...@@ -1066,16 +1068,17 @@ public class TwoQuadCLT { ...@@ -1066,16 +1068,17 @@ public class TwoQuadCLT {
/** /**
* Refine (re-measure with updated expected disparity) tiles. If refine_min_strength and refine_tolerance are both * Refine (re-measure with updated expected disparity) tiles. If refine_min_strength and refine_tolerance are both
* set to 0.0, all (or listed) tiles will be re-measured, use camera extrinsics are changed * set to 0.0, all (or listed) tiles will be re-measured, use camera after extrinsics are changed
* With refine_min_strength == 0, will re-measure infinity (have keep_inf == true)
* @param quadCLT_main main camera QuadCLT instance (should have tp initialized) * @param quadCLT_main main camera QuadCLT instance (should have tp initialized)
* @param quadCLT_aux auxiliary camera QuadCLT instance (should have tp initialized) * @param quadCLT_aux auxiliary camera QuadCLT instance (should have tp initialized)
* @param double_stacks image data from both cameras converted to double and conditioned * @param double_stacks image data from both cameras converted to double and conditioned
* @param src_bimap results of the older measurements (now includes expected disparity) * @param src_bimap results of the older measurements (now includes expected disparity)
* @param prev_bimap results of the even older measurements to interpolate if there was an overshoot * @param prev_bimap results of the even older measurements to interpolate if there was an overshoot
* @param refine_mode reference camera data: 0 - main camera, 1 - aux camera, 2 - cross-camera * @param refine_mode reference camera data: 0 - main camera, 1 - aux camera, 2 - cross-camera
* @param keep_inf do not refine expected disparity for infinity * @param keep_inf do not refine expected disparity for infinity, unless refine_min_strength == 0
* @param refine_min_strength do not refine weaker tiles * @param refine_min_strength do not refine weaker tiles
* @param refine_tolerance do not refine if residial disparity (after FD pre-shift by expected disparity) less than this * @param refine_tolerance do not refine if residual disparity (after FD pre-shift by expected disparity) less than this
* @param tile_list list of selected tiles or null. If null - try to refine all tiles, otherwise - only listed tiles * @param tile_list list of selected tiles or null. If null - try to refine all tiles, otherwise - only listed tiles
* @param saturation_main saturated pixels bitmaps for the main camera * @param saturation_main saturated pixels bitmaps for the main camera
* @param saturation_aux saturated pixels bitmaps for the auxiliary camera * @param saturation_aux saturated pixels bitmaps for the auxiliary camera
...@@ -1324,7 +1327,14 @@ public class TwoQuadCLT { ...@@ -1324,7 +1327,14 @@ public class TwoQuadCLT {
// check if it was measured (skip NAN) // check if it was measured (skip NAN)
if (Double.isNaN(src_bimap[ImageDtt.BI_TARGET_INDEX][nTile])) return false; if (Double.isNaN(src_bimap[ImageDtt.BI_TARGET_INDEX][nTile])) return false;
// check if it is infinity and change is prohibited // check if it is infinity and change is prohibited
if (keep_inf && (src_bimap[ImageDtt.BI_TARGET_INDEX][nTile] == 0.0)) return false; if (keep_inf && (src_bimap[ImageDtt.BI_TARGET_INDEX][nTile] == 0.0)) {
if ((refine_min_strength == 0.0) || (refine_tolerance == 0.0)) {
tile_op[tileY][tileX] = tile_op_all;
disparity_array[tileY][tileX] = 0.0;
return true;
}
return false;
}
double diff_disp, strength, disp_scale, diff_prev; double diff_disp, strength, disp_scale, diff_prev;
switch (refine_mode) { switch (refine_mode) {
case 0: case 0:
...@@ -1429,12 +1439,17 @@ public class TwoQuadCLT { ...@@ -1429,12 +1439,17 @@ public class TwoQuadCLT {
if (select_infinity) { if (select_infinity) {
for (int nTile = 0; nTile < numTiles; nTile++) { for (int nTile = 0; nTile < numTiles; nTile++) {
if ( (disparity_bimap[ImageDtt.BI_TARGET_INDEX][nTile] == 0.0 ) && // expected disparity was 0.0 (infinity) if ( (disparity_bimap[ImageDtt.BI_TARGET_INDEX][nTile] == 0.0 ) && // expected disparity was 0.0 (infinity)
(disparity_bimap[ImageDtt.BI_STR_FULL_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_main)&& (disparity_bimap[ImageDtt.BI_STR_FULL_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_main) &&
(disparity_bimap[ImageDtt.BI_ASTR_FULL_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_aux)&& (disparity_bimap[ImageDtt.BI_ASTR_FULL_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_aux) &&
(disparity_bimap[ImageDtt.BI_STR_CROSS_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_rig)&& (disparity_bimap[ImageDtt.BI_STR_CROSS_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_rig) &&
(Math.abs(disparity_bimap[ImageDtt.BI_DISP_FULL_INDEX][nTile]) <= clt_parameters.rig.inf_max_disp_main)&&
(Math.abs(disparity_bimap[ImageDtt.BI_ADISP_FULL_INDEX][nTile]) <= clt_parameters.rig.inf_max_disp_aux)&& (disparity_bimap[ImageDtt.BI_DISP_FULL_INDEX][nTile] <= clt_parameters.rig.inf_max_disp_main) &&
(Math.abs(disparity_bimap[ImageDtt.BI_DISP_CROSS_INDEX][nTile]) <= clt_parameters.rig.inf_max_disp_rig)) { (disparity_bimap[ImageDtt.BI_ADISP_FULL_INDEX][nTile] <= clt_parameters.rig.inf_max_disp_aux) &&
(disparity_bimap[ImageDtt.BI_DISP_CROSS_INDEX][nTile] <= clt_parameters.rig.inf_max_disp_rig) &&
(disparity_bimap[ImageDtt.BI_DISP_FULL_INDEX][nTile] >= -clt_parameters.rig.inf_max_disp_main) &&
(disparity_bimap[ImageDtt.BI_ADISP_FULL_INDEX][nTile] >= -clt_parameters.rig.inf_max_disp_aux) &&
(disparity_bimap[ImageDtt.BI_DISP_CROSS_INDEX][nTile] >= -clt_parameters.rig.inf_max_disp_rig * clt_parameters.rig.inf_neg_tolerance)) {
tilesList.add(nTile); tilesList.add(nTile);
} }
} }
...@@ -1445,9 +1460,14 @@ public class TwoQuadCLT { ...@@ -1445,9 +1460,14 @@ public class TwoQuadCLT {
(disparity_bimap[ImageDtt.BI_STR_FULL_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_main)&& (disparity_bimap[ImageDtt.BI_STR_FULL_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_main)&&
(disparity_bimap[ImageDtt.BI_ASTR_FULL_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_aux)&& (disparity_bimap[ImageDtt.BI_ASTR_FULL_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_aux)&&
(disparity_bimap[ImageDtt.BI_STR_CROSS_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_rig)&& (disparity_bimap[ImageDtt.BI_STR_CROSS_INDEX][nTile] >= clt_parameters.rig.inf_min_strength_rig)&&
(Math.abs(disparity_bimap[ImageDtt.BI_DISP_FULL_INDEX][nTile]) <= clt_parameters.rig.near_max_disp_main)&&
(Math.abs(disparity_bimap[ImageDtt.BI_ADISP_FULL_INDEX][nTile]) <= clt_parameters.rig.near_max_disp_aux)&& (disparity_bimap[ImageDtt.BI_DISP_FULL_INDEX][nTile] <= clt_parameters.rig.inf_max_disp_main) &&
(Math.abs(disparity_bimap[ImageDtt.BI_DISP_CROSS_INDEX][nTile]) <= clt_parameters.rig.near_max_disp_rig)) { (disparity_bimap[ImageDtt.BI_ADISP_FULL_INDEX][nTile] <= clt_parameters.rig.inf_max_disp_aux) &&
(disparity_bimap[ImageDtt.BI_DISP_CROSS_INDEX][nTile] <= clt_parameters.rig.inf_max_disp_rig) &&
(disparity_bimap[ImageDtt.BI_DISP_FULL_INDEX][nTile] >= -clt_parameters.rig.inf_max_disp_main) &&
(disparity_bimap[ImageDtt.BI_ADISP_FULL_INDEX][nTile] >= -clt_parameters.rig.inf_max_disp_aux) &&
(disparity_bimap[ImageDtt.BI_DISP_CROSS_INDEX][nTile] >= -clt_parameters.rig.inf_max_disp_rig * clt_parameters.rig.inf_neg_tolerance)) {
tilesList.add(nTile); tilesList.add(nTile);
} }
} }
......
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