Commit 16931433 authored by Andrey Filippov's avatar Andrey Filippov

bug fixes, NaNs in eigen, blanking individual tiles with fpn

parent 388be26d
......@@ -2753,15 +2753,21 @@ public class Correlation2d {
}
x0 += sx / s0; // relative to top-left
y0 += sy / s0;
//https://users.cs.utah.edu/~tch/CS4640/resources/A%20geometric%20interpretation%20of%20the%20covariance%20matrix.pdf
double cxx = sx2 - sx * sx / s0, cyy= sy2 - sy * sy / s0, cxy = sxy - sx * sy / s0;
double cxx = sx2 - sx * sx / s0, cyy= sy2 - sy * sy / s0, cxy = sxy - sx * sy / s0;
if ((sx2 == 0) ||(sy2 == 0) || (cxx == 0) || (cyy == 0)){
return null;
}
double [][] acovar = {{cxx, cxy},{cxy,cyy}};
// TODO: calculate for 2x2 faster?
double [] xy = {x0-center_xy, y0-center_xy}; // relative to the center
double [] rslt;
if (eig_fast2x2) {
double [] eig = getEigen2x2(acovar);
if (eig == null) {
return null;
}
rslt = new double[] {
xy[0], // x0 - center_xy,
xy[1], // y0 - center_xy,
......@@ -2787,13 +2793,19 @@ public class Correlation2d {
eigval[1-eig_indx]};
if (debug){
double [] r = getEigen2x2(acovar);
System.out.println(String.format("%10f %10f", rslt[3], r[0]));
System.out.println(String.format("%10f %10f", rslt[4], r[1]));
System.out.println(String.format("%10f %10f", rslt[5], r[2]));
System.out.println(String.format("%10f %10f", rslt[6], r[3]));
if (r!= null) {
System.out.println(String.format("%10f %10f", rslt[3], r[0]));
System.out.println(String.format("%10f %10f", rslt[4], r[1]));
System.out.println(String.format("%10f %10f", rslt[5], r[2]));
System.out.println(String.format("%10f %10f", rslt[6], r[3]));
} else {
System.out.println("Got null from getEigen2x2()");
}
}
}
if (Double.isNaN(rslt[3])) {
System.out.println("getMaxXYCmEig(): Got NaN");
}
if (debug){
System.out.println("getMaxXYCm() -> "+rslt[0]+":"+rslt[1]+" ("+rslt[2]+
......@@ -2882,10 +2894,18 @@ public class Correlation2d {
}
double [] lambda = {hapd-d, hapd+d};
double [] v0 = {A[0][0] - lambda[1], A[1][0]};
double k = 1.0/Math.sqrt(v0[0]*v0[0] + v0[1]*v0[1]);
double l = Math.sqrt(v0[0]*v0[0] + v0[1]*v0[1]);
if (l==0) {
return null;
}
double k = 1.0/l;
if (v0[0] < 0) { // to be compatible with standard?
k = -k;
}
if (Double.isNaN(k) || Double.isNaN(v0[0])) {
System.out.println("getEigen2x2(): Got NaN");
}
return new double [] {k*v0[0], k*v0[1], lambda[0], lambda[1]};
}
......
......@@ -3841,6 +3841,7 @@ public class Interscene {
boolean fpn_remove = !fpn_disable && clt_parameters.imp.fpn_remove;
double fpn_max_offset = clt_parameters.imp.fpn_max_offset;
final double fpn_min_offset = clt_parameters.imp.fpn_min_offset;
double fpn_radius = clt_parameters.imp.fpn_radius;
boolean fpn_ignore_border = clt_parameters.imp.fpn_ignore_border; // only if fpn_mask != null - ignore tile if maximum touches fpn_mask
boolean show_tptask_ref = false;
......@@ -4193,16 +4194,14 @@ public class Interscene {
}
}
double [][] fpn_offsets = null;
if (fpn_remove) {
fpn_offsets = getInterCorrOffsets(
final double [][] fpn_offsets = fpn_remove ? getInterCorrOffsets(
fpn_max_offset, // final double max_offset,
tp_tasks_ref, // final TpTask[] tp_tasks_ref,
tp_tasks[0], // final TpTask[] tp_tasks,
first_scene.getNumSensors(), // final int numSens,
tilesX, // final int tilesX,
tilesY); // final int tilesY);
}
tilesY) : null; // final int tilesY);
// Verify offsets before running LMA, return null and reason if test fails.
if (min_max != null) {
double [][] offsets = getInterCorrOffsets(
......@@ -4438,8 +4437,20 @@ public class Interscene {
}
return null;
}
}
int nremoved = 0;
if ((fpn_offsets != null) && (fpn_min_offset > 0)) {
nremoved = removeFPNTiles(
fpn_offsets, // final double [][] fpn_offsets,
fpn_min_offset, // final double fpn_min_offset,
coord_motion, // final double [][][] coord_motion,
1); // final int offset_index)
if (debug_level > -3) {
System.out.println("Removed "+nremoved+
" tiles as their peaks are too close to the FPN predicted offset (<"+fpn_min_offset+"pix");
}
}
// optional coord_motion[1][3..4] is reserved for disparity difference and strength
// final int globalDebugLevel);
if (use3D) {//(scene_disparity_strength != null)
......@@ -4822,6 +4833,42 @@ public class Interscene {
}
return null;
}
public static int removeFPNTiles(
final double [][] fpn_offsets,
final double fpn_min_offset,
final double [][][] coord_motion,
final int offset_index) {
if (fpn_offsets == null) {
return 0;
}
final double fpn_min_offset2 = fpn_min_offset * fpn_min_offset;
final Thread[] threads = ImageDtt.newThreadArray(THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger anremoved = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < fpn_offsets.length; nTile = ai.getAndIncrement()) {
if ((fpn_offsets[nTile] != null) && (coord_motion[offset_index][nTile] != null)) {
double dx = coord_motion[offset_index][nTile][0] - fpn_offsets[nTile][0];
double dy = coord_motion[offset_index][nTile][1] - fpn_offsets[nTile][1];
double l2 = dx*dx + dy*dy;
if (l2 < fpn_min_offset2) {
for (int i = 0; i < coord_motion.length; i++) {
coord_motion[i][nTile] = null;
}
anremoved.getAndIncrement();
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return anremoved.get();
}
public static boolean [] getMovementMask(
......
......@@ -806,7 +806,7 @@ public class IntersceneLma {
if (eigen == null) {
return null;
}
final double [][][] transform = new double[eigen.length][2][2];
final double [][][] transform = new double[eigen.length][][];
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
final double k0 = 1.0/eig_max_sqrt;
......@@ -816,11 +816,14 @@ public class IntersceneLma {
public void run() {
for (int iTile = ai.getAndIncrement(); iTile < eigen.length; iTile = ai.getAndIncrement()) if (eigen[iTile] != null){
double [][] am = {{eigen[iTile][0],eigen[iTile][1]},{eigen[iTile][1],-eigen[iTile][0]}};
for (int i = 0; i < 2; i++) {
double k = Math.max(0, 1/Math.max(eig_min_sqrt, Math.sqrt(eigen[iTile][2+i]))-k0);
for (int j = 0; j < 2; j++) {
transform[iTile][i][j] = k* am[i][j];
}
if (!Double.isNaN(am[0][0]) && !Double.isNaN(am[0][1])) {
transform[iTile] = new double [2][2];
for (int i = 0; i < 2; i++) {
double k = Math.max(0, 1/Math.max(eig_min_sqrt, Math.sqrt(eigen[iTile][2+i]))-k0);
for (int j = 0; j < 2; j++) {
transform[iTile][i][j] = k* am[i][j];
}
}
}
}
}
......@@ -849,8 +852,13 @@ public class IntersceneLma {
int thread_num = ati.getAndIncrement();
for (int iMTile = ai.getAndIncrement(); iMTile < vector_XYSDS.length; iMTile = ai.getAndIncrement()) if (vector_XYSDS[iMTile] != null){
double w = vector_XYSDS[iMTile][2];
if ((eig_trans != null) && (eig_trans[iMTile] == null)) {
w = 0;
continue;
}
if (Double.isNaN(w)) {
w = 0;
continue;
}
if (w > 0) {
anum_defined.getAndIncrement();
......@@ -1069,6 +1077,9 @@ public class IntersceneLma {
jt[i][num_components * iMTile + 2] = deriv_params[indx][2]; // pY (disparity is used)
}
}
if (Double.isNaN(jt[0][num_components * iMTile + 0])) {
System.out.println("getFxDerivs(): NaN, iMTile="+iMTile);
}
}
}
} else if (mb_mode) {
......@@ -1123,9 +1134,13 @@ public class IntersceneLma {
double d = 0.0;
for (int k = 0; k < nup_points; k++) {
if (jt[i][k] != 0) {
d+=0;
d+=0; // ???
}
d += weights[k]*jt[i][k]*jt[j][k];
if (Double.isNaN(d)) {
System.out.println("getWJtJlambda(): NAN i="+i+", j="+j+", k="+k);
}
}
wjtjl[i][j] = d;
if (i == j) {
......
......@@ -509,6 +509,7 @@ min_str_neib_fpn 0.35
// Remove correlation caused by FPN
public boolean fpn_remove = true; // only use reference DSI tiles that have LMA (strong) disparity
public double fpn_max_offset = 8.0; // pix - ignore larger FPN offsets
public double fpn_min_offset = 1.8; // pix - ignore tile if maximum differs less from fpn offset
public double fpn_radius = 0.75; // pix - zero around center
public boolean fpn_ignore_border = false; // only if fpn_mask != null - ignore tile if maximum touches fpn_mask
......@@ -1461,6 +1462,8 @@ min_str_neib_fpn 0.35
"Zero-out integrated inter-scene correlation around zero-shift offset");
gd.addNumericField("Maximal FPN offset to consider", this.fpn_max_offset, 6,7,"pix",
"Maximal offset from the zero shift to consider (normally just 8 pix)");
gd.addNumericField("Closest peak from the FPN offset", this.fpn_min_offset, 6,7,"pix",
"Discard tile if maximum is closer to the fpn offset");
gd.addNumericField("FPN suppression radius", this.fpn_radius, 6,7,"pix",
"Blank correlation pixels closer than this distance from the FPN offset");
gd.addCheckbox ("Ignore maximums \"touching\" FPN", this.fpn_ignore_border,
......@@ -2119,6 +2122,7 @@ min_str_neib_fpn 0.35
this.use_lma_dsi = gd.getNextBoolean();
this.fpn_remove = gd.getNextBoolean();
this.fpn_max_offset = gd.getNextNumber();
this.fpn_min_offset = gd.getNextNumber();
this.fpn_radius = gd.getNextNumber();
this.fpn_ignore_border = gd.getNextBoolean();
......@@ -2691,6 +2695,7 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"use_lma_dsi", this.use_lma_dsi+""); // boolean
properties.setProperty(prefix+"fpn_remove", this.fpn_remove+""); // boolean
properties.setProperty(prefix+"fpn_max_offset", this.fpn_max_offset+""); // double
properties.setProperty(prefix+"fpn_min_offset", this.fpn_min_offset+""); // double
properties.setProperty(prefix+"fpn_radius", this.fpn_radius+""); // double
properties.setProperty(prefix+"fpn_ignore_border", this.fpn_ignore_border+""); // boolean
......@@ -3221,6 +3226,7 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"use_lma_dsi")!=null) this.use_lma_dsi=Boolean.parseBoolean(properties.getProperty(prefix+"use_lma_dsi"));
if (properties.getProperty(prefix+"fpn_remove")!=null) this.fpn_remove=Boolean.parseBoolean(properties.getProperty(prefix+"fpn_remove"));
if (properties.getProperty(prefix+"fpn_max_offset")!=null) this.fpn_max_offset=Double.parseDouble(properties.getProperty(prefix+"fpn_max_offset"));
if (properties.getProperty(prefix+"fpn_min_offset")!=null) this.fpn_min_offset=Double.parseDouble(properties.getProperty(prefix+"fpn_min_offset"));
if (properties.getProperty(prefix+"fpn_radius")!=null) this.fpn_radius=Double.parseDouble(properties.getProperty(prefix+"fpn_radius"));
if (properties.getProperty(prefix+"fpn_ignore_border")!=null) this.fpn_ignore_border=Boolean.parseBoolean(properties.getProperty(prefix+"fpn_ignore_border"));
......@@ -3759,6 +3765,7 @@ min_str_neib_fpn 0.35
imp.use_lma_dsi = this.use_lma_dsi;
imp.fpn_remove = this.fpn_remove;
imp.fpn_max_offset = this.fpn_max_offset;
imp.fpn_min_offset = this.fpn_min_offset;
imp.fpn_radius = this.fpn_radius;
imp.fpn_ignore_border = this.fpn_ignore_border;
......
......@@ -6492,19 +6492,30 @@ public class OpticalFlow {
start_ref_pointers[0] = earliest_scene;
start_ref_pointers[1] = ref_index;
}
String top_dir = quadCLTs[ref_index].getX3dTopDirectory();
// temporary fix save/restore linkedModels, sourceDirectory, sourcePaths
// that are copied main-> aux in EyesisCorrectionParameters.updateAuxFromMain()
// quadCLT_main.correctionsParameters
String bkp_linkedModels = quadCLT_main.correctionsParameters.linkedModels;
String bkp_videoDirectory = quadCLT_main.correctionsParameters.videoDirectory;
String bkp_x3dDirectory = quadCLT_main.correctionsParameters.x3dDirectory;
String bkp_mlDirectory = quadCLT_main.correctionsParameters.mlDirectory;
String bkp_sourceDirectory = quadCLT_main.correctionsParameters.sourceDirectory;
String [] bkp_sourcePaths = quadCLT_main.correctionsParameters.sourcePaths;
boolean bkp_use_set_dirs = quadCLT_main.correctionsParameters.use_set_dirs;
quadCLTs[ref_index].saveConfInModelDirectory(); // save all (global) configurations in model/version directory
quadCLT_main.correctionsParameters.linkedModels = bkp_linkedModels;
quadCLT_main.correctionsParameters.videoDirectory = bkp_videoDirectory;
quadCLT_main.correctionsParameters.x3dDirectory = bkp_x3dDirectory;
quadCLT_main.correctionsParameters.mlDirectory = bkp_mlDirectory;
quadCLT_main.correctionsParameters.sourceDirectory = bkp_sourceDirectory;
quadCLT_main.correctionsParameters.sourceDirectory = bkp_sourceDirectory;
quadCLT_main.correctionsParameters.sourcePaths = bkp_sourcePaths;
quadCLT_main.correctionsParameters.use_set_dirs = bkp_use_set_dirs;
System.out.println("buildSeries(): DONE"); //
return quadCLTs[ref_index].getX3dTopDirectory();
String top_dir0=quadCLTs[ref_index].getX3dTopDirectory();
return quadCLTs[ref_index].getX3dTopDirectory(); // top_dir; //
}
public void adjustLYSeries(
......
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