Commit 41d614cb authored by Andrey Filippov's avatar Andrey Filippov

handling zero eigenvalues

parent b267218c
......@@ -2142,6 +2142,7 @@ public class EyesisCorrectionParameters {
public double grow_disp_step = 6.0; // Increase disparity (from maximal tried) if nothing found in that tile // TODO: handle enclosed dips?
public double grow_min_diff = 0.5; // Grow more only if at least one channel has higher variance from others for the tile
public boolean plPreferDisparity = false;// Always start with disparity-most axis (false - lowest eigenvalue)
public double plDispNorm = 3.0; // Normalize disparities to the average if above (now only for eigenvalue comparison)
public int plMinPoints = 5; // Minimal number of points for plane detection
public double plTargetEigen = 0.1; // Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below
......@@ -2150,7 +2151,8 @@ public class EyesisCorrectionParameters {
public double plMinStrength = 0.1; // Minimal total strength of a plane
public double plMaxEigen = 0.3; // Maximal eigenvalue of a plane
public boolean plDbgMerge = true; // Combine 'other' plane with current
public double plWorstWorsening = 1.0; // Worst case worsening after merge
public double plWorstWorsening = 3.0; // Worst case worsening after merge
public double plWeakWorsening = 1.0; // Relax merge requirements for weaker planes
public boolean plMutualOnly = true; // keep only mutual links, remove weakest if conflict
public boolean plFillSquares = true; // Add diagonals to full squares
public boolean plCutCorners = true; // Add ortho to 45-degree corners
......@@ -2406,6 +2408,7 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"grow_disp_step", this.grow_disp_step +"");
properties.setProperty(prefix+"grow_min_diff", this.grow_min_diff +"");
properties.setProperty(prefix+"plPreferDisparity",this.plPreferDisparity+"");
properties.setProperty(prefix+"plDispNorm", this.plDispNorm +"");
properties.setProperty(prefix+"plMinPoints", this.plMinPoints+"");
properties.setProperty(prefix+"plTargetEigen", this.plTargetEigen +"");
......@@ -2415,6 +2418,7 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"plMaxEigen", this.plMaxEigen +"");
properties.setProperty(prefix+"plDbgMerge", this.plDbgMerge+"");
properties.setProperty(prefix+"plWorstWorsening", this.plWorstWorsening +"");
properties.setProperty(prefix+"plWeakWorsening", this.plWeakWorsening +"");
properties.setProperty(prefix+"plMutualOnly", this.plMutualOnly+"");
properties.setProperty(prefix+"plFillSquares", this.plFillSquares+"");
......@@ -2657,6 +2661,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"grow_disp_step")!=null) this.grow_disp_step=Double.parseDouble(properties.getProperty(prefix+"grow_disp_step"));
if (properties.getProperty(prefix+"grow_min_diff")!=null) this.grow_min_diff=Double.parseDouble(properties.getProperty(prefix+"grow_min_diff"));
if (properties.getProperty(prefix+"plPreferDisparity")!=null) this.plPreferDisparity=Boolean.parseBoolean(properties.getProperty(prefix+"plPreferDisparity"));
if (properties.getProperty(prefix+"plDispNorm")!=null) this.plDispNorm=Double.parseDouble(properties.getProperty(prefix+"plDispNorm"));
if (properties.getProperty(prefix+"plMinPoints")!=null) this.plMinPoints=Integer.parseInt(properties.getProperty(prefix+"plMinPoints"));
if (properties.getProperty(prefix+"plTargetEigen")!=null) this.plTargetEigen=Double.parseDouble(properties.getProperty(prefix+"plTargetEigen"));
......@@ -2666,6 +2671,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"plMaxEigen")!=null) this.plMaxEigen=Double.parseDouble(properties.getProperty(prefix+"plMaxEigen"));
if (properties.getProperty(prefix+"plDbgMerge")!=null) this.plDbgMerge=Boolean.parseBoolean(properties.getProperty(prefix+"plDbgMerge"));
if (properties.getProperty(prefix+"plWorstWorsening")!=null) this.plWorstWorsening=Double.parseDouble(properties.getProperty(prefix+"plWorstWorsening"));
if (properties.getProperty(prefix+"plWeakWorsening")!=null) this.plWeakWorsening=Double.parseDouble(properties.getProperty(prefix+"plWeakWorsening"));
if (properties.getProperty(prefix+"plMutualOnly")!=null) this.plMutualOnly=Boolean.parseBoolean(properties.getProperty(prefix+"plMutualOnly"));
if (properties.getProperty(prefix+"plFillSquares")!=null) this.plFillSquares=Boolean.parseBoolean(properties.getProperty(prefix+"plFillSquares"));
......@@ -2930,6 +2936,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Increase disparity (from maximal tried) if nothing found in that tile", this.grow_disp_step, 6);
gd.addNumericField("Grow more only if at least one channel has higher variance from others for the tile", this.grow_min_diff, 6);
gd.addMessage ("--- Planes detection ---");
gd.addCheckbox ("Always start with disparity-most axis (false - lowest eigenvalue)", this.plPreferDisparity);
gd.addNumericField("Normalize disparities to the average if above", this.plDispNorm, 6);
gd.addNumericField("Minimal number of points for plane detection", this.plMinPoints, 0);
gd.addNumericField("Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below", this.plTargetEigen, 6);
......@@ -2937,8 +2944,9 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Maximal number of outliers to remove", this.plMaxOutliers, 0);
gd.addNumericField("Minimal total strength of a plane", this.plMinStrength, 6);
gd.addNumericField("Maximal eigenvalue of a plane", this.plMaxEigen, 6);
gd.addCheckbox ("Combine 'other' plane with the current", this.plDbgMerge);
gd.addCheckbox ("Combine 'other' plane with the current (unused)", this.plDbgMerge);
gd.addNumericField("Worst case worsening after merge", this.plWorstWorsening, 6);
gd.addNumericField("Relax merge requirements for weaker planes", this.plWeakWorsening, 6);
gd.addCheckbox ("Keep only mutual links, remove weakest if conflict", this.plMutualOnly);
gd.addCheckbox ("Add diagonals to full squares", this.plFillSquares);
......@@ -3191,6 +3199,7 @@ public class EyesisCorrectionParameters {
this.grow_disp_step= gd.getNextNumber();
this.grow_min_diff= gd.getNextNumber();
this.plPreferDisparity= gd.getNextBoolean();
this.plDispNorm= gd.getNextNumber();
this.plMinPoints= (int) gd.getNextNumber();
this.plTargetEigen= gd.getNextNumber();
......@@ -3200,6 +3209,7 @@ public class EyesisCorrectionParameters {
this.plMaxEigen= gd.getNextNumber();
this.plDbgMerge= gd.getNextBoolean();
this.plWorstWorsening= gd.getNextNumber();
this.plWeakWorsening= gd.getNextNumber();
this.plMutualOnly= gd.getNextBoolean();
this.plFillSquares= gd.getNextBoolean();
......
......@@ -1168,7 +1168,6 @@ public class SuperTiles{
public void processPlanes2(
final boolean [] selected, // or null
final double min_disp,
final boolean invert_disp, // use 1/disparity
......@@ -1177,6 +1176,7 @@ public class SuperTiles{
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 int debugLevel,
......@@ -1262,27 +1262,19 @@ public class SuperTiles{
}
}
planes[nsTile] = null;
if (sw >0){
if (sw >0){ // there are some non-zero tiles, process them (all points, not clustered by disparity value)
ArrayList<TilePlanes.PlaneData> st_planes = new ArrayList<TilePlanes.PlaneData>();
// int dl = ((nsTile >= debug_stile-1) && (nsTile <= debug_stile+1) ) ? 1 : 0;
// int dl = ((stileY == 17) && (stileX > 4)) ? 1 : 0;
// int dl = (stileY >= 0) ? 1 : 0;
int dl1 = (nsTile == debug_stile) ? 3 : 0;
// int dl = (nsTile == debug_stile) ? 3 : 0;
// int dl = ((stileY >= 15) && (stileY <= 18) && (stileX >= 5) && (stileX <= 31)) ? 1 : 0;
// int dl = ((stileY == 16) && (stileX == 27) ) ? 3 : 0;
int dl = (nsTile == debug_stile) ? 3 : 0;
// int debugLevel1 = ((sTileXY[0] == 27) && (sTileXY[1] == 16))? 1: 0; // check why v[0][0] <0
boolean [] sel_all = stSel.clone();
TilePlanes.PlaneData pd = tpl.getPlane(
sTiles,
stDisparity,
stStrength,
sel_all,
plPreferDisparity,
0); // debugLevel);
if (pd != null) {
if (pd != null) { // not too few points, probably
//correct_distortions
double swc_common = pd.getWeight();
if (dl > 0) {
......@@ -1301,19 +1293,11 @@ public class SuperTiles{
// 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 ((plTargetEigen > 0.0) && (z0 > plDispNorm)) {
double dd = (plDispNorm + z0)/ plDispNorm; // > 1
targetV *= dd * dd; // > original
}
*/
double targetV = corrMaxEigen(
plTargetEigen,
plDispNorm,
pd);
if (pd.getValues()[0] > targetV) {
if (pd.getValue() > targetV) {
pd = tpl.removePlaneOutliers(
pd,
sTiles,
......@@ -1323,7 +1307,9 @@ public class SuperTiles{
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)
plMinPoints, // int minLeft, // minimal number of tiles to keep
plPreferDisparity,
dl1); // 0); // debugLevel);
if (pd == null) continue;
if (dl > 0) {
if (swc_common > 0.3) { // 1.0) {
System.out.println("Removed outliers["+nsTile+"]"+
......@@ -1350,9 +1336,9 @@ public class SuperTiles{
norm_xyz[0]+", "+norm_xyz[1]+", "+norm_xyz[2]+"}");
}
st_planes.add(pd);
st_planes.add(pd); // adding [0] - all supertile tiles, not clustered by disparity value
// now try for each of the disparity-separated clusters
// now try for each of the disparity-separated clusters (only for multi-peak histograms)
double [][] mm = maxMinMax[nsTile];
......@@ -1392,6 +1378,7 @@ public class SuperTiles{
stDisparity,
stStrength,
stSels[m],
plPreferDisparity,
0); // debugLevel);
if (pd != null) {
if (dl > 0) {
......@@ -1426,7 +1413,11 @@ public class SuperTiles{
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)
plMinPoints, // int minLeft, // minimal number of tiles to keep
plPreferDisparity,
dl1); // 0); // debugLevel);
if (pd == null) {
continue;
}
if (dl > 0) {
if (swc_common > 1.0) {
System.out.println("Removed outliers["+nsTile+"]["+m+"]"+
......@@ -1485,6 +1476,7 @@ public class SuperTiles{
TilePlanes.PlaneData [][] getNeibPlanes(
final int dir, // 0: get from up (N), 1:from NE, ... 7 - from NW
final boolean preferDisparity,
final boolean dbgMerge, // Combine 'other' plane with current
final int dbg_X,
final int dbg_Y
......@@ -1548,12 +1540,14 @@ public class SuperTiles{
planes[nsTile0][indx], // PlaneData otherPd,
1.0, // double scale_other,
true, // boolean ignore_weights,
preferDisparity,
(nsTile0 == debug_stile)? 1:0); // int debugLevel)
System.out.println("other with other, same weight:");
TilePlanes.PlaneData other_other_pd = other_pd.mergePlaneToThis(
other_pd, // PlaneData otherPd,
1.0, // double scale_other,
true, // boolean ignore_weights,
preferDisparity,
(nsTile0 == debug_stile)? 1:0); // int debugLevel)
System.out.println("other with this, same weight:");
}
......@@ -1561,6 +1555,7 @@ public class SuperTiles{
other_pd, // PlaneData otherPd,
1.0, // double scale_other,
true, // boolean ignore_weights,
preferDisparity,
(nsTile0 == debug_stile)? 1:0); // int debugLevel)
if (!(merged_pd.getValue() > best_value)) { // Double.isNaN(best_value) will work too
best_value = merged_pd.getValue();
......@@ -1576,6 +1571,7 @@ public class SuperTiles{
other_pd, // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
preferDisparity,
(nsTile0 == debug_stile)? 1:0); // int debugLevel)
neib_planes[nsTile0][np] = merged_pd;
} else {
......@@ -1618,6 +1614,7 @@ public class SuperTiles{
}
public void matchPlanes(
final boolean preferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
final int dbg_X,
final int dbg_Y)
{
......@@ -1636,6 +1633,7 @@ public class SuperTiles{
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
// Select best symmetrical match, consider only N, NE, E, SE - later opposite ones will be copied
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
......@@ -1673,6 +1671,7 @@ public class SuperTiles{
other_plane, // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
preferDisparity,
dl); // int debugLevel)
if (merged_pd !=null) { // now always, but may add later
this_plane.setNeibMatch(dir, np, merged_pd.getValue()); // smallest eigenValue
......@@ -1706,28 +1705,18 @@ public class SuperTiles{
if ( planes[nsTile0] != null) {
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
// this_plane.initMergedValue();
for (int dir = 4; dir < 8; dir++){ // other half - copy from opposite
int stx = stx0 + dirsYX[dir][1];
int sty = sty0 + dirsYX[dir][0];
// if ((stx < stilesX) && (sty < stilesY) && (sty > 0)) {
if ((sty < stilesY) && (sty > 0) && (stx > 0)) {
int nsTile = sty * stilesX + stx; // from where to get
TilePlanes.PlaneData [] other_planes = planes[nsTile];
if (other_planes !=null) {
this_plane.initMergedValue(dir,other_planes.length); // filled with NaN
for (int np = 0; np < other_planes.length; np ++){
/*
if ((other_planes[np] != null) && (other_planes[np].getMergedValue(dir-4) != null)) {
double [] dbg_nm = other_planes[np].getMergedValue(dir-4);
this_plane.setNeibMatch(dir,np, other_planes[np].getMergedValue(dir-4, np0)); //
}
*/
if (other_planes[np] != null) { // && (other_planes[np].getMergedValue(dir-4) != null)) {
double [] nm = other_planes[np].getMergedValue(dir-4);
if (nm != null) {
// this_plane.setNeibMatch(dir,np, other_planes[np].getMergedValue(dir-4, np0)); //
this_plane.setNeibMatch(dir,np, nm[np0]); //
}
}
......@@ -1859,7 +1848,7 @@ public class SuperTiles{
ImageDtt.startAndJoin(threads);
}
}
public void fillSquares()
public int fillSquares()
{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
......@@ -1868,6 +1857,7 @@ public class SuperTiles{
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
int num_added = 0;
for (int stY = 0; stY < (stilesY - 1); stY++ ) {
for (int stX = 0; stX < (stilesX - 1); stX++ ) {
int nsTile = stY * stilesX + stX;
......@@ -1891,18 +1881,21 @@ public class SuperTiles{
if (neibs0[3] < 0) {
neibs0[3] = neibs1[4];
neibs3[7] = np;
num_added++;
}
if (neibs1[5] < 0){
neibs1[5] = neibs0[4];
neibs2[1] = neibs0[2];
num_added++;
}
}
}
}
}
return num_added;
}
public void cutCorners()
public int cutCorners()
{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
......@@ -1910,7 +1903,8 @@ public class SuperTiles{
// 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 int nStiles = stilesX * stilesY;
int num_added = 0;
for (int stY = 0; stY < (stilesY - 1); stY++ ) {
for (int stX = 0; stX < (stilesX - 1); stX++ ) {
int nsTile = stY * stilesX + stX;
......@@ -1931,6 +1925,7 @@ public class SuperTiles{
neibs0[4] = neibs1[5];
int [] neibs2 = planes4[2][neibs1[5]].getNeibBest();
neibs2[0] = np; //?
num_added++;
}
}
}
......@@ -1942,6 +1937,7 @@ public class SuperTiles{
neibs0[2] = neibs2[1];
int [] neibs1 = planes4[1][neibs2[1]].getNeibBest();
neibs1[6] = np;
num_added++;
}
}
}
......@@ -1951,6 +1947,7 @@ public class SuperTiles{
if (neibs1[4] < 0) {
neibs1[4] = neibs0[3];
neibs3[0] = neibs0[2]; //?
num_added++;
}
}
if ((neibs0[3] >= 0) && (neibs0[4] >= 0)){
......@@ -1959,6 +1956,7 @@ public class SuperTiles{
if (neibs2[2] < 0) {
neibs2[2] = neibs0[3];
neibs3[6] = neibs0[4];
num_added++;
}
}
}
......@@ -1975,6 +1973,7 @@ public class SuperTiles{
if (neibs0[2] < 0) {
neibs0[2] = neibs3[0];
neibs1[6] = neibs3[7];
num_added++;
}
}
......@@ -1985,6 +1984,7 @@ public class SuperTiles{
if (neibs0[4] < 0) {
neibs0[4] = neibs3[6];
neibs2[0] = neibs3[7]; //?
num_added++;
}
}
......@@ -1996,6 +1996,7 @@ public class SuperTiles{
int [] neibs2 = planes4[2][neibs0[4]].getNeibBest();
neibs3[6] = neibs0[4];
neibs2[2] = np; //?
num_added++;
}
}
......@@ -2006,6 +2007,7 @@ public class SuperTiles{
int [] neibs1 = planes4[1][neibs2[1]].getNeibBest();
neibs3[0] = neibs2[1]; //?
neibs1[4] = np;
num_added++;
}
}
}
......@@ -2013,6 +2015,8 @@ public class SuperTiles{
}
}
}
return num_added;
}
/**
......@@ -2027,6 +2031,7 @@ public class SuperTiles{
*/
public void selectNeighborPlanesMutual(
final double rquality,
final double weakWorsening,
final double dispNorm,
final double maxEigen, // maximal eigenvalue of planes to consider
final double minWeight, // minimal pain weight to consider
......@@ -2130,8 +2135,9 @@ public class SuperTiles{
merge_ev[np], // double L,
w1, // double w1,
w2); // double w2)
// if (this_rq <= rquality) { // compare with the threshold before applying strengths
if ((w1 + w2) * this_rq <= rquality) { // forgive more for weak planes
double this_rq_norm = this_rq;
if ((w1 + w2) < weakWorsening) this_rq_norm *= (w1 + w2) / weakWorsening; // forgive more for weak planes
if (this_rq_norm <= rquality) {
this_rq /= (w1 + w2); // for comparision reduce this value for stronger planes
if (Double.isNaN(best_rqual) || (this_rq < best_rqual)){ // OK if Double.isNaN(this_rq[np])
best_rqual = this_rq;
......@@ -2504,6 +2510,7 @@ public class SuperTiles{
final double meas_pull,// relative pull of the original (measured) plane with respect to the average of the neighbors
final int num_passes,
final double maxDiff, // maximal change in any of the disparity values
final boolean preferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
final int debugLevel,
final int dbg_X,
final int dbg_Y)
......@@ -2517,6 +2524,7 @@ public class SuperTiles{
this.planes, // final TilePlanes.PlaneData[][] measured_planes,
this.planes_mod, // final TilePlanes.PlaneData[][] mod_planes,
true, // final boolean calc_diff,
preferDisparity,
(pass < 10)? debugLevel: 0,
dbg_X,
dbg_Y);
......@@ -2539,6 +2547,7 @@ public class SuperTiles{
final TilePlanes.PlaneData[][] measured_planes,
final TilePlanes.PlaneData[][] mod_planes,
final boolean calc_diff,
final boolean preferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
final int debugLevel,
final int dbg_X,
final int dbg_Y)
......@@ -2600,6 +2609,7 @@ public class SuperTiles{
other_plane, // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
preferDisparity,
dl); // int debugLevel)
} else {
this_new_plane = other_plane;
......@@ -2619,6 +2629,7 @@ public class SuperTiles{
measured_planes[nsTile0][np0], // PlaneData otherPd,
meas_pull, // double scale_other,
false, // boolean ignore_weights,
preferDisparity,
dl); // int debugLevel)
} else {
this_new_plane = measured_planes[nsTile0][np0].clone();
......
......@@ -452,6 +452,7 @@ public class TilePlanes {
PlaneData otherPd,
double scale_other,
boolean ignore_weights,
boolean preferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
int debugLevel)
{
if (debugLevel > 0) {
......@@ -475,6 +476,10 @@ public class TilePlanes {
double other_fraction = ignore_weights? (scale_other/(scale_other + 1.0)): ((scale_other * otherPd.weight) / sum_weight);
Matrix common_center = this_center.times(1.0 - other_fraction).plus(other_center.times(other_fraction));
Matrix other_offset = other_center.minus(this_center); // other center from this center
if ((this.values[0] == 0.0) || (otherPd.values[0] == 0.0)) {
System.out.println("Zero eigenvalue");
debugLevel = 10;
}
if (debugLevel > 0) {
System.out.println("other_eig_vals");
other_eig_vals.print(8, 6);
......@@ -495,9 +500,6 @@ public class TilePlanes {
System.out.println("other_fraction="+other_fraction);
}
double [][] acovar = { // covariance matrix of center masses (not yet scaled by weight)
{other_offset.get(0,0)*other_offset.get(0,0), other_offset.get(0,0)*other_offset.get(1,0), other_offset.get(0,0)*other_offset.get(2,0)},
{other_offset.get(1,0)*other_offset.get(0,0), other_offset.get(1,0)*other_offset.get(1,0), other_offset.get(1,0)*other_offset.get(2,0)},
......@@ -525,9 +527,12 @@ public class TilePlanes {
System.out.println("covar with other_covar and this_covar");
covar.print(8, 6);
}
if (Double.isNaN(covar.get(0, 0))){
System.out.println("covar is NaN !");
covar.print(8, 6);
}
// extract new eigenvalues, eigenvectors
EigenvalueDecomposition eig = covar.eig();
EigenvalueDecomposition eig = covar.eig(); // verify NaN - it gets stuck
// eig.getD().getArray(),
// eig.getV().getArray(),
if (debugLevel > 0) {
......@@ -542,12 +547,30 @@ public class TilePlanes {
double [][] eig_vect = eig.getV().getArray();
double [][] eig_val = eig.getD().getArray();
// make towards camera, left coordinate system
/*
int oindx = 0;
for (int i = 1; i <3; i++){
if (Math.abs(eig_vect[0][i]) > Math.abs(eig_vect[0][oindx])){
oindx = i;
}
}
*/
int oindx = 0;
if (preferDisparity) {
for (int i = 1; i <3; i++){
if (Math.abs(eig_vect[0][i]) > Math.abs(eig_vect[0][oindx])){
oindx = i;
}
}
} else {
for (int i = 1; i <3; i++){
if (eig_val[i][i] < eig_val[oindx][oindx]){
oindx = i;
}
}
}
// select 2 other axes for increasing eigenvalues (so v is short axis, h is the long one)
int vindx = (oindx == 0)? 1 : 0;
int hindx = (oindx == 0)? 2 : ((oindx == 1) ? 2 : 1);
......@@ -886,6 +909,7 @@ public class TilePlanes {
boolean [] select,
double plDispNorm, // Normalize disparities to the average if above
int debugLevel){
double mindet = 1E-15;
int stSize2 = 2 * stSize;
// Matrix covar = new Matrix(3,3);
double [][] acovar = new double [3][3];
......@@ -939,8 +963,21 @@ public class TilePlanes {
acovar [2][0] = acovar [0][2];
acovar [2][1] = acovar [1][2];
Matrix covar = new Matrix(acovar);
if (Math.abs(covar.det()) < mindet){
debugLevel = 5;
}
EigenvalueDecomposition eig = covar.eig();
if (Double.isNaN(eig.getV().get(0, 0))){
System.out.println("getCovar(): Double.isNaN(eig.getV().get(0, 0))");
debugLevel = 20;
}
if (eig.getD().get(0, 0) == 0.0){
debugLevel = 10;
}
if (debugLevel > 0){
System.out.println("getCovar(): sw = "+sw +", swz = "+swz +", swx = "+swx +", swy = "+swy +", covar.det() = "+covar.det());
System.out.println("getCovar(): covarianvce matrix, number of used points:"+numPoints);
covar.print(10, 6); // w,d
System.out.println("getCovar(): eigenvalues");
......@@ -948,6 +985,10 @@ public class TilePlanes {
System.out.println("getCovar(): eigenvectors");
eig.getV().print(10, 6); // w,d
}
if ((eig.getD().get(0, 0) == 0.0) || (Math.abs(covar.det()) < mindet)) {
return null; // testing with zero eigenvalue
// Problem with zero eigenvalue is with derivatives and coordinate conversion
}
double [][][] rslt = {
eig.getD().getArray(),
eig.getV().getArray(),
......@@ -962,13 +1003,12 @@ public class TilePlanes {
double [] data,
double [] weight,
boolean [] select, // null OK, will enable all tiles
boolean preferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
int debugLevel){
if (select == null) {
select = new boolean [4*stSize];
for (int i = 0; i < select.length; i++) select[i] = true;
}
// int debugLevel1 = ((sTileXY[0] == 27) && (sTileXY[1] == 20))? 1: 0;
// int debugLevel1 = ((sTileXY[0] == 27) && (sTileXY[1] == 17))? 1: 0;
int debugLevel1 = ((sTileXY[0] == 27) && (sTileXY[1] == 16))? 1: 0; // check why v[0][0] <0
......@@ -980,7 +1020,6 @@ public class TilePlanes {
debugLevel1); //0); // debugLevel);
if (rslt == null) return null;
int numPoints = (int) rslt[2][0][2];
// double kz = rslt[2][0][1]; // == 1.0
double swc = rslt[2][0][0];
double [] szxy = rslt[2][1];
double [][] eig_val = rslt[0];
......@@ -988,11 +1027,23 @@ public class TilePlanes {
// find vector most orthogonal to view // (anyway it all works with that assumption), make it first
// TODO normalize to local linear scales
int oindx = 0;
if (preferDisparity) {
for (int i = 1; i <3; i++){
if (Math.abs(eig_vect[0][i]) > Math.abs(eig_vect[0][oindx])){
oindx = i;
}
}
} else {
for (int i = 1; i < 3 ; i++){
if (eig_val[i][i] < eig_val[oindx][oindx]){
oindx = i;
}
}
}
if (eig_val[oindx][oindx] == 0.0){
System.out.println("getPlane(): zero eigenvalue!!");
}
/*
// Find two other axis - "mostly X" (horizontal) and "mostly Y" (vertical)
int vindx = (oindx == 0)? 1 : 0;
......@@ -1058,6 +1109,7 @@ public class TilePlanes {
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 minLeft, // minimal number of tiles to keep
boolean preferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
int debugLevel){
int stSize2 = 2 * stSize;
if (pd == null) {
......@@ -1066,10 +1118,14 @@ public class TilePlanes {
data,
weight,
select, // null OK
preferDisparity,
debugLevel);
} else if (select != null){
pd.setPlaneSelection(select);
}
if (pd == null){
return null; // zero eigenvalues
}
if (maxRemoved > (pd.getNumPoints() - minLeft)) maxRemoved = pd.getNumPoints() - minLeft;
int numRemoved = 0;
for (; (pd.getValue() > targetEigen) && (numRemoved < maxRemoved); numRemoved++){
......@@ -1107,7 +1163,11 @@ public class TilePlanes {
data,
weight,
select,
preferDisparity,
debugLevel);
if (pd == null) {
return null;
}
}
return pd;
}
......
......@@ -2952,7 +2952,8 @@ public class TileProcessor {
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.plMaxOutliers, // = 20; // Maximal number of outliers to remove\
clt_parameters.plPreferDisparity,
geometryCorrection,
clt_parameters.correct_distortions,
0, // -1, // debugLevel, // final int debugLevel)
......@@ -2964,25 +2965,35 @@ public class TileProcessor {
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
st.matchPlanes(
clt_parameters.plPreferDisparity,
clt_parameters.tileX,
clt_parameters.tileY);
st.selectNeighborPlanesMutual(
clt_parameters.plWorstWorsening, // final double worst_worsening,
clt_parameters.plWeakWorsening, // final double worst_worsening,
clt_parameters.plDispNorm,
clt_parameters.plMaxEigen,
clt_parameters.plMinStrength,
0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
while (true) {
int num_added = 0;
if (clt_parameters.plFillSquares){
st.fillSquares();
num_added += st.fillSquares();
}
if (debugLevel > -1) {
System.out.println("after fillSquares() added "+num_added);
}
if (clt_parameters.plCutCorners){
st.cutCorners();
num_added += st.cutCorners();
}
if (debugLevel > -1) {
System.out.println("after plCutCorners() added (cumulative) "+num_added);
}
if (num_added == 0) break;
}
TilePlanes.PlaneData [][] planes_mod = null;
......@@ -2993,6 +3004,7 @@ public class TileProcessor {
clt_parameters.plPull, // final double meas_pull,// relative pull of the original (measured) plane with respect to the average of the neighbors
clt_parameters.plIterations, // final int num_passes,
Math.pow(10.0, -clt_parameters.plPrecision), // final double maxDiff, // maximal change in any of the disparity values
clt_parameters.plPreferDisparity,
0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
......
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