Commit c4468ec2 authored by Andrey Filippov's avatar Andrey Filippov

more testing/tuning

parent e5d30e06
......@@ -2164,12 +2164,12 @@ public class EyesisCorrectionParameters {
public int plInitPasses = 3; // Number of initial passes to assign tiles to vert (const disparity) and hor planes
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
public double plTargetEigen = 0.02; // Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below
public double plFractOutliers = 0.3; // Maximal fraction of outliers to remove
public int plMaxOutliers = 20; // Maximal number of outliers to remove
public double plMinStrength = 0.1; // Minimal total strength of a plane
public double plMaxEigen = 0.05; // Maximal eigenvalue of a plane
public double plEigenFloor = 0.01; // Add to eigenvalues of each participating plane and result to validate connections
public double plMinStrength = 0.01; // Minimal total strength of a plane
public double plMaxEigen = 0.06; // Maximal eigenvalue of a plane
public double plEigenFloor = 0.005;// Add to eigenvalues of each participating plane and result to validate connections
public boolean plDbgMerge = true; // Combine 'other' plane with current
public double plWorstWorsening = 2.0; // Worst case worsening after merge
public double plWorstWorsening2 = 5.0; // Worst case worsening for thin planes
......@@ -2177,6 +2177,7 @@ public class EyesisCorrectionParameters {
public double plWorstEq2 = 2.0; // Worst case worsening for thin planes with equal weights
public double plOKMergeEigen = 0.03; // If result of the merged planes is below, OK to use thin planes (higher) threshold
public double plMaxWorldSin2 = 0.1; // Maximal sine squared of the world angle between planes to merge. Set to >= 1.0 to disable
public double pl2dForSin = 2.5; // Do not compare sin() between planes, if at least one has too small axis ratio
public double plWeakWorsening = 1.0; // Relax merge requirements for weaker planes
public double plMaxOverlap = 0.1; // Maximal overlap between the same supertile planes to merge
// Merge same supetile planes if at least one is weak and they do not differ much
......@@ -2184,12 +2185,14 @@ public class EyesisCorrectionParameters {
public double plWeakEigen = 0.1; // Maximal eigenvalue of the result of non-weighted merge
public double plWeakWeight2 = 10.0 ; // Maximal weight of the weak plane to merge (second variant)
public double plWeakEigen2 = 0.05; // Maximal eigenvalue of the result of non-weighted merge (second variant)
public double plSumThick = 1.2; // Do not merge if any sqrt of merged eigenvalue exceeds scaled sum of components
public double plMaxZRatio = 2.0; // Maximal ratio of Z to allow plane merging
public double plMaxDisp = 0.6; // Maximal disparity of one of the planes to apply maximal ratio
public double plCutTail = 1.4; // When merging with neighbors cut the tail that is worse than scaled best
public double plMinTail = 0.015;// Set cutoff value level not less than
// parameters to recreate planes from tiles disparity/strengths using determined plane connections to neighbors
public boolean plDiscrEn = true; // Enable planes tiles selection regeneration hinted by supertile neighbors
public double plDiscrTolerance = 0.4; // Maximal disparity difference from the plane to consider tile
public double plDiscrDispRange = 1.0; // Parallel move known planes around original know value for the best overall fit
public int plDiscrSteps = 10; // Number of steps (each direction) for each plane to search for the best fit (0 - single, 1 - 1 each side)
......@@ -2202,6 +2205,12 @@ public class EyesisCorrectionParameters {
public double plDiscrExclusivity = 1.5; // Tile exclusivity: 1.0 - tile belongs to one plane only, 0.0 - regardless of others
public double plDiscrExclus2 = 0.8; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
public boolean plDiscrStrict = false; // When growing selection do not allow any offenders around (false - more these than others)
public double plDiscrCorrMax = 0.7; // Attraction to different planes correlation that is too high for re-discrimination.
public double plDiscrCorrMerge = 0.85; // Attraction to different planes correlation that is high enough to merge planes
public int plDiscrSteal = 4; // If offender has this number of tiles (including center) the cell can not be used
public int plDiscrGrown = 4; // Only use tiles within this range from original selection
public double plDiscrXMedian = 1.5; // Remove outliers from the final selection that have distance more than scaled median
// comparing merge quality for plane pairs
public double plCostKrq = 0.8; // cost of merge quality weighted in disparity space
......@@ -2232,7 +2241,7 @@ public class EyesisCorrectionParameters {
public boolean plFillSquares = true; // Add diagonals to full squares
public boolean plCutCorners = true; // Add ortho to 45-degree corners
public double plPull = .3; // Relative weight of original (measured) plane compared to average neighbor pull
public double plPull = 5.0; // .3; // Relative weight of original (measured) plane compared to average neighbor pull
// when combing with neighbors
public int plIterations = 10; // Maximal number of smoothing iterations for each step
public boolean plStopBad = true; // Do not update supertile if any of connected neighbors is not good (false: just skip that neighbor)
......@@ -2578,6 +2587,7 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"plWorstEq2", this.plWorstEq2 +"");
properties.setProperty(prefix+"plOKMergeEigen", this.plOKMergeEigen +"");
properties.setProperty(prefix+"plMaxWorldSin2", this.plMaxWorldSin2 +"");
properties.setProperty(prefix+"pl2dForSin", this.pl2dForSin +"");
properties.setProperty(prefix+"plWeakWorsening", this.plWeakWorsening +"");
properties.setProperty(prefix+"plMaxOverlap", this.plMaxOverlap +"");
......@@ -2585,12 +2595,14 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"plWeakEigen", this.plWeakEigen +"");
properties.setProperty(prefix+"plWeakWeight2", this.plWeakWeight2 +"");
properties.setProperty(prefix+"plWeakEigen2", this.plWeakEigen2 +"");
properties.setProperty(prefix+"plSumThick", this.plSumThick +"");
properties.setProperty(prefix+"plMaxZRatio", this.plMaxZRatio +"");
properties.setProperty(prefix+"plMaxDisp", this.plMaxDisp +"");
properties.setProperty(prefix+"plCutTail", this.plCutTail +"");
properties.setProperty(prefix+"plMinTail", this.plMinTail +"");
properties.setProperty(prefix+"plDiscrEn", this.plDiscrEn+"");
properties.setProperty(prefix+"plDiscrTolerance", this.plDiscrTolerance +"");
properties.setProperty(prefix+"plDiscrDispRange", this.plDiscrDispRange +"");
properties.setProperty(prefix+"plDiscrSteps", this.plDiscrSteps+"");
......@@ -2602,6 +2614,11 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"plDiscrExclusivity",this.plDiscrExclusivity +"");
properties.setProperty(prefix+"plDiscrExclus2", this.plDiscrExclus2 +"");
properties.setProperty(prefix+"plDiscrStrict", this.plDiscrStrict+"");
properties.setProperty(prefix+"plDiscrCorrMax", this.plDiscrCorrMax +"");
properties.setProperty(prefix+"plDiscrCorrMerge", this.plDiscrCorrMerge +"");
properties.setProperty(prefix+"plDiscrSteal", this.plDiscrSteal+"");
properties.setProperty(prefix+"plDiscrGrown", this.plDiscrGrown+"");
properties.setProperty(prefix+"plDiscrXMedian", this.plDiscrXMedian +"");
properties.setProperty(prefix+"plCostKrq", this.plCostKrq +"");
properties.setProperty(prefix+"plCostKrqEq", this.plCostKrqEq +"");
......@@ -2955,6 +2972,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"plWorstEq2")!=null) this.plWorstEq2=Double.parseDouble(properties.getProperty(prefix+"plWorstEq2"));
if (properties.getProperty(prefix+"plOKMergeEigen")!=null) this.plOKMergeEigen=Double.parseDouble(properties.getProperty(prefix+"plOKMergeEigen"));
if (properties.getProperty(prefix+"plMaxWorldSin2")!=null) this.plMaxWorldSin2=Double.parseDouble(properties.getProperty(prefix+"plMaxWorldSin2"));
if (properties.getProperty(prefix+"pl2dForSin")!=null) this.pl2dForSin=Double.parseDouble(properties.getProperty(prefix+"pl2dForSin"));
if (properties.getProperty(prefix+"plWeakWorsening")!=null) this.plWeakWorsening=Double.parseDouble(properties.getProperty(prefix+"plWeakWorsening"));
if (properties.getProperty(prefix+"plMaxOverlap")!=null) this.plMaxOverlap=Double.parseDouble(properties.getProperty(prefix+"plMaxOverlap"));
......@@ -2962,12 +2980,14 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"plWeakEigen")!=null) this.plWeakEigen=Double.parseDouble(properties.getProperty(prefix+"plWeakEigen"));
if (properties.getProperty(prefix+"plWeakWeight2")!=null) this.plWeakWeight2=Double.parseDouble(properties.getProperty(prefix+"plWeakWeight2"));
if (properties.getProperty(prefix+"plWeakEigen2")!=null) this.plWeakEigen2=Double.parseDouble(properties.getProperty(prefix+"plWeakEigen2"));
if (properties.getProperty(prefix+"plSumThick")!=null) this.plSumThick=Double.parseDouble(properties.getProperty(prefix+"plSumThick"));
if (properties.getProperty(prefix+"plMaxZRatio")!=null) this.plMaxZRatio=Double.parseDouble(properties.getProperty(prefix+"plMaxZRatio"));
if (properties.getProperty(prefix+"plMaxDisp")!=null) this.plMaxDisp=Double.parseDouble(properties.getProperty(prefix+"plMaxDisp"));
if (properties.getProperty(prefix+"plCutTail")!=null) this.plCutTail=Double.parseDouble(properties.getProperty(prefix+"plCutTail"));
if (properties.getProperty(prefix+"plMinTail")!=null) this.plMinTail=Double.parseDouble(properties.getProperty(prefix+"plMinTail"));
if (properties.getProperty(prefix+"plDiscrEn")!=null) this.plDiscrEn=Boolean.parseBoolean(properties.getProperty(prefix+"plDiscrEn"));
if (properties.getProperty(prefix+"plDiscrTolerance")!=null) this.plDiscrTolerance=Double.parseDouble(properties.getProperty(prefix+"plDiscrTolerance"));
if (properties.getProperty(prefix+"plDiscrDispRange")!=null) this.plDiscrDispRange=Double.parseDouble(properties.getProperty(prefix+"plDiscrDispRange"));
if (properties.getProperty(prefix+"plDiscrSteps")!=null) this.plDiscrSteps=Integer.parseInt(properties.getProperty(prefix+"plDiscrSteps"));
......@@ -2979,6 +2999,11 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"plDiscrExclusivity")!=null)this.plDiscrExclusivity=Double.parseDouble(properties.getProperty(prefix+"plDiscrExclusivity"));
if (properties.getProperty(prefix+"plDiscrExclus2")!=null) this.plDiscrExclus2=Double.parseDouble(properties.getProperty(prefix+"plDiscrExclus2"));
if (properties.getProperty(prefix+"plDiscrStrict")!=null) this.plDiscrStrict=Boolean.parseBoolean(properties.getProperty(prefix+"plDiscrStrict"));
if (properties.getProperty(prefix+"plDiscrCorrMax")!=null) this.plDiscrCorrMax=Double.parseDouble(properties.getProperty(prefix+"plDiscrCorrMax"));
if (properties.getProperty(prefix+"plDiscrCorrMerge")!=null) this.plDiscrCorrMerge=Double.parseDouble(properties.getProperty(prefix+"plDiscrCorrMerge"));
if (properties.getProperty(prefix+"plDiscrSteal")!=null) this.plDiscrSteal=Integer.parseInt(properties.getProperty(prefix+"plDiscrSteal"));
if (properties.getProperty(prefix+"plDiscrGrown")!=null) this.plDiscrGrown=Integer.parseInt(properties.getProperty(prefix+"plDiscrGrown"));
if (properties.getProperty(prefix+"plDiscrXMedian")!=null) this.plDiscrXMedian=Double.parseDouble(properties.getProperty(prefix+"plDiscrXMedian"));
if (properties.getProperty(prefix+"plCostKrq")!=null) this.plCostKrq=Double.parseDouble(properties.getProperty(prefix+"plCostKrq"));
if (properties.getProperty(prefix+"plCostKrqEq")!=null) this.plCostKrqEq=Double.parseDouble(properties.getProperty(prefix+"plCostKrqEq"));
......@@ -3360,6 +3385,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Worst case worsening for thin planes with equal weights", this.plWorstEq2, 6);
gd.addNumericField("If result of the merged planes is below, OK to use thin planes (higher) threshold ",this.plOKMergeEigen, 6);
gd.addNumericField("Maximal sine squared of the world angle between planes to merge. Set to >= 1.0 to disable", this.plMaxWorldSin2, 6);
gd.addNumericField("Do not compare sin() between planes, if at least one has too small axis ratio",this.pl2dForSin, 6);
gd.addNumericField("Relax merge requirements for weaker planes", this.plWeakWorsening, 6);
gd.addNumericField("Maximal overlap between the same supertile planes to merge", this.plMaxOverlap, 6);
......@@ -3368,6 +3394,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Maximal eigenvalue of the result of non-weighted merge (first variant)", this.plWeakEigen, 6);
gd.addNumericField("Maximal weight of the weak plane to merge (second variant)", this.plWeakWeight2, 6);
gd.addNumericField("Maximal eigenvalue of the result of non-weighted merge (second variant)", this.plWeakEigen2, 6);
gd.addNumericField("Do not merge if any sqrt of merged eigenvalue exceeds scaled sum of components", this.plSumThick, 6);
gd.addMessage ("--- ---");
gd.addNumericField("Maximal ratio of Z to allow plane merging", this.plMaxZRatio, 6);
......@@ -3376,6 +3403,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Set cutoff value livel not less than this", this.plMinTail, 6);
gd.addMessage ("--- Parameters to regenerate planes using preliminary tile connections ---");
gd.addCheckbox (" Enable planes tiles selection regeneration hinted by supertile neighbors", this.plDiscrEn);
gd.addNumericField("Maximal disparity difference from the plane to consider tile", this.plDiscrTolerance, 6);
gd.addNumericField("Parallel move known planes around original know value for the best overall fit",this.plDiscrDispRange, 6);
gd.addNumericField("Number of steps (each direction) for each plane to search for the best fit (0 - single, 1 - 1 each side)",this.plDiscrSteps, 0);
......@@ -3387,6 +3415,11 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Tile exclusivity: 1.0 - tile belongs to one plane only, 0.0 - regardless of others",this.plDiscrExclusivity, 6);
gd.addNumericField("For second pass if exclusivity > 1.0 - will assign only around strong neighbors",this.plDiscrExclus2, 6);
gd.addCheckbox ("When growing selection do not allow any offenders around (false - more these than others)", this.plDiscrStrict);
gd.addNumericField("Attraction to different planes correlation that is too high for re-discrimination",this.plDiscrCorrMax, 6);
gd.addNumericField("Attraction to different planes correlation that is high enough to merge", this.plDiscrCorrMerge, 6);
gd.addNumericField("If offender has this number of tiles (including center) the cell can not be used", this.plDiscrSteal, 0);
gd.addNumericField("Only use tiles within this range from original selection", this.plDiscrGrown, 0);
gd.addNumericField("Remove outliers from the final selection that have distance more than scaled median",this.plDiscrXMedian, 6);
gd.addMessage ("--- Planes merge costs ---");
gd.addNumericField("Cost of merge quality weighted in disparity space", this.plCostKrq, 6);
......@@ -3754,6 +3787,7 @@ public class EyesisCorrectionParameters {
this.plWorstEq2= gd.getNextNumber();
this.plOKMergeEigen= gd.getNextNumber();
this.plMaxWorldSin2= gd.getNextNumber();
this.pl2dForSin= gd.getNextNumber();
this.plWeakWorsening= gd.getNextNumber();
this.plMaxOverlap= gd.getNextNumber();
......@@ -3761,12 +3795,14 @@ public class EyesisCorrectionParameters {
this.plWeakEigen= gd.getNextNumber();
this.plWeakWeight2= gd.getNextNumber();
this.plWeakEigen2= gd.getNextNumber();
this.plSumThick= gd.getNextNumber();
this.plMaxZRatio= gd.getNextNumber();
this.plMaxDisp= gd.getNextNumber();
this.plCutTail= gd.getNextNumber();
this.plMinTail= gd.getNextNumber();
this.plDiscrEn= gd.getNextBoolean();
this.plDiscrTolerance= gd.getNextNumber();
this.plDiscrDispRange= gd.getNextNumber();
this.plDiscrSteps= (int) gd.getNextNumber();
......@@ -3778,6 +3814,11 @@ public class EyesisCorrectionParameters {
this.plDiscrExclusivity= gd.getNextNumber();
this.plDiscrExclus2= gd.getNextNumber();
this.plDiscrStrict= gd.getNextBoolean();
this.plDiscrCorrMax= gd.getNextNumber();
this.plDiscrCorrMerge= gd.getNextNumber();
this.plDiscrSteal= (int) gd.getNextNumber();
this.plDiscrGrown= (int) gd.getNextNumber();
this.plDiscrXMedian= gd.getNextNumber();
this.plCostKrq= gd.getNextNumber();
this.plCostKrqEq= gd.getNextNumber();
......
......@@ -43,6 +43,7 @@ public class LinkPlanes {
public double plOKMergeEigen; // = 0.03; // If result of the merged planes is below, OK to use thin planes (higher) threshold
public double plMaxWorldSin2; // = 0.1; // Maximal sine squared of the world angle between planes to merge. Set to >= 1.0 to disable
public double pl2dForSin; // = 2.5; // Do not compare sin() between planes, if at least one has too small axis ratio
public double plWeakWorsening; // = 1.0; // Relax merge requirements for weaker planes
public double plMaxOverlap; // = 0.1; // Maximal overlap between the same supertile planes to merge
......@@ -51,6 +52,7 @@ public class LinkPlanes {
public double plWeakEigen; // = 0.1; // Maximal eigenvalue of the result of non-weighted merge
public double plWeakWeight2; // = 10.0 ; // Maximal weight of the weak plane to merge (second variant)
public double plWeakEigen2; // = 0.05; // Maximal eigenvalue of the result of non-weighted merge (second variant)
public double plSumThick; // = 1.2; // Do not merge if any sqrt of merged eigenvalue exceeds scaled sum of components
// comparing merge quality for plane pairs
public double plCostKrq; // = 0.8; // cost of merge quality weighted in disparity space
......@@ -63,7 +65,7 @@ public class LinkPlanes {
public double plMaxZRatio; // = 2.5; // Maximal ratio of Z to allow plane merging
public double plMaxDisp; // = 0.5; // Maximal disparity of one of the planes to apply maximal ratio
public double plCutTail; // = 1.4; // When merging with neighbors cut the tail that is worse than scaled best
public double plMinTail; // = 0.015;// Set cutoff value livel not less than
public double plMinTail; // = 0.015;// Set cutoff value level not less than
public int dbg_tileX;
......@@ -82,6 +84,7 @@ public class LinkPlanes {
plWeakWorsening = clt_parameters.plWeakWorsening;
plOKMergeEigen = clt_parameters.plOKMergeEigen;
plMaxWorldSin2 = clt_parameters.plMaxWorldSin2;
pl2dForSin = clt_parameters.pl2dForSin;
plDispNorm = clt_parameters.plDispNorm;
plMaxEigen = clt_parameters.plMaxEigen;
......@@ -93,6 +96,7 @@ public class LinkPlanes {
plWeakEigen = clt_parameters.plWeakEigen;
plWeakWeight2 = clt_parameters.plWeakWeight2;
plWeakEigen2 = clt_parameters.plWeakEigen2;
plSumThick = clt_parameters.plSumThick;
plCostKrq = clt_parameters.plCostKrq;
plCostKrqEq = clt_parameters.plCostKrqEq;
......@@ -179,7 +183,7 @@ public class LinkPlanes {
double disp1 = plane1.getZxy()[0];
double disp2 = plane2.getZxy()[0];
if ((disp1 <= 0) || (disp2 <= 0) || (((disp1 <= plMaxDisp) || (disp2 <= plMaxDisp)) && ((disp1/disp2 > plMaxZRatio) || (disp2/disp1 > plMaxZRatio)))){
if (debugLevel > -1) System.out.println(prefix+" planes have too high disparity ratio ("+disp1+":"+disp2+" > plMaxZRatio="+plMaxZRatio+
if (debugLevel > 0) System.out.println(prefix+" planes have too high disparity ratio ("+disp1+":"+disp2+" > plMaxZRatio="+plMaxZRatio+
", at least one of them < plMaxDisp="+plMaxDisp);
return false;
} else {
......@@ -298,39 +302,73 @@ public class LinkPlanes {
boolean OK_to_merge = false;
boolean notOK_to_merge = false;
// plSumThick should override weak_and_close
double sum_thick = Math.sqrt(plane1.getValue()) + Math.sqrt(plane2.getValue());
double sum_wthick = Math.sqrt(plane1.getWValue()) + Math.sqrt(plane2.getWValue());
if (Math.sqrt(merged_ev) > plSumThick * sum_thick){
notOK_to_merge = true;
if (dbg) System.out.println(prefix+": planes do not fit as weighted pixel thickness = "+Math.sqrt(merged_ev_eq)+
" > " +plSumThick+" * "+ sum_thick+" = "+(plSumThick * sum_thick) );
}
if (Math.sqrt(merged_ev_eq) > plSumThick * sum_thick){
notOK_to_merge = true;
if (dbg) System.out.println(prefix+": planes do not fit as equalized pixel thickness = "+Math.sqrt(merged_ev_eq)+
" > " +plSumThick+" * "+ sum_thick+" = "+(plSumThick * sum_thick) );
}
if (Math.sqrt(merged_wev) > plSumThick * sum_wthick){
notOK_to_merge = true;
if (dbg) System.out.println(prefix+": planes do not fit as weighted world thickness = "+Math.sqrt(merged_wev)+
" > " +plSumThick+" * "+ sum_wthick+" = "+(plSumThick * sum_wthick) );
}
if (Math.sqrt(merged_wev_eq) > plSumThick*sum_wthick){
notOK_to_merge = true;
if (dbg) System.out.println(prefix+": planes do not fit as equalized world thickness = "+Math.sqrt(merged_wev_eq)+
" > " +plSumThick+" * "+ sum_wthick+" = "+(plSumThick * sum_wthick) );
}
if (this_rq_norm <= plWorstWorsening){
if (notOK_to_merge) {
weak_and_close = false;
}
if (!notOK_to_merge && (this_rq_norm <= plWorstWorsening)){
OK_to_merge = true;
if (dbg) System.out.println(prefix+": planes may fit (this_rq_norm="+this_rq_norm+" <= plWorstWorsening="+plWorstWorsening+")");
}
if ((!OK_to_merge || dbg) && (merged_ev <= plOKMergeEigen) && (this_rq_norm <= plWorstWorsening2)){
if (!notOK_to_merge && (!OK_to_merge || dbg) && (merged_ev <= plOKMergeEigen) && (this_rq_norm <= plWorstWorsening2)){
OK_to_merge = true;
if (dbg) System.out.println(prefix+": planes may fit (merged_ev="+merged_ev+
" <= plOKMergeEigen="+plOKMergeEigen+") && (this_rq_norm="+this_rq_norm+
" <= plWorstWorsening2="+plWorstWorsening2+")");
}
if ((!OK_to_merge || dbg) && (this_rq_eq_norm <= plWorstEq)){
if (!notOK_to_merge && (!OK_to_merge || dbg) && (this_rq_eq_norm <= plWorstEq)){
OK_to_merge = true;
if (dbg) System.out.println(prefix+": planes may fit (this_rq_eq_norm="+this_rq_eq_norm+" <= plWorstEq="+plWorstEq+")");
}
if ((!OK_to_merge || dbg) && (merged_ev_eq <= plOKMergeEigen) && (this_rq_eq_norm <= plWorstEq2)){
if (!notOK_to_merge && (!OK_to_merge || dbg) && (merged_ev_eq <= plOKMergeEigen) && (this_rq_eq_norm <= plWorstEq2)){
OK_to_merge = true;
if (dbg) System.out.println(prefix+": planes may fit (merged_ev_eq="+merged_ev_eq+" <= plOKMergeEigen) && (this_rq_eq_norm="+
this_rq_eq_norm+" <= plWorstEq2="+plWorstEq2+")");
}
if ((!OK_to_merge || dbg) && (this_wrq_norm <= plWorstWorsening)){
if (!notOK_to_merge && (!OK_to_merge || dbg) && (this_wrq_norm <= plWorstWorsening)){
OK_to_merge = true;
if (dbg) System.out.println(prefix+": planes may fit (this_wrq_norm="+this_wrq_norm+" <= plWorstWorsening="+plWorstWorsening+")");
}
if ((!OK_to_merge || dbg) && (this_wrq_eq_norm <= plWorstEq)){
if (!notOK_to_merge && (!OK_to_merge || dbg) && (this_wrq_eq_norm <= plWorstEq)){
OK_to_merge = true;
if (dbg) System.out.println(prefix+": planes may fit (this_wrq_eq_norm="+this_wrq_eq_norm+" <= plWorstEq="+plWorstEq+")");
}
// do not apply sin2 to weak planes
if ((plMaxWorldSin2 < 1.0) && (weakest > plWeakWeight) && (plane1.getWorldSin2(plane2) > plMaxWorldSin2)) {
// do not apply sin2 to weak planes or if they are not flat enough
// TODO: Compare what can be compared (for 2 linear features or plane + linear?
double min2d = Math.min(plane1.get2dRatio(), plane2.get2dRatio());
if (Double.isNaN(min2d)) min2d = pl2dForSin;
if ((plMaxWorldSin2 < 1.0) && (min2d >= pl2dForSin) && (!merge_weak || (weakest > plWeakWeight)) && (plane1.getWorldSin2(plane2) > plMaxWorldSin2)) {
notOK_to_merge = true;
if (dbg) System.out.println(prefix+": planes do not fit as sin2 > "+plMaxWorldSin2+" weakest="+weakest);
if (dbg) System.out.println(prefix+": planes do not fit as sin2 > "+plMaxWorldSin2+" weakest="+weakest+
" or minimal 2d = "+min2d+" >= pl2dForSin=" + pl2dForSin);
}
if (weak_and_close){
OK_to_merge = true;
......@@ -521,7 +559,7 @@ public class LinkPlanes {
if (debugLevel > 0){
System.out.println(prefix+" cost="+cost);
if (debugLevel > 1){
System.out.println(prefix+ "cost contributions: "+
System.out.println(prefix+ " cost contributions: "+
((int)(100*qualities[3]))+"%, "+
((int)(100*qualities[4]))+"%, "+
((int)(100*qualities[5]))+"%, "+
......@@ -792,7 +830,7 @@ public class LinkPlanes {
if (planesFit(
planes[nsTile0][np0], // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
planes[nsTile][np], // TilePlanes.PlaneData plane2,
merge_low_eigen, // false, // boolean merge_weak, // use for same supertile merge
true, // merge_low_eigen, // false, // boolean merge_weak, // use for same supertile merge
merge_ev[np], // double merged_ev, // if NaN will calculate assuming the same supertile
merge_ev_eq[np], //double merged_ev_eq, // if NaN will calculate assuming the same supertile
merge_wev[np], // double merged_wev, // if NaN will calculate assuming the same supertile - for world
......@@ -802,6 +840,20 @@ public class LinkPlanes {
){
planes[nsTile0][np0].setMergedValid(dir, np, true, planes[nsTile].length);
planes[nsTile][np].setMergedValid((dir + 4) %8, np0, true, planes[nsTile0].length);
if (planesFit(
planes[nsTile0][np0], // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
planes[nsTile][np], // TilePlanes.PlaneData plane2,
false, // merge_low_eigen, // false, // boolean merge_weak, // use for same supertile merge
merge_ev[np], // double merged_ev, // if NaN will calculate assuming the same supertile
merge_ev_eq[np], //double merged_ev_eq, // if NaN will calculate assuming the same supertile
merge_wev[np], // double merged_wev, // if NaN will calculate assuming the same supertile - for world
merge_wev_eq[np], // double merged_wev_eq, // if NaN will calculate assuming the same supertile - for world
prefix, // String prefix,
dl) // int debugLevel)
){
planes[nsTile0][np0].setMergedStrongValid(dir, np, true, planes[nsTile].length);
planes[nsTile][np].setMergedStrongValid((dir + 4) %8, np0, true, planes[nsTile0].length);
}
}
}
}
......@@ -1653,7 +1705,7 @@ public class LinkPlanes {
if (valid_candidates[nsTile0][np1][np2]) { // only check pair considered valid
boolean [] old_valid = new boolean[8];
for (int dir = 0; dir < 8; dir++){
old_valid[dir] = planes[nsTile0][np1].hasMergedValid(dir) || planes[nsTile0][np2].hasMergedValid(dir);
old_valid[dir] = planes[nsTile0][np1].hasMergedStrongValid(dir) || planes[nsTile0][np2].hasMergedStrongValid(dir);
}
// should be merged same way as later actually. Does it need to be recalculated from the original tiles?
TilePlanes.PlaneData merged_pd = planes[nsTile0][np1].mergePlaneToThis(
......@@ -2313,8 +2365,10 @@ public class LinkPlanes {
}
groups_list.add(sub_group);
} else {
System.out.println("====== BUG: extractMergeSameTileGroups() nsTile = "+nsTile+" : found incomplete group: "+group+""
+ "best_pair = null");
System.out.println("===== All remaining planes are incompatible to each other: extractMergeSameTileGroups() nsTile = "+nsTile+" : found incomplete group: "+group+""
+ " best_pair = null");
break; // all remaining planes are incompatible to each other
}
}
......
......@@ -637,7 +637,7 @@ public class MeasuredLayers {
* 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
* and 3 - vertical pairs correlation
* @param stX supertile horizontal index
* @param stY supertile vertical index
* @param sel_in input selection of the output data samples (or null)
......
......@@ -29,14 +29,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicInteger;
//import java.awt.Point;
//import java.util.ArrayList;
//import TilePlanes.PlaneData;
//import TilePlanes.PlaneData;
public class SuperTiles{
TileProcessor tileProcessor;
double step_far;
......@@ -1996,13 +1988,17 @@ public class SuperTiles{
final int plDiscrVariants, // = 100; // Total number of variants to try (protect from too many planes)
final int plDiscrMode, // = 3; // What plane to use as a hint: 0 - weighted, 1 - equalized, 2 - best, 3 - combined
final double plDiscrVarFloor, // = 0.03; // Squared add to variance to calculate reverse flatness (used mostly for single-cell clusters)
final double plDiscrSigma, // = 0.05; // Gaussian sigma to compare how measured data is attracted to planes
final double plDiscrBlur, // = 0.1; // Sigma to blur histograms while re-discriminating
final double plDiscrVarFloor, // = 0.03; // Squared add to variance to calculate reverse flatness (used mostly for single-cell clusters)
final double plDiscrSigma, // = 0.05; // Gaussian sigma to compare how measured data is attracted to planes
final double plDiscrBlur, // = 0.1; // Sigma to blur histograms while re-discriminating
final double plDiscrExclusivity, // = 1.5; // Tile exclusivity: 1.0 - tile belongs to one plane only, 0.0 - regardless of others
final double plDiscrExclus2, // = 0.8; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
final boolean plDiscrStrict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
final double plDiscrExclus2, // = 0.8; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
final boolean plDiscrStrict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
final double plDiscrCorrMax, // = 0.7; // Attraction to different planes correlation that is too high for re-discrimination.
final double plDiscrCorrMerge, // = 0.85; // Attraction to different planes correlation that is high enough to merge planes
final int plDiscrSteal, // = 4; // If offender has this number of tiles (including center) the cell can not be used
final int plDiscrGrown, // = 0; // Only use tiles within this range from original selection
final double plDiscrXMedian, // = 1.5; // Remove outliers from the final selection that have distance more than scaled median
final int debugLevel,
final int dbg_X,
final int dbg_Y)
......@@ -2018,7 +2014,7 @@ public class SuperTiles{
final int nStiles = stilesX * stilesY;
final TilePlanes tpl = new TilePlanes(tileSize,superTileSize, geometryCorrection);
final Thread[] threads = ImageDtt.newThreadArray((debugLevel > 1)? 1 : 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;
......@@ -2031,56 +2027,116 @@ public class SuperTiles{
if (dl > 1){
System.out.println("refineDiscriminateTiles() selecting: nsTile="+nsTile);
}
int stileY = nsTile / stilesX;
int stileX = nsTile % stilesX;
int [] sTiles = {stileX, stileY};
TilePlanes.PlaneData pd0 = tpl.new PlaneData (
sTiles, // int [] sTileXY,
tileSize, // int tileSize,
geometryCorrection, // GeometryCorrection geometryCorrection,
correct_distortions,
measuredLayers, // MeasuredLayers measuredLayers,
plPreferDisparity); // boolean preferDisparity)
/*
planes_selections[nsTile] = pd0.reDiscriminateTiles_0(
""+nsTile, // String prefix,
planes[nsTile], // final PlaneData [] planes,
stMeasSel, // final int stMeasSel, // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
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
if (planes[nsTile] != null) {
int stileY = nsTile / stilesX;
int stileX = nsTile % stilesX;
int [] sTiles = {stileX, stileY};
TilePlanes.PlaneData pd0 = tpl.new PlaneData (
sTiles, // int [] sTileXY,
tileSize, // int tileSize,
geometryCorrection, // GeometryCorrection geometryCorrection,
correct_distortions,
measuredLayers, // MeasuredLayers measuredLayers,
plPreferDisparity); // boolean preferDisparity)
TilePlanes.PlaneData [] these_planes = planes[nsTile].clone(); // null pointer
for (int ntry = 0; ntry < planes[nsTile].length; ntry ++) { // can be while(true), just for debugging
int [] merge_planes = {-1, -1};
planes_selections[nsTile] = pd0.reDiscriminateTiles(
""+nsTile, // String prefix,
these_planes, //planes[nsTile], // final PlaneData [] planes,
merge_planes, // final int [] merge_planes, // indices of planes suggested to be merged
stMeasSel, // final int stMeasSel, // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
plDispNorm, // final double dispNorm, // Normalize disparities to the average if above
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
plDiscrTolerance, // final double disp_tolerance, // maximal disparity difference from the plane to consider tile
plDiscrVarFloor, // final double disp_var_floor, // squared add to variance to calculate reverse flatness (used mostly for single-cell clusters)
plDiscrSigma, // final double disp_sigma, // G.sigma to compare how measured data is attracted to planes
plDiscrDispRange, // final double disp_range, // parallel move known planes around original know value for the best overall fit
plDiscrSteps, // final int amplitude_steps, // number of steps (each direction) for each plane to search for the best fit (0 - single, 1 - 1 each side)
plDiscrBlur, // final double hist_blur, // Sigma to blur histogram
plDiscrExclusivity, // final double exclusivity, // 1.0 - tile belongs to one plane only, 0.0 - regardless of others
plDiscrExclus2, // final double excluisivity2, // = 0.8; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
plDiscrStrict, // final boolean exclusivity_strict// = true; // When growing selection do not allow any offenders around (false - more these than others)
plDiscrCorrMax, // final double plDiscrCorrMax, // = 0.7; // Attraction to different planes correlation that is too high for re-discrimination.
plDiscrCorrMerge, // final double attractionCorrMerge, // = 0.85; // Attraction to different planes correlation that is high enough to merge planes
plDiscrSteal, // final int plDiscrSteal, // = 4; // If offender has this number of tiles (including center) the cell can not be used
plDiscrGrown, // final int plDiscrGrown, // = 0; // Only use tiles within this range from original selection
plDiscrXMedian, // final double outliersXMedian, // = 1.5; // Remove outliers from the final selection that have distance more than scaled median
plDiscrMode, // final int mode, // 0 - weighted, 1 - equalized, 2 - best, 3 - combined
dl); // debugLevel); // final int debugLevel)
if ((planes_selections[nsTile] != null) || (merge_planes[0] < 0)){ // either OK, or does not know what to do (keep old)
break;
}
// merging suggested plane pair
if (debugLevel > -1) {
System.out.println("refineDiscriminateTiles(): nsTile="+nsTile+" merging pair ["+merge_planes[0]+","+merge_planes[1]+"]");
}
TilePlanes.PlaneData [] new_planes = new TilePlanes.PlaneData [these_planes.length -1];
int np1 = 0;
for (int np = 0; np < these_planes.length; np++) {
if (np != merge_planes[1]){
new_planes[np1++] = these_planes[np];
}
}
TilePlanes.PlaneData plane1 = these_planes[merge_planes[0]].mergePlaneToThis(
these_planes[merge_planes[1]], // PlaneData otherPd,
1.0, // double scale_other,
1.0, // double starWeightPwr, // Use this power of tile weight when calculating connection cost
false, // boolean ignore_weights,
true, // boolean sum_weights,
these_planes[merge_planes[0]].getPreferDisparity(), // preferDisparity,
dl-1); // int debugLevel)
// combine tile selection - if next time pd0.reDiscriminateTiles() will fail, it will
// use old selections, we need to provide them (otherwise will use selection from the first plane)
plane1.orMeasSelection(these_planes[merge_planes[1]].getMeasSelection());
plDiscrTolerance, // final double max_disp_diff, // maximal disparity difference from the plane to consider tile
plDiscrDispRange, // final double disp_range, // parallel move known planes around original know value for the best overall fit
plDiscrSteps, // final int amplitude_steps, // number of steps (each direction) for each plane to search for the best fit (0 - single, 1 - 1 each side)
plDiscrVariants, // final int num_variants, // total number of variants to try (protect from too many planes)
plDiscrMode, // final int mode, // 0 - weighted, 1 - equalized, 2 - best, 3 - combined
dl); // debugLevel); // final int debugLevel)
*/
planes_selections[nsTile] = pd0.reDiscriminateTiles(
""+nsTile, // String prefix,
planes[nsTile], // final PlaneData [] planes,
stMeasSel, // final int stMeasSel, // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
plDispNorm, // final double dispNorm, // Normalize disparities to the average if above
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
// separately merge corresponding nonexclusiveStar and nonexclusiveStarEq of these planes - kit is not exact,
// but is needed just for a hint and is compatible with multithreading without recalculating other planes
plDiscrTolerance, // final double disp_tolerance, // maximal disparity difference from the plane to consider tile
plDiscrVarFloor, // final double disp_var_floor, // squared add to variance to calculate reverse flatness (used mostly for single-cell clusters)
plDiscrSigma, // final double disp_sigma, // G.sigma to compare how measured data is attracted to planes
plDiscrDispRange, // final double disp_range, // parallel move known planes around original know value for the best overall fit
plDiscrSteps, // final int amplitude_steps, // number of steps (each direction) for each plane to search for the best fit (0 - single, 1 - 1 each side)
plDiscrBlur, // final double hist_blur, // Sigma to blur histogram
plDiscrExclusivity, // final double exclusivity, // 1.0 - tile belongs to one plane only, 0.0 - regardless of others
plDiscrExclus2, // final double excluisivity2, // = 0.8; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
plDiscrStrict, // final boolean exclusivity_strict// = true; // When growing selection do not allow any offenders around (false - more these than others)
plDiscrMode, // final int mode, // 0 - weighted, 1 - equalized, 2 - best, 3 - combined
dl); // debugLevel); // final int debugLevel)
TilePlanes.PlaneData plane1Ex = these_planes[merge_planes[0]].getNonexclusiveStar();
if (plane1Ex == null) plane1Ex = these_planes[merge_planes[0]];
TilePlanes.PlaneData plane1ExEq = these_planes[merge_planes[0]].getNonexclusiveStarEq();
if (plane1ExEq == null) plane1ExEq = these_planes[merge_planes[0]];
TilePlanes.PlaneData plane2Ex = these_planes[merge_planes[1]].getNonexclusiveStar();
if (plane2Ex == null) plane2Ex = these_planes[merge_planes[1]];
TilePlanes.PlaneData plane2ExEq = these_planes[merge_planes[1]].getNonexclusiveStarEq();
if (plane2ExEq == null) plane2ExEq = these_planes[merge_planes[1]];
TilePlanes.PlaneData plane1NonExcl = plane1Ex.mergePlaneToThis(
plane2Ex, // PlaneData otherPd,
1.0, // double scale_other,
1.0, // double starWeightPwr, // Use this power of tile weight when calculating connection cost
false, // boolean ignore_weights,
true, // boolean sum_weights,
these_planes[merge_planes[0]].getPreferDisparity(), // preferDisparity,
dl-2); // int debugLevel)
TilePlanes.PlaneData plane1NonExclEq = plane1ExEq.mergePlaneToThis(
plane2ExEq, // PlaneData otherPd,
1.0, // double scale_other,
1.0, // double starWeightPwr, // Use this power of tile weight when calculating connection cost
true, // boolean ignore_weights,
true, // boolean sum_weights,
these_planes[merge_planes[0]].getPreferDisparity(), // preferDisparity,
dl-2); // int debugLevel)
plane1.setNonexclusiveStar (plane1NonExcl);
plane1.setNonexclusiveStarEq(plane1NonExclEq);
new_planes[merge_planes[0]] = plane1;
if (dl > 1){
System.out.println("First plane ("+merge_planes[0]+"):\n"+(these_planes[merge_planes[0]].toString()));
System.out.println("Second plane ("+merge_planes[1]+"):\n"+(these_planes[merge_planes[1]].toString()));
System.out.println("combined plane:\n"+(plane1.toString()));
}
these_planes = new_planes.clone();
}
}
}
}
};
......@@ -2416,7 +2472,13 @@ public class SuperTiles{
final double plDiscrBlur, // = 0.1; // Sigma to blur histograms while re-discriminating
final double plDiscrExclusivity, // = 1.5; // Tile exclusivity: 1.0 - tile belongs to one plane only, 0.0 - regardless of others
final double plDiscrExclus2, // = 0.8; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
final boolean plDiscrStrict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
final boolean plDiscrStrict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
final double plDiscrCorrMax, // = 0.7; // Attraction to different planes correlation that is too high for re-discrimination.
final double plDiscrCorrMerge, // = 0.85; // Attraction to different planes correlation that is high enough to merge planes
final int plDiscrSteal, // = 4; // If offender has this number of tiles (including center) the cell can not be used
final int plDiscrGrown, // = 0; // Only use tiles within this range from original selection
final double plDiscrXMedian, // = 1.5; // Remove outliers from the final selection that have distance more than scaled median
final int debugLevel,
final int dbg_X,
final int dbg_Y)
......@@ -2452,7 +2514,14 @@ public class SuperTiles{
plDiscrBlur, // final double plDiscrBlur, // = 0.1; // Sigma to blur histograms while re-discriminating
plDiscrExclusivity,// final double plDiscrExclusivity, // = 0.5; // Tile exclusivity: 1.0 - tile belongs to one plane only, 0.0 - regardless of others
plDiscrExclus2, // final double plDiscrExclus2, // = 0.5; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
plDiscrStrict, // final boolean plDiscrStrict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
plDiscrStrict, // final boolean plDiscrStrict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
plDiscrCorrMax, // final double plDiscrCorrMax, // = 0.7; // Attraction to different planes correlation that is too high for re-discrimination.
plDiscrCorrMerge, // final double plDiscrCorrMerge, // = 0.85; // Attraction to different planes correlation that is high enough to merge planes
plDiscrSteal, // final int plDiscrSteal, // = 4; // If offender has this number of tiles (including center) the cell can not be used
plDiscrGrown, // final int plDiscrGrown, // = 0; // Only use tiles within this range from original selection
plDiscrXMedian, //final double plDiscrXMedian, // = 1.5; // Remove outliers from the final selection that have distance more than scaled median
2, // debugLevel, // final int debugLevel,
dbg_X, // final int dbg_X,
dbg_Y); // final int dbg_Y)
......@@ -2498,8 +2567,11 @@ public class SuperTiles{
debugLevel + 2, // 1, // final int debugLevel,
dbg_X, // final int dbg_X,
dbg_Y); // final int dbg_Y)
this.planes = new_planes; // save as "measured" (as opposed to "smoothed" by neighbors) planes
// combine old and new planes (refineDiscriminateTiles will return null for the supertile if failed to re-disciminate)
for (int nsTile = 0; nsTile < this.planes.length; nsTile++){
this.planes[nsTile] = (new_planes[nsTile] != null) ? new_planes[nsTile] : planes[nsTile];
}
}
......@@ -5640,6 +5712,7 @@ public class SuperTiles{
}
public TilePlanes.PlaneData[][] planesSmooth(
final LinkPlanes lp,
final double meas_pull,// relative pull of the original (measured) plane with respect to the average of the neighbors
final double maxValue, // do not combine with too bad planes with primary eigenvalue above this value ( 0 any OK)
final int num_passes,
......@@ -5657,6 +5730,7 @@ public class SuperTiles{
}
for (int pass = 0; pass < num_passes; pass++){
double diff = planesSmoothStep(
lp, // LinkPlanes lp,
meas_pull, // relative pull of the original (measured) plane with respect to the average of the neighbors
maxValue, // final double maxValue, // do not combine with too bad planes
stopBadNeib, // do not update supertile if any of connected neighbors is not good (false: just skip that neighbor)
......@@ -5683,8 +5757,9 @@ public class SuperTiles{
}
public double planesSmoothStep(
final LinkPlanes lp,
final double meas_pull,// relative pull of the original (measured) plane with respect to the average of the neighbors
final double maxValue, // do not combine with too bad planes
final double maxValue, // do not combine with too bad planes, do not merge if result is above
final boolean stopBadNeib, // do not update supertile if any of connected neighbors is not good (false: just skip that neighbor)
final double normPow,
final TilePlanes.PlaneData[][] measured_planes,
......@@ -5738,8 +5813,50 @@ public class SuperTiles{
}
if (dl > 0) dbg_img[ 0] = this_new_plane.getSinglePlaneDisparity(false);
if (dl > 0) dbg_img[ 1] = measured_planes[nsTile0][np0].getSinglePlaneDisparity(false);
int [] neibs = this_new_plane.getNeibBest();
double [][] costs = new double[neibs.length][];
double [] weights = new double[neibs.length];
int cost_index = 1;
double sum_rcosts = 0.0;
int non_zero = 0;
for (int dir = 0; dir < neibs.length; dir++) if (neibs[dir] >= 0) {
int stx = stx0 + dirsYX[dir][1];
int sty = sty0 + dirsYX[dir][0];
int nsTile = sty * stilesX + stx; // from where to get
TilePlanes.PlaneData other_plane = this_new_plane.getPlaneToThis(
mod_planes[nsTile][neibs[dir]], // neighbor, previous value
dl - 1); // debugLevel);
costs[dir] = lp.getFitQualities(
this_new_plane, // TilePlanes.PlaneData plane1, // should belong to the same supertile (or be converted for one)
other_plane, // TilePlanes.PlaneData plane2,
Double.NaN, // double merged_ev, // if NaN will calculate assuming the same supertile
Double.NaN, // double merged_ev_eq, // if NaN will calculate assuming the same supertile
Double.NaN, // double merged_wev, // if NaN will calculate assuming the same supertile - for world
Double.NaN, // double merged_wev_eq, // if NaN will calculate assuming the same supertile - for world
nsTile0+":"+np0+"-"+dir, // String prefix,
0); // int debugLevel)
for (int i = 3; i < costs[dir].length; i++) costs[dir][i] *= costs[dir][2];
non_zero ++;
weights[dir] = 1.0/costs[dir][cost_index];
sum_rcosts += weights[dir];
}
for (int dir = 0; dir < neibs.length; dir++) if (neibs[dir] >= 0) {
weights[dir] *= non_zero/sum_rcosts; // average weight fcor active links will be 1.0
}
if (dl > 0) {
for (int dir = 0; dir <8; dir++)if (costs[dir] != null){
System.out.print(nsTile0+":"+np0+"-"+dir+" "+String.format(" weight= %6.3f ",weights[dir]));
for (int i = 0; i < costs[dir].length; i++){
System.out.print(String.format("%8.3f", costs[dir][i]));
// if (i < 3) System.out.print(String.format("%8.3f", costs[dir][i]));
// else System.out.print(String.format("%8.3f", costs[dir][i]*costs[dir][2]));
}
System.out.println();
}
System.out.println();
}
this_new_plane.setWeight(0.0); //
double num_merged = 0.0; // double to add fractional pull weight of the center
for (int dir = 0; dir < neibs.length; dir++){
......@@ -5751,27 +5868,30 @@ public class SuperTiles{
mod_planes[nsTile][neibs[dir]], // neighbor, previous value
dl - 1); // debugLevel);
if (dl > 0) dbg_img[ 2 + dir] = other_plane.getSinglePlaneDisparity(false);
if ((other_plane != null) && ((other_plane.getValue() <= maxValue) || (maxValue == 0))) {
if ((other_plane != null) && ((other_plane.getValue() <= maxValue) || (maxValue == 0))) { // TODO:
if (this_new_plane.getWeight() > 0.0){
this_new_plane = this_new_plane.mergePlaneToThis(
other_plane, // PlaneData otherPd,
1.0, // double scale_other,
weights[dir], // 1.0, // double scale_other,
// here it should be no power function for the weights
1.0, // double starWeightPwr, // Use this power of tile weight when calculating connection cost
false, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
dl - 1); // int debugLevel)
if (this_new_plane != null){
num_merged += 1.0;
}
} else {
this_new_plane = other_plane;
this_new_plane = other_plane; // should increment num_merged
this_new_plane.scaleWeight(weights[dir]);
}
if (this_new_plane != null){
num_merged += 1.0;
// just for debug / calculate
this_new_plane.getWorldXYZ(0);
}
new_planes[nsTile0][np0] = this_new_plane;
if (dl > 0) dbg_img[10 + dir] = this_new_plane.getSinglePlaneDisparity(false);
} else if (stopBadNeib){
} else if (stopBadNeib){ // just skip, not abandon? (set to false)
this_new_plane = null;
break;
}
......@@ -5816,13 +5936,16 @@ public class SuperTiles{
}
if ((num_merged > 0.0) && (this_new_plane != null)){
this_new_plane.scaleWeight(1.0/num_merged);
double true_num_merged = num_merged - meas_pull + 1;
this_new_plane.setNumPoints((int) (this_new_plane.getNumPoints()/true_num_merged));
}
// Revert if the result value is higher than imposed maximum
if ((this_new_plane.getValue() > maxValue) && (maxValue != 0)){
if ((this_new_plane.getValue() > maxValue) && (maxValue != 0)){ // TODO: Set more relaxed here?
this_new_plane = mod_planes[nsTile0][np0].clone();
new_planes[nsTile0][np0] = this_new_plane;
}
// just for debug / calculate
this_new_plane.getWorldXYZ(0);
// calculate largest disparity difference between old and new plane
if (rslt_diffs != null){ // filter out outliers here?
// get plane for both old and new, calc rms of diff
......@@ -5851,7 +5974,7 @@ public class SuperTiles{
if (debugLevel > -1) {
// if ((s > 5.0) || (dl > 0)){
if ((s > 5.0) || (dl > 0)){
System.out.println("planesSmoothStep() nsTile0="+nsTile0+
System.out.println("planesSmoothStep() nsTile0="+nsTile0+":"+np0+
" num_merged="+num_merged + " rms = "+s+
" new_weight = "+new_planes[nsTile0][np0].getWeight()+
" old_weight = "+mod_planes[nsTile0][np0].getWeight()+
......
......@@ -21,6 +21,7 @@
** -----------------------------------------------------------------------------**
**
*/
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
......@@ -68,6 +69,8 @@ public class TilePlanes {
double [][] merged_eig_val = null; // for each of the directions (N, NE, .. NW) quality match for each layer
double [][] merged_eig_eq = null; // for each of the directions (N, NE, .. NW) quality match for each layer - ignoring weights
boolean [][] merged_valid = null; // for each of the directions (N, NE, .. NW) if it is possible to connect with link swaps
boolean [][] merged_strong_valid = null; // for each of the directions (N, NE, .. NW) if it is possible to connect with link swaps (no "discounts"
// for low weight(s)
int [] neib_best = null; // new int [8]; // for each of the directions (N, NE, .. NW) index of best match, -1 if none
// stores "worsening" of merging 2 planes. if L1,L2,L = values[0] of plane1, plane2 plane composite: w1, w2 - weights for plane1, plane2
......@@ -108,7 +111,7 @@ public class TilePlanes {
double [][] merged_weig_val = null; // for each of the directions (N, NE, .. NW) quality match for each layer
double [][] merged_weig_eq = null; // for each of the directions (N, NE, .. NW) quality match for each layer - ignoring weights
int mark0 = -1; // just for temporary labeling the plane
public PlaneData clone(){
PlaneData pd = new PlaneData(
......@@ -177,9 +180,22 @@ public class TilePlanes {
pd.wvectors[1] = this.wvectors[1].clone();
pd.wvectors[2] = this.wvectors[2].clone();
}
pd.mark0 = this.mark0;
return pd;
}
public int getMark0(){
return this.mark0;
}
public void setMark0(int mark0){
this.mark0 = mark0;
}
public boolean getPreferDisparity(){
return this.preferDisparity;
}
public String getNeibString()
{
if (neib_best == null) {
......@@ -200,6 +216,10 @@ public class TilePlanes {
}
return false;
}
public double get2dRatio(){
if (wvalues != null) return Math.sqrt(wvalues[1]/wvalues[0]);
return Double.NaN;
}
public String toString()
{
......@@ -208,11 +228,13 @@ public class TilePlanes {
if (isHorizontal()){
s+= "HORIZONTAL ";
}
s += String.format("2d=%4.1f ", get2dRatio());
s += String.format( "np=%3d weight= %8.5f", num_points, weight);
if (starValueWeight != null) s += String.format(" star=[%8.5f, %8.5f]", starValueWeight[0], starValueWeight[1]);
else s += " star= null";
s += String.format(" dens=%8.5f", conn_density);
if (zxy != null) s += String.format("\nzxy = [%8.3f, %8.3f, %8.3f] (pix)",zxy[0],zxy[1],zxy[2]);
double [] px_py = getCenterPxPy();
if (zxy != null) s += String.format("\nzxy = [%8.3f, %8.3f, %8.3f] (pix)",zxy[0],zxy[1]+px_py[0],zxy[2]+px_py[1]);
else s += "\nzxy = null";
if (values != null) s += String.format(", values = [%8.3f, %8.3f, %8.3f] pix^2",values[0],values[1],values[2]);
else s += " values = null";
......@@ -234,9 +256,13 @@ public class TilePlanes {
if (nonexclusiveStar.isHorizontal()){
s+= "HORIZONTAL ";
}
s += String.format("2d=%4.1f ", nonexclusiveStar.get2dRatio());
s += String.format( "np=%3d weight= %8.5f", nonexclusiveStar.num_points, nonexclusiveStar.weight);
double [] ne_px_py = getCenterPxPy();
if (nonexclusiveStar.center_xyz != null) s += String.format("\n--center =[%8.2f, %8.2f, %8.2f]",
nonexclusiveStar.center_xyz[0],nonexclusiveStar.center_xyz[1],nonexclusiveStar.center_xyz[2]);
nonexclusiveStar.center_xyz[0],
nonexclusiveStar.center_xyz[1], // + ne_px_py[0],
nonexclusiveStar.center_xyz[2]); // + ne_px_py[1]);
else s += "\n--ncenter = null";
if (nonexclusiveStar.world_xyz != null) s += String.format(" normal = [%8.2f, %8.2f, %8.2f] (m)",
nonexclusiveStar.world_xyz[0],nonexclusiveStar.world_xyz[1],nonexclusiveStar.world_xyz[2]);
......@@ -245,12 +271,16 @@ public class TilePlanes {
if (nonexclusiveStarEq != null){
s+= "\nequalized:";
s+= nonexclusiveStarEq.getNeibString();
if (nonexclusiveStar.isHorizontal()){
if (nonexclusiveStarEq.isHorizontal()){
s+= "HORIZONTAL ";
}
s += String.format("2d=%4.1f ", nonexclusiveStarEq.get2dRatio());
s += String.format( "np=%3d weight= %8.5f", nonexclusiveStarEq.num_points, nonexclusiveStarEq.weight);
double [] ne_px_py = getCenterPxPy();
if (nonexclusiveStarEq.center_xyz != null) s += String.format("\n--center =[%8.2f, %8.2f, %8.2f]",
nonexclusiveStarEq.center_xyz[0],nonexclusiveStarEq.center_xyz[1],nonexclusiveStarEq.center_xyz[2]);
nonexclusiveStarEq.center_xyz[0],
nonexclusiveStarEq.center_xyz[1], // + ne_px_py[0],
nonexclusiveStarEq.center_xyz[2]); // + ne_px_py[1]);
else s += "\n--ncenter = null";
if (nonexclusiveStarEq.world_xyz != null) s += String.format(" normal = [%8.2f, %8.2f, %8.2f] (m)",
nonexclusiveStarEq.world_xyz[0],nonexclusiveStarEq.world_xyz[1],nonexclusiveStarEq.world_xyz[2]);
......@@ -426,7 +456,16 @@ public class TilePlanes {
}
}
}
if (src.merged_strong_valid != null){
dst.merged_strong_valid = src.merged_strong_valid.clone();
for (int i = 0; i < src.merged_strong_valid.length; i++){
if (src.merged_strong_valid[i] != null){
dst.merged_strong_valid[i] = src.merged_strong_valid[i].clone();
}
}
}
if (src.neib_best != null) dst.neib_best = src.neib_best.clone();
// also copy original plane parameters - tile selection and number of points
......@@ -1680,6 +1719,7 @@ public class TilePlanes {
this.merged_weig_val = new double[8][];
this.merged_weig_eq = new double[8][];
this.merged_valid = new boolean[8][];
this.merged_strong_valid = new boolean[8][];
return this.merged_eig_val;
}
public double [][] getMergedValue()
......@@ -1705,11 +1745,12 @@ public class TilePlanes {
public double [] initMergedValue(int dir, int leng)
{
this.merged_eig_val[dir] = new double[leng];
this.merged_eig_eq[dir] = new double[leng];
this.merged_weig_val[dir] = new double[leng];
this.merged_weig_eq[dir] = new double[leng];
this.merged_valid[dir] = new boolean[leng];
this.merged_eig_val[dir] = new double[leng];
this.merged_eig_eq[dir] = new double[leng];
this.merged_weig_val[dir] = new double[leng];
this.merged_weig_eq[dir] = new double[leng];
this.merged_valid[dir] = new boolean[leng];
this.merged_strong_valid[dir] = new boolean[leng];
for (int i = 0; i < leng; i++) {
this.merged_eig_val[dir][i] = Double.NaN;
this.merged_eig_eq[dir][i] = Double.NaN;
......@@ -1851,7 +1892,53 @@ public class TilePlanes {
}
public boolean [][] getMergedStrongValid()
{
return this.merged_strong_valid;
}
public boolean [] getMergedStrongValid(int dir)
{
if (this.merged_strong_valid == null) {
return null;
}
return this.merged_strong_valid[dir];
}
public boolean hasMergedStrongValid(int dir){
if ((this.merged_strong_valid == null) || (this.merged_strong_valid[dir] == null)){
return false;
}
for (int np = 0; np < this.merged_strong_valid[dir].length; np++){
if (this.merged_strong_valid[dir][np]) return true;
}
return false;
}
public boolean isMergedStrongValid(int dir, int plane)
{
if ((this.merged_strong_valid == null) || (this.merged_strong_valid[dir] == null)){
return false;
}
return this.merged_strong_valid[dir][plane];
}
public void setMergedStrongValid(int dir, int plane, boolean valid)
{
this.merged_strong_valid[dir][plane] = valid;
}
public void setMergedStrongValid(int dir, int plane, boolean valid, int leng)
{
if (this.merged_strong_valid == null){
this.merged_strong_valid = new boolean[8][];
}
if (this.merged_strong_valid[dir] == null){
this.merged_strong_valid[dir] = new boolean[leng];
}
this.merged_strong_valid[dir][plane] = valid;
}
public int [] initNeibBest()
{
this.neib_best = new int[8];
......@@ -3168,6 +3255,8 @@ public class TilePlanes {
// ", other_det = "+((new Matrix(otherPd.vectors).det()) +", pdr_det = "+((new Matrix(pd.vectors).det()))));
}
copyNeib(this, pd);
pd.num_points = otherPd.num_points; // restore, maybe remove from copy_neib?
return pd; // make sure pd are updated // "this" is not used. Should it be used instead of pd?
}
......@@ -3839,6 +3928,7 @@ public class TilePlanes {
* re-discriminate tiles between supertiles in the list using hints from the already calculated planes and their neighbors
* @param prefix text to be used in debug output (such as supertile number)
* @param planes array of PlaneData instances of the current supertile to be used as hints
* @param merge_planes should be initilaized to int[2], will return indices of planes suggested to be merged or [-1, -1]
* @param stMeasSel select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
* @param dispNorm normalize disparities to the average if above
* @param smplMode use sample mode (false - each tile independent)
......@@ -3852,14 +3942,22 @@ public class TilePlanes {
* @param amplitude_steps numer of histogram steps in each direction from the center
* @param hist_blur histogram LPF sigma
* @param exclusivity 1.0 - tile belongs to one plane only, 0.0 - regardless of others
* @param exclusivity2 when exclusivity > 1.0, add tiles to the existing clusters if attraction > this relaxed level
* @param exclusivity_strict do not add to the clusters if there is a single offending neighbor (false just more of the these neighbors than offenders)
* @param attractionCorrMax do not discriminate if at least one pair has attraction correlation above this level
* @param attractionCorrMerge attraction to different planes correlation that is high enough to merge planes
* @param plDiscrSteal if offender has this number of tiles (including center) the cell can not be used
* @param plDiscrGrown only use tiles within this range from original selection, < 0 - disable this filter
* @param outliersXMedian remove outliers from the final selection that have distance more than scaled median
* @param mode what neighbor-dependent pre-calculated plane to use as hints: 0 - weighted, 1 - equalized, 2 - best, 3 - combined
* @param debugLevel debug level
* @return per-plane, per-measurement layer, per tile index - use this tile.
* @return per-plane, per-measurement layer, per tile index - use this tile. Return null if could not discriminate,
* in that case merge_planes may contain non-negative indices to be merged and the whole method re-ran
*/
public boolean [][][] reDiscriminateTiles(
String prefix,
final PlaneData [] planes,
final PlaneData [] planes,
final int [] merge_planes, // indices of planes suggested to be merged
final int stMeasSel, // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
final double dispNorm, // Normalize disparities to the average if above
......@@ -3875,8 +3973,14 @@ public class TilePlanes {
final int amplitude_steps, // number of steps (each direction) for each plane to search for the best fit (0 - single, 1 - 1 each side)
final double hist_blur, // Sigma to blur histogram
final double exclusivity, // 1.0 - tile belongs to one plane only, 0.0 - regardless of others
final double exclusivity2, // = 0.8; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
final boolean exclusivity_strict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
final double exclusivity2, // = 0.8; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
final boolean exclusivity_strict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
final double attractionCorrMax, // = 0.7; // Attraction to different planes correlation that is too high for re-discrimination.
final double attractionCorrMerge, // = 0.85; // Attraction to different planes correlation that is high enough to merge planes
final int plDiscrSteal, // = 4; // If offender has this number of tiles (including center) the cell can not be used
final int plDiscrGrown, // = 0; // Only use tiles within this range from original selection
final double outliersXMedian, // = 1.5; // Remove outliers from the final selection that have distance more than scaled median
final int mode, // 0 - weighted, 1 - equalized, 2 - best, 3 - combined
final int debugLevel)
{
......@@ -3969,6 +4073,7 @@ public class TilePlanes {
default:
throw new IllegalArgumentException ("refineDiscriminateTiles() "+prefix+":"+np+": invalid mode="+mode);
}
tilePlanes.get(tilePlanes.size()-1).setMark0(np);
}
if (tilePlanes.isEmpty()){
return null;
......@@ -4022,6 +4127,51 @@ public class TilePlanes {
0.0, // double fraction_uni,
0); // int debugLevel)
}
// Create enable and disable masks
boolean [][] prev_used = new boolean [num_planes][size2];
boolean [][] mask = new boolean [num_planes][];
boolean [][] used_strong = new boolean [num_planes][size2];
for (int np = 0; np < num_planes; np++){
boolean [][] meas_sel = tilePlanes.get(np).getMeasSelection();
for (int ml = 0; ml < meas_sel.length; ml++) if (meas_sel[ml] != null){
for (int indx = 0; indx < size2; indx++){
prev_used[np][indx] |= meas_sel[ml][indx];
}
}
mask[np] = prev_used[np].clone();
if (plDiscrGrown > 0) {
tileNeibs.growSelection(
plDiscrGrown, // int grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
mask[np], // boolean [] tiles,
null); // boolean [] prohibit)
} else if (plDiscrGrown < 0){
for (int indx = 0; indx < size2; indx++) mask[np][indx] = true;
}
if (plDiscrSteal > 0){
for (int indx = 0; indx < size2; indx++) if (prev_used[np][indx]){
int num_neibs = 1;
for (int dir = 0; dir < 8; dir++){
int indx1 = tileNeibs.getNeibIndex(indx, dir);
if ((indx1 >=0) && prev_used[np][indx1]){
num_neibs++;
}
}
used_strong[np][indx] = (num_neibs >= plDiscrSteal);
}
}
}
if (plDiscrSteal > 0){
for (int np = 0; np < num_planes; np++){
for (int np1 = 0; np1 < num_planes; np1++) if (np1 != np){
for (int indx = 0; indx < size2; indx++){
mask[np][indx] &= !used_strong[np1][indx];
}
}
}
}
double [][][] flatness = new double [num_planes][disp_strength.length][];
double [][][] norm_flatness = new double [num_planes][disp_strength.length][];
int [][][] num_cells = new int [num_planes][disp_strength.length][];
......@@ -4058,8 +4208,10 @@ public class TilePlanes {
flatness[np][ml][indx] = rms; // sd2; // will not be used
// norm_flatness[np][ml][indx] = num_cells[np][ml][indx]/(sd2 + floor2);
// norm_flatness[np][ml][indx] = (num_cells[np][ml][indx] > 1) ? (1.0/sd2): (1.0/floor2);
if (rms < disp_var_floor){
rms = disp_var_floor;
}
norm_flatness[np][ml][indx] = (num_cells[np][ml][indx] > 1) ? (1.0/rms): (1.0/disp_var_floor);
}
}
}
......@@ -4074,7 +4226,7 @@ public class TilePlanes {
double weight = disp_strength[ml][1][indx];
if (weight > 0.0) {
double disp = disp_strength[ml][0][indx];
for (int np = 0; np < num_planes; np++){
for (int np = 0; np < num_planes; np++) if (mask[np][indx]){
double d = disp - pds[np][0][indx];
double db = d * k_bin + amplitude_steps;
int bin = (int) Math.round (db);
......@@ -4189,7 +4341,7 @@ public class TilePlanes {
}
for (int ml = 0; ml < disp_strength.length; ml++) if (disp_strength[ml] != null){
for (int indx = 0; indx < size2; indx++) if (disp_strength[ml][1][indx] > 0){
for (int np = 0; np < num_planes; np++) {
for (int np = 0; np < num_planes; np++) if (mask[np][indx]){
double d1 = pds[np][0][indx] + offsets[np]; // shifted plane
double d2 = disp_strength[ml][0][indx];
double dav = 0.5 * (d1 + d2);
......@@ -4226,14 +4378,16 @@ public class TilePlanes {
attr_corr[np][np] = 1.0;
}
if ((debugLevel > 0) && (num_planes > 1)){
String dbg_s = "refineDiscriminateTiles() plane attraction correlation for "+prefix+":";
for (int np = 0; np < num_planes; np++) {
for (int np1 = np + 1; np1 < num_planes; np1++) {
dbg_s += String.format(" %d-%d:%6.3f",np,np1,attr_corr[np][np1]);
double max_attr_corr = 0.0;
int [] merge_pair = {-1,-1};
for (int np = 0; np < num_planes; np++) {
for (int np1 = np + 1; np1 < num_planes; np1++) {
if (attr_corr[np][np1] > max_attr_corr) {
max_attr_corr = attr_corr[np][np1];
merge_pair[0] = np;
merge_pair[1] = np1;
}
}
System.out.println(dbg_s);
}
......@@ -4323,14 +4477,82 @@ public class TilePlanes {
}
}
boolean [][][] all_best_selections = null;
if (outliersXMedian > 0.0) {
all_best_selections = best_selections.clone();
for (int np = 0; np < num_planes; np++) if (best_selections[np] != null){
all_best_selections[np] = best_selections[np].clone();
for (int ml = 0; ml < best_selections[np].length; ml++) if (best_selections[np][ml] != null){
all_best_selections[np][ml] = best_selections[np][ml].clone();
}
}
// from each plane remove outliers (without re-calculating mean value) that are farther from the mean than scaled median distance
class ValIndex {
int ml;
int indx;
double val;
ValIndex(int ml, int indx, double val){
this.ml = ml;
this.indx = indx;
this.val = val;
}
}
for (int np = 0; np < num_planes; np++) if (best_selections[np] != null){
ArrayList<ValIndex> tile_list = new ArrayList<ValIndex>();
for (int ml = 0; ml < best_selections[np].length; ml++) if (best_selections[np][ml] != null){
for (int indx = 0; indx < best_selections[np][ml].length; indx++) if (best_selections[np][ml][indx]){
double d1 = pds[np][0][indx] + offsets[np]; // shifted plane
double d2 = disp_strength[ml][0][indx];
double diff = d2 - d1;
// double dav = 0.5 * (d1 + d2);
// if (dav > dispNorm) diff *= dispNorm/dav;
double diff2 = diff * diff;
tile_list.add(new ValIndex(ml,indx,diff2));
}
}
if (!tile_list.isEmpty()){
Collections.sort(tile_list, new Comparator<ValIndex>() {
@Override
public int compare(ValIndex lhs, ValIndex rhs) {
// -1 - less than, 1 - greater than, 0 - equal
return (rhs.val > lhs.val) ? -1 : (rhs.val < lhs.val ) ? 1 : 0;
}
});
int size = tile_list.size();
double threshold =tile_list.get(size/2).val * outliersXMedian * outliersXMedian *1.0;
for (int i = (outliersXMedian > 1.0) ? (size / 2 + 1) : 0; i < size; i++){
if (tile_list.get(i).val > threshold) {
best_selections[np][tile_list.get(i).ml][tile_list.get(i).indx] = false;
}
}
}
// now restore outliers if they had non-outliers neighbors
ArrayList<Point> to_resore_list = new ArrayList<Point>();
for (int ml = 0; ml < best_selections[np].length; ml++) if (best_selections[np][ml] != null){
for (int indx = 0; indx < best_selections[np][ml].length; indx++) {
if (all_best_selections[np][ml][indx] && !best_selections[np][ml][indx]){ // removed as outliers
for (int dir = 0; dir<8; dir++){
int indx1 = tileNeibs.getNeibIndex(indx, dir);
if ((indx1 >= 0) && best_selections[np][ml][indx1]){
to_resore_list.add(new Point(ml, indx));
break;
}
}
}
}
}
for (Point p:to_resore_list) {
best_selections[np][p.x][p.y] = true;
}
}
}
if (debugLevel > 2){
int dbg_ml = 0; // to protect from different layer configuration
for (; dbg_ml < disp_strength.length; dbg_ml++){
if (disp_strength[dbg_ml] != null) break;
}
//disp_strength[dbg_ml][0], disp_strength[dbg_ml][1] * 10, disp_strength[dbg_ml][0] - pds[np][0], pds[np][0]
String [] dbg_titles = new String[2 + 8 * num_planes];
String [] dbg_titles = new String[2 + 10 * num_planes];
double [][] dbg_img = new double [dbg_titles.length][];
dbg_titles[0] = "disp_"+dbg_ml;
dbg_titles[1] = "str_"+dbg_ml;
......@@ -4342,31 +4564,37 @@ public class TilePlanes {
dbg_titles[2 + 2 * num_planes + np] = "flat_"+np;
dbg_titles[2 + 3 * num_planes + np] = "rflat_"+np;
dbg_titles[2 + 4 * num_planes + np] = "nrflat_"+np;
dbg_titles[2 + 5 * num_planes + np] = "attr_"+np;
dbg_titles[2 + 6 * num_planes + np] = "sel_"+np; // add also old selection?
dbg_titles[2 + 7 * num_planes + np] = "oldsel_"+np; // add also old selection?
dbg_titles[2 + 5 * num_planes + np] = "mask_"+np;
dbg_titles[2 + 6 * num_planes + np] = "attr_"+np;
dbg_titles[2 + 7 * num_planes + np] = "pre_sel_"+np; // before outliers
dbg_titles[2 + 8 * num_planes + np] = "sel_"+np; // add also old selection?
dbg_titles[2 + 9 * num_planes + np] = "oldsel_"+np; // add also old selection?
dbg_img[2 + 0 * num_planes + np] = pds[np][0];
dbg_img[2 + 1 * num_planes + np] = disp_strength[dbg_ml][0].clone();
dbg_img[2 + 2 * num_planes + np] = flatness[np][dbg_ml];
dbg_img[2 + 3 * num_planes + np] = new double[size2];
dbg_img[2 + 4 * num_planes + np] = norm_flatness[np][dbg_ml];
dbg_img[2 + 5 * num_planes + np] = attractions[np][dbg_ml];
dbg_img[2 + 6 * num_planes + np] = new double[size2];
dbg_img[2 + 5 * num_planes + np] = new double[size2];
dbg_img[2 + 6 * num_planes + np] = attractions[np][dbg_ml];
dbg_img[2 + 7 * num_planes + np] = new double[size2];
dbg_img[2 + 8 * num_planes + np] = new double[size2];
dbg_img[2 + 9 * num_planes + np] = new double[size2];
for (int i = 0; i < size2; i++) {
dbg_img[2 + 1 * num_planes + np][i] -= pds[np][0][i];
// dbg_img[2 + 3 * num_planes + np][i] = 1.0 / (flatness[np][dbg_ml][i] + 0.001);
dbg_img[2 + 3 * num_planes + np][i] = (num_cells[np][dbg_ml][i] > 1) ? (1.0/flatness[np][dbg_ml][i]): (1.0/disp_var_floor); // floor2);
// dbg_img[2 + 4 * num_planes + np][i] = num_cells[np][dbg_ml][i] * 1.0 / (flatness[np][dbg_ml][i] + 0.001);
dbg_img[2 + 6 * num_planes + np][i] = best_selections[np][dbg_ml][i] ? 1.0 : 0.0;
dbg_img[2 + 7 * num_planes + np][i] = planes[np+1].measuredSelection[dbg_ml][i]? 1.0:0.0; // temporarily
dbg_img[2 + 5 * num_planes + np][i] = mask[np][i] ? 1.0 : 0.0;
if (all_best_selections != null) {
dbg_img[2 + 7 * num_planes + np][i] = all_best_selections[np][dbg_ml][i] ? 1.0 : 0.0;
}
dbg_img[2 + 8 * num_planes + np][i] = best_selections[np][dbg_ml][i] ? 1.0 : 0.0;
dbg_img[2 + 9 * num_planes + np][i] = planes[np+1].measuredSelection[dbg_ml][i]? 1.0:0.0; // temporarily
if (disp_strength[dbg_ml][1][i] == 0.0){
dbg_img[2 + 1 * num_planes + np][i] = Double.NaN;
dbg_img[2 + 2 * num_planes + np][i] = Double.NaN;
dbg_img[2 + 3 * num_planes + np][i] = Double.NaN;
dbg_img[2 + 4 * num_planes + np][i] = Double.NaN;
dbg_img[2 + 5 * num_planes + np][i] = Double.NaN;
dbg_img[2 + 6 * num_planes + np][i] = Double.NaN;
}
}
}
......@@ -4376,7 +4604,39 @@ public class TilePlanes {
if (debugLevel > 1) {
System.out.println ("refineDiscriminateTiles() "+prefix+" - step 3");
}
// moved here to debug
if (merge_planes != null) {
if ((max_attr_corr > attractionCorrMax) && (max_attr_corr > attractionCorrMerge)) { // attractionCorrMerge can be ==0, then all >..Max will be merged
tilePlanes.get(merge_pair[0]).getMark0();
merge_planes[0] = tilePlanes.get(merge_pair[0]).getMark0(); // merge_pair[0];
merge_planes[1] = tilePlanes.get(merge_pair[1]).getMark0(); // merge_pair[1];
} else {
merge_planes[0] = -1;
merge_planes[1] = -1;
}
}
if (((debugLevel > -1) && ((debugLevel > 0) || (max_attr_corr > attractionCorrMax)) )&& (num_planes > 1)){
String dbg_s = "refineDiscriminateTiles() plane attraction correlation for "+prefix+": maximal="+max_attr_corr;
for (int np = 0; np < num_planes; np++) {
for (int np1 = np + 1; np1 < num_planes; np1++) {
dbg_s += String.format(" %d-%d:%6.3f",np,np1,attr_corr[np][np1]);
}
}
if (merge_planes[0] >= 0) {
dbg_s += " will merge pair: ["+merge_pair[0]+", "+merge_pair[1]+"],"+
" planes["+tilePlanes.get(merge_pair[0]).getMark0()+"] and"+
" planes["+tilePlanes.get(merge_pair[1]).getMark0()+"] ";
} else if (max_attr_corr > attractionCorrMax){
dbg_s += " KEEPENG original tile selections";
}
System.out.println(dbg_s);
}
if (max_attr_corr > attractionCorrMax) {
return null;
}
return best_selections;
}
......
......@@ -3306,7 +3306,7 @@ public class TileProcessor {
st.planes, // final TilePlanes.PlaneData [][] planes,
merge_candidates, // final int [][][] merge_candidates,
plane_nooverlaps, // final boolean [][][] valid_candidates, // will be updated
true, // final boolean merge_low_eigen,
true, // final boolean merge_low_eigen, here it should be true
2, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
......@@ -3520,47 +3520,54 @@ public class TileProcessor {
// re-generate planes in the supertiles using previously calculated planes (for tghe tiles and their neighbors)
// as hints, new planes will be assumed parallel to the known and possibly slightly offset in disparity
st.regeneratePlanes(
st.planes, // final TilePlanes.PlaneData [][] planes,
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,
if (clt_parameters.plDiscrEn) {
st.regeneratePlanes(
st.planes, // final TilePlanes.PlaneData [][] planes,
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,
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.plDiscrTolerance, // final double plDiscrTolerance, // = 0.4; // Maximal disparity difference from the plane to consider tile
clt_parameters.plDiscrDispRange, // final double plDiscrDispRange, // = 0.6; // Parallel move known planes around original know value for the best overall fit
clt_parameters.plDiscrSteps, // final int plDiscrSteps, // = 3; // Number of steps (each direction) for each plane to search for the best fit (0 - single, 1 - 1 each side)
clt_parameters.plDiscrVariants, // final int plDiscrVariants, // = 100; // Total number of variants to try (protect from too many planes)
clt_parameters.plDiscrMode, // final int plDiscrMode, // = 3; // What plane to use as a hint: 0 - weighted, 1 - equalized, 2 - best, 3 - combined
clt_parameters.plDiscrVarFloor, // final double plDiscrVarFloor, // = 0.03; // Squared add to variance to calculate reverse flatness (used mostly for single-cell clusters)
clt_parameters.plDiscrSigma, // final double plDiscrSigma, // = 0.05; // Gaussian sigma to compare how measured data is attracted to planes
clt_parameters.plDiscrBlur, // final double plDiscrBlur, // = 0.1; // Sigma to blur histograms while re-discriminating
clt_parameters.plDiscrExclusivity,// final double plDiscrExclusivity, // = 0.5; // Tile exclusivity: 1.0 - tile belongs to one plane only, 0.0 - regardless of others
clt_parameters.plDiscrExclus2,// final double plDiscrExclus2, // = 0.5; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
clt_parameters.plDiscrStrict, // final boolean plDiscrStrict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
0, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
// condition the redcefined planes
conditionSuperTiles(
clt_parameters, //EyesisCorrectionParameters.CLTParameters clt_parameters,
geometryCorrection, // GeometryCorrection geometryCorrection,
st, // SuperTiles st,
lp, // LinkPlanes lp,
debugLevel); // final int debugLevel);
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.plDiscrTolerance, // final double plDiscrTolerance, // = 0.4; // Maximal disparity difference from the plane to consider tile
clt_parameters.plDiscrDispRange, // final double plDiscrDispRange, // = 0.6; // Parallel move known planes around original know value for the best overall fit
clt_parameters.plDiscrSteps, // final int plDiscrSteps, // = 3; // Number of steps (each direction) for each plane to search for the best fit (0 - single, 1 - 1 each side)
clt_parameters.plDiscrVariants, // final int plDiscrVariants, // = 100; // Total number of variants to try (protect from too many planes)
clt_parameters.plDiscrMode, // final int plDiscrMode, // = 3; // What plane to use as a hint: 0 - weighted, 1 - equalized, 2 - best, 3 - combined
clt_parameters.plDiscrVarFloor, // final double plDiscrVarFloor, // = 0.03; // Squared add to variance to calculate reverse flatness (used mostly for single-cell clusters)
clt_parameters.plDiscrSigma, // final double plDiscrSigma, // = 0.05; // Gaussian sigma to compare how measured data is attracted to planes
clt_parameters.plDiscrBlur, // final double plDiscrBlur, // = 0.1; // Sigma to blur histograms while re-discriminating
clt_parameters.plDiscrExclusivity,// final double plDiscrExclusivity, // = 0.5; // Tile exclusivity: 1.0 - tile belongs to one plane only, 0.0 - regardless of others
clt_parameters.plDiscrExclus2, // final double plDiscrExclus2, // = 0.5; // For second pass if exclusivity > 1.0 - will assign only around strong neighbors
clt_parameters.plDiscrStrict, // final boolean plDiscrStrict, // = true; // When growing selection do not allow any offenders around (false - more these than others)
clt_parameters.plDiscrCorrMax, // final double plDiscrCorrMax, // = 0.7; // Attraction to different planes correlation that is too high for re-discrimination.
clt_parameters.plDiscrCorrMerge, // final double plDiscrCorrMerge, // = 0.85; // Attraction to different planes correlation that is high enough to merge planes
clt_parameters.plDiscrSteal, // final int plDiscrSteal, // = 4; // If offender has this number of tiles (including center) the cell can not be used
clt_parameters.plDiscrGrown, // final int plDiscrGrown, // = 0; // Only use tiles within this range from original selection
clt_parameters.plDiscrXMedian, // final double plDiscrXMedian, // = 1.5; // Remove outliers from the final selection that have distance more than scaled median
0, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
// condition the redcefined planes
conditionSuperTiles(
clt_parameters, //EyesisCorrectionParameters.CLTParameters clt_parameters,
geometryCorrection, // GeometryCorrection geometryCorrection,
st, // SuperTiles st,
lp, // LinkPlanes lp,
debugLevel); // final int debugLevel);
}
double [][] quality_stats1 = lp.selectNeighborPlanesMutual(
st.planes, // final TilePlanes.PlaneData [][] planes,
2, // final int debugLevel)
......@@ -3751,6 +3758,7 @@ public class TileProcessor {
if (clt_parameters.plIterations > 0) {
st.resetPlanesMod(); // clean start
planes_mod = st.planesSmooth(
lp, // LinkPlanes lp,
clt_parameters.plPull, // final double meas_pull,// relative pull of the original (measured) plane with respect to the average of the neighbors
clt_parameters.plMaxEigen, // final double maxValue, // do not combine with too bad planes
clt_parameters.plIterations, // final int num_passes,
......@@ -3758,7 +3766,7 @@ public class TileProcessor {
clt_parameters.plNormPow, // 0.0: 8 neighbors pull 8 times as 1, 1.0 - same as 1
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)
1,// 0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
} else {
......
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