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

showing edges fro plane pairs

parent bdf3d47f
......@@ -2160,10 +2160,13 @@ public class EyesisCorrectionParameters {
public double plPull = .1; // Relative weight of original (measured) plane 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)
public int plPrecision = 6; // Maximal step difference (1/power of 10)
public double plSplitPull = .5; // Relative weight of center plane when splitting into pairs
public int plSplitMinNeib = 2; // Minimal number of neighbors to split plane in pairs
public double plSplitMinWeight = 2.0; // Minimal weight of split plains to show
public double plSplitMinQuality = 1.1; // Minimal split quality to show
public boolean plFuse = true; // Fuse planes together (off for debug only)
......@@ -2430,10 +2433,13 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"plPull", this.plPull +"");
properties.setProperty(prefix+"plIterations", this.plIterations+"");
properties.setProperty(prefix+"plStopBad", this.plStopBad+"");
properties.setProperty(prefix+"plPrecision", this.plPrecision+"");
properties.setProperty(prefix+"plSplitPull", this.plSplitPull +"");
properties.setProperty(prefix+"plSplitMinNeib", this.plSplitMinNeib+"");
properties.setProperty(prefix+"plSplitMinWeight", this.plSplitMinWeight +"");
properties.setProperty(prefix+"plSplitMinQuality",this.plSplitMinQuality +"");
properties.setProperty(prefix+"plFuse", this.plFuse+"");
properties.setProperty(prefix+"plKeepOrphans", this.plKeepOrphans+"");
......@@ -2687,10 +2693,13 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"plPull")!=null) this.plPull=Double.parseDouble(properties.getProperty(prefix+"plPull"));
if (properties.getProperty(prefix+"plIterations")!=null) this.plIterations=Integer.parseInt(properties.getProperty(prefix+"plIterations"));
if (properties.getProperty(prefix+"plStopBad")!=null) this.plStopBad=Boolean.parseBoolean(properties.getProperty(prefix+"plStopBad"));
if (properties.getProperty(prefix+"plPrecision")!=null) this.plPrecision=Integer.parseInt(properties.getProperty(prefix+"plPrecision"));
if (properties.getProperty(prefix+"plSplitPull")!=null) this.plSplitPull=Double.parseDouble(properties.getProperty(prefix+"plSplitPull"));
if (properties.getProperty(prefix+"plSplitMinNeib")!=null) this.plSplitMinNeib=Integer.parseInt(properties.getProperty(prefix+"plSplitMinNeib"));
if (properties.getProperty(prefix+"plSplitMinWeight")!=null) this.plSplitMinWeight=Double.parseDouble(properties.getProperty(prefix+"plSplitMinWeight"));
if (properties.getProperty(prefix+"plSplitMinQuality")!=null) this.plSplitMinQuality=Double.parseDouble(properties.getProperty(prefix+"plSplitMinQuality"));
if (properties.getProperty(prefix+"plFuse")!=null) this.plFuse=Boolean.parseBoolean(properties.getProperty(prefix+"plFuse"));
if (properties.getProperty(prefix+"plKeepOrphans")!=null) this.plKeepOrphans=Boolean.parseBoolean(properties.getProperty(prefix+"plKeepOrphans"));
......@@ -2966,10 +2975,13 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Relative weight of original (measured) plane when combing with neighbors", this.plPull, 6);
gd.addNumericField("Maximal number of smoothing iterations for each step", this.plIterations, 0);
gd.addCheckbox ("Do not update supertile if any of connected is not good (false: just skip that neighbor)", this.plStopBad);
gd.addNumericField("Maximal step difference (1/power of 10)", this.plPrecision, 0);
gd.addNumericField("Relative weight of center plane when splitting into pairs", this.plSplitPull, 6);
gd.addNumericField("Minimal number of neighbors to split plane in pairs", this.plSplitMinNeib, 0);
gd.addNumericField(" Minimal weight of split plains to show", this.plSplitMinWeight, 6);
gd.addNumericField("Minimal split quality to show", this.plSplitMinQuality, 6);
gd.addCheckbox ("Fuse planes together (off for debug only)", this.plFuse);
gd.addCheckbox ("Keep unconnected supertiles", this.plKeepOrphans);
......@@ -3233,10 +3245,13 @@ public class EyesisCorrectionParameters {
this.plPull= gd.getNextNumber();
this.plIterations= (int) gd.getNextNumber();
this.plStopBad= gd.getNextBoolean();
this.plPrecision= (int) gd.getNextNumber();
this.plSplitPull= gd.getNextNumber();
this.plSplitMinNeib= (int) gd.getNextNumber();
this.plSplitMinWeight= gd.getNextNumber();
this.plSplitMinQuality= gd.getNextNumber();
this.plFuse= gd.getNextBoolean();
this.plKeepOrphans= gd.getNextBoolean();
......
......@@ -624,7 +624,7 @@ public class SuperTiles{
int y0 = stileY * (numBins + 1);
int indx0 = x0 + y0*width;
// draw rectangular frame - horisontal dotted lines
// draw rectangular frame - horizontal dotted lines
for (int j = 0; j < numBins + 2; j+=2) {
rslt [indx0 + j] = maxW;
rslt [indx0 + (sTileHeight + 1) * width+ j] = maxW;
......@@ -1540,6 +1540,7 @@ public class SuperTiles{
planes[nsTile0][indx], // PlaneData otherPd,
1.0, // double scale_other,
true, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
(nsTile0 == debug_stile)? 1:0); // int debugLevel)
System.out.println("other with other, same weight:");
......@@ -1547,6 +1548,7 @@ public class SuperTiles{
other_pd, // PlaneData otherPd,
1.0, // double scale_other,
true, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
(nsTile0 == debug_stile)? 1:0); // int debugLevel)
System.out.println("other with this, same weight:");
......@@ -1555,6 +1557,7 @@ public class SuperTiles{
other_pd, // PlaneData otherPd,
1.0, // double scale_other,
true, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
(nsTile0 == debug_stile)? 1:0); // int debugLevel)
if (!(merged_pd.getValue() > best_value)) { // Double.isNaN(best_value) will work too
......@@ -1571,8 +1574,12 @@ public class SuperTiles{
other_pd, // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
(nsTile0 == debug_stile)? 1:0); // int debugLevel)
if (merged_pd != null) {
merged_pd.scaleWeight(0.5);
}
neib_planes[nsTile0][np] = merged_pd;
} else {
neib_planes[nsTile0][np] = other_pd;
......@@ -1665,15 +1672,18 @@ public class SuperTiles{
for (int np = 0; np < other_planes.length; np ++){
TilePlanes.PlaneData other_plane = this_plane.getPlaneToThis(
other_planes[np],
dl); // debugLevel);
dl-1); // debugLevel);
if (other_plane !=null) { // now always, but may add later
TilePlanes.PlaneData merged_pd = this_plane.mergePlaneToThis(
other_plane, // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
dl); // int debugLevel)
dl-1); // int debugLevel)
if (merged_pd !=null) { // now always, but may add later
/// merged_pd.scaleWeight(0.5);
this_plane.setNeibMatch(dir, np, merged_pd.getValue()); // smallest eigenValue
}
}
......@@ -2145,10 +2155,12 @@ public class SuperTiles{
best_pair[1]= np;
}
}
if ((merge_ev[np] < 0.4) && (w1 > 1.0) && (w2 > 1.0) ){
System.out.println("nsTile0="+nsTile0+":"+np0+", nsTile="+nsTile+":"+np+", this_rq="+this_rq+
" w1="+w1+" w2="+w2+
" L1="+planes[nsTile0][np0].getValue()+" L2="+planes[nsTile][np].getValue()+" L="+merge_ev[np]);
if (debugLevel > 0){
if ((merge_ev[np] < 0.4) && (w1 > 1.0) && (w2 > 1.0) ){
System.out.println("nsTile0="+nsTile0+":"+np0+", nsTile="+nsTile+":"+np+", this_rq="+this_rq+
" w1="+w1+" w2="+w2+
" L1="+planes[nsTile0][np0].getValue()+" L2="+planes[nsTile][np].getValue()+" L="+merge_ev[np]);
}
}
}
}
......@@ -2508,7 +2520,9 @@ public class SuperTiles{
public TilePlanes.PlaneData[][] planesSmooth(
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,
final boolean stopBadNeib, // do not update supertile if any of connected neighbors is not good (false: just skip that neighbor)
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,
......@@ -2521,6 +2535,8 @@ public class SuperTiles{
for (int pass = 0; pass < num_passes; pass++){
double diff = planesSmoothStep(
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)
this.planes, // final TilePlanes.PlaneData[][] measured_planes,
this.planes_mod, // final TilePlanes.PlaneData[][] mod_planes,
true, // final boolean calc_diff,
......@@ -2544,6 +2560,8 @@ public class SuperTiles{
public double planesSmoothStep(
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 boolean stopBadNeib, // do not update supertile if any of connected neighbors is not good (false: just skip that neighbor)
final TilePlanes.PlaneData[][] measured_planes,
final TilePlanes.PlaneData[][] mod_planes,
final boolean calc_diff,
......@@ -2594,6 +2612,7 @@ public class SuperTiles{
int [] neibs = this_new_plane.getNeibBest();
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++){
if (neibs[dir] >= 0) {
int stx = stx0 + dirsYX[dir][1];
......@@ -2601,68 +2620,111 @@ public class SuperTiles{
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); // debugLevel);
dl - 1); // debugLevel);
if (dl > 0) dbg_img[ 2 + dir] = other_plane.getPlaneDisparity(false);
if (other_plane != null){
if ((other_plane != null) && ((other_plane.getValue() <= maxValue) || (maxValue == 0))) {
if (this_new_plane.getWeight() > 0.0){
this_new_plane = this_new_plane.mergePlaneToThis(
other_plane, // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
dl); // int debugLevel)
dl - 1); // int debugLevel)
if (this_new_plane != null){
num_merged += 1.0;
}
} else {
this_new_plane = other_plane;
}
new_planes[nsTile0][np0] = this_new_plane;
if (dl > 0) dbg_img[10 + dir] = this_new_plane.getPlaneDisparity(false);
} else if (stopBadNeib){
this_new_plane = null;
break;
}
}
}
if ( (meas_pull > 0.0) &&
(measured_planes != null) &&
(measured_planes[nsTile0] != null) &&
(measured_planes[nsTile0][np0] != null)){ // merge with "measured"
if (this_new_plane.getWeight() > 0.0){
this_new_plane = this_new_plane.mergePlaneToThis(
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();
if (this_new_plane != null) {
if ( (meas_pull > 0.0) &&
(measured_planes != null) &&
(measured_planes[nsTile0] != null) &&
(measured_planes[nsTile0][np0] != null) &&
((measured_planes[nsTile0][np0].getValue() < maxValue) || (maxValue == 0))
){ // merge with "measured"
if (this_new_plane.getWeight() > 0.0){
this_new_plane = this_new_plane.mergePlaneToThis(
measured_planes[nsTile0][np0], // PlaneData otherPd,
meas_pull, // double scale_other,
false, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
dl - 1); // int debugLevel)
if (this_new_plane != null){
num_merged += meas_pull;
}
} else {
this_new_plane = measured_planes[nsTile0][np0].clone();
num_merged = 1.0;
}
new_planes[nsTile0][np0] = this_new_plane;
if (dl > 0) dbg_img[18] = this_new_plane.getPlaneDisparity(false);
}
new_planes[nsTile0][np0] = this_new_plane;
if (dl > 0) dbg_img[18] = this_new_plane.getPlaneDisparity(false);
}
// calculate largest disparity difference between old and new plane
if (rslt_diffs != null){
// get plane for both old and new, calc rms of diff
double [] oldPlane = mod_planes[nsTile0][np0].getPlaneDisparity(
false); // use_NaN)
double [] newPlane = new_planes[nsTile0][np0].getPlaneDisparity(
false); // use_NaN)
double s = 0.0;
for (int i = 0; i < oldPlane.length; i++){
double d = newPlane[i] - oldPlane[i];
s+= d*d;
if ((num_merged > 0.0) && (this_new_plane != null)){
this_new_plane.scaleWeight(1.0/num_merged);
}
s= Math.sqrt(s/oldPlane.length);
if (s > rslt_diffs[numThread]){
rslt_diffs[numThread] = s;
// Revert if the result value is higher than imposed maximum
if ((this_new_plane.getValue() > maxValue) && (maxValue != 0)){
this_new_plane = mod_planes[nsTile0][np0].clone();
new_planes[nsTile0][np0] = this_new_plane;
}
if (dl > 0) {
dbg_img[19] = new double[oldPlane.length];
// 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
double [] oldPlane = mod_planes[nsTile0][np0].getPlaneDisparity(
false); // use_NaN)
double [] newPlane = new_planes[nsTile0][np0].getPlaneDisparity(
false); // use_NaN)
double s = 0.0;
for (int i = 0; i < oldPlane.length; i++){
dbg_img[19][i] = newPlane[i] - oldPlane[i];
double d = newPlane[i] - oldPlane[i];
s+= d*d;
}
s= Math.sqrt(s/oldPlane.length);
if (s > rslt_diffs[numThread]){
rslt_diffs[numThread] = s;
}
if (dl > 0) {
dbg_img[19] = new double[oldPlane.length];
for (int i = 0; i < oldPlane.length; i++){
dbg_img[19][i] = newPlane[i] - oldPlane[i];
}
if (debugLevel > 0) {
System.out.println("planesSmoothStep() nsTile0="+nsTile0+" rms = "+s);
}
}
if (debugLevel > -1) {
// if ((s > 5.0) || (dl > 0)){
if (s > 5.0){
System.out.println("planesSmoothStep() nsTile0="+nsTile0+
" num_merged="+num_merged + " rms = "+s+
" new_weight = "+new_planes[nsTile0][np0].getWeight()+
" old_weight = "+mod_planes[nsTile0][np0].getWeight()+
" new_value = "+new_planes[nsTile0][np0].getValue()+
" old_value = "+mod_planes[nsTile0][np0].getValue()+
" measured_weight = "+measured_planes[nsTile0][np0].getWeight()+
" measured_value = "+measured_planes[nsTile0][np0].getValue());
}
}
}
if ((dl > 0) && (debugLevel > 0)){
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
sdfa_instance.showArrays(dbg_img, superTileSize, superTileSize, true, "smooth_step_x"+stx0+"_y"+sty0, titles);
}
}
if ((dl > 0) && (debugLevel >1)){
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
sdfa_instance.showArrays(dbg_img, superTileSize, superTileSize, true, "smooth_step_x"+stx0+"_y"+sty0, titles);
}
}
}
......@@ -2700,10 +2762,107 @@ public class SuperTiles{
return diffs;
}
/**
* Prepare visualization of the plane separation lines
* @param split_planes per supertile, per plane sets of 3 plane data instances
* (first, second, merged)
* @param debugLevel debug level
* @param dbg_X supertile horizontal index to show debug information
* @param dbg_Y supertile vertical index to show debug information
* @return array to be visualized as width=superTileSize*stilesX,
* height = superTileSize*stilesY data. Lines value match plane index,
* length corresponds to triple-sized supertiles
*/
public double [] showSplitLines(
final TilePlanes.PlaneData[][][] split_planes,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
final int [][] dirsYX = {{-1, 0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int width = superTileSize * stilesX;
final int height = superTileSize * stilesY;
final int debug_stile = dbg_Y * stilesX + dbg_X;
double [] split_lines = new double[width * height];
final int ss3 = 3 * superTileSize;
for (int nsTile = 0; nsTile < split_planes.length; nsTile++) {
if (split_planes[nsTile] != null) {
int sty = nsTile / stilesX;
int stx = nsTile % stilesX;
int dl = ((debugLevel > -1) && (nsTile == debug_stile)) ? 1:0;
int min_np = (split_planes[nsTile].length > 1)? 1 : 0;
for (int np = min_np; np < split_planes[nsTile].length; np++){
if (split_planes[nsTile][np] != null){
TilePlanes.PlaneData split_plane1 = split_planes[nsTile][np][0];
TilePlanes.PlaneData split_plane2 = split_planes[nsTile][np][1];
if ((split_plane1 != null) && ( split_plane2 != null)){
double [] tpd = split_plane1.getTriplePlaneDisparity();
double [] tpd1 = split_plane2.getTriplePlaneDisparity();
// difference of the 2 split planes disparities, show where
// they have lowest value in any of the 2 orthogonal directions
for (int i = 0; i < tpd.length; i++) {
tpd[i] = Math.abs(tpd[i] - tpd1[i]);
}
int [] vby = new int [ss3];
for (int x = 0; x < ss3; x ++){
vby[x] = 0;
for (int y = 1; y < ss3; y ++){
if (tpd[y * ss3 + x] < tpd[vby[x] * ss3 + x]){
vby[x] = y;
}
}
}
int [] vbx = new int [ss3];
for (int y = 0; y < ss3; y ++){
vbx[y] = 0;
for (int x = 1; x < ss3; x ++){
if (tpd[y * ss3 + x] < tpd[y * ss3 + vbx[y]]){
vbx[y] = x;
}
}
}
for (int dx = 0; dx < ss3; dx ++){
if ((vby[dx] > 0) && (vby[dx] < (ss3-1))) {
int y = vby[dx] + superTileSize * (sty - 1);
int x = dx + superTileSize * (stx - 1);
if ((y >= 0) && (y < height) && (x >= 0) && (x < width)){
split_lines[ y* width + x] = np - min_np + 1;
}
}
}
for (int dy = 0; dy < ss3; dy ++){
if ((vbx[dy] > 0) && (vbx[dy] < (ss3-1))) {
int x = vbx[dy] + superTileSize * (stx - 1);
int y = dy + superTileSize * (sty - 1);
if ((y >= 0) && (y < height) && (x >= 0) && (x < width)){
split_lines[ y* width + x] = np - min_np + 1;
}
}
}
}
}
}
}
}
return split_lines;
}
/**
* Create candidate planes to break a single plane in 2 by splitting consecutive connected
* neighbors in 2 groups that make the smallest weighted sum of the eigenvalues
* Groups may be optionally supplemented by the center supertile
* Groups may be optionally supplemented by the center supertile
* Result weights are sums of participating supertile weights, for normalization (if needed)
* divide by number of neighbors plus center_pull
* @param center_planes [per supertile][per plane] array of plane objects to use as
* the source of connections and optionally other data for the center tiles
* @param neib_planes [per supertile][per plane] array of plane objects to use for
......@@ -2711,6 +2870,9 @@ public class SuperTiles{
* @param center_pull - merge with center plane when calculating half-planes with this
* relative weight: 0.0 - only neighbors, 1.0 - same weight of the center as each neighbor.
* @param min_neibs - minimal number of connected neighbors to work with (>=2)
* @param splitMinWeight - minimal weight of the tile to split
* @param splitMinQuality - minimal quality of split (EV of the single plane over weighted average
* of each half-plane
* @param preferDisparity - the first eigenvalue/vector is the most disparity-like
* (false - smallest eigenvalue)
* @param debugLevel debug level
......@@ -2720,10 +2882,12 @@ public class SuperTiles{
* (to compare eigenvalues)
*/
public TilePlanes.PlaneData[][][] breakPlanesToPairs(
final TilePlanes.PlaneData[][] center_planes, // measured_planes,
final TilePlanes.PlaneData[][] neib_planes, //mod_planes,
final TilePlanes.PlaneData[][] center_planes, // measured_planes,
final TilePlanes.PlaneData[][] neib_planes, //mod_planes,
final double center_pull,
final int min_neibs, // 2
final int min_neibs, // 2
final double splitMinWeight, // = 2.0; // Minimal weight of split plains to show
final double splitMinQuality, // = 1.1; // Minimal split quality to show
final boolean preferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
final int debugLevel,
final int dbg_X,
......@@ -2739,7 +2903,7 @@ public class SuperTiles{
final TilePlanes.PlaneData[][][] rslt_planes = new TilePlanes.PlaneData[center_planes.length][][];
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final String [] titles= {"center", "first", "second", "all"};
final String [] titles= {"center", "first", "second", "all", "f-s"};
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
......@@ -2758,112 +2922,211 @@ public class SuperTiles{
int np0_min = (center_planes[nsTile0].length > 1) ? 1:0; // Modify if overall plane will be removed
for (int np0 = np0_min; np0 < center_planes[nsTile0].length; np0 ++){
TilePlanes.PlaneData center_plane = center_planes[nsTile0][np0];
if (dl > 0) dbg_img[ 0] = center_plane.getPlaneDisparity(false);
int [] neibs = center_plane.getNeibBest();
int num_neibs = 0;
for (int i = 0; i < neibs.length; i++) if (neibs[i] >= 0) num_neibs++;
if (num_neibs >= min_neibs) {
// create all pairs to test
int num_splits = num_neibs * (num_neibs - 1) / 2;
double [] split_quality = new double [num_splits]; // weighted sum of eigenvalues of merged
int [][][] neibs12 = new int [2][num_splits][];
TilePlanes.PlaneData[][] plane_triads = new TilePlanes.PlaneData[num_splits][3];
int [] neib_index = new int [num_neibs];
int nn = 0;
for (int i = 0; i < neibs.length; i++) if (neibs[i] >= 0) neib_index[nn++] = i;
nn = 0;
for (int nStart = 1; nStart < num_neibs; nStart++) {
for (int nEnd = nStart+1; nEnd <= num_neibs; nEnd++){
neibs12[0][nn] = neibs.clone();
neibs12[1][nn] = neibs.clone();
for (int i = 0; i < neib_index.length; i++) {
if ((i < nStart) || (i >= nEnd)){
neibs12[0][nn][neib_index[i]] = -1;
} else {
neibs12[1][nn][neib_index[i]] = -1;
if (center_plane.getWeight() >= splitMinWeight) {
if (dl > 0) dbg_img[ 0] = center_plane. getTriplePlaneDisparity();
int [] neibs = center_plane.getNeibBest();
int num_neibs = 0;
for (int i = 0; i < neibs.length; i++) if (neibs[i] >= 0) num_neibs++;
if (num_neibs >= min_neibs) {
// create all pairs to test
int num_splits = num_neibs * (num_neibs - 1) / 2;
double [] split_quality = new double [num_splits]; // weighted sum of eigenvalues of merged
int [][][] neibs12 = new int [2][num_splits][];
TilePlanes.PlaneData[][] plane_triads = new TilePlanes.PlaneData[num_splits][3];
int [] neib_index = new int [num_neibs];
int nn = 0;
for (int i = 0; i < neibs.length; i++) if (neibs[i] >= 0) neib_index[nn++] = i;
nn = 0;
for (int nStart = 1; nStart < num_neibs; nStart++) {
for (int nEnd = nStart+1; nEnd <= num_neibs; nEnd++){
neibs12[0][nn] = neibs.clone();
neibs12[1][nn] = neibs.clone();
for (int i = 0; i < neib_index.length; i++) {
if ((i < nStart) || (i >= nEnd)){
neibs12[0][nn][neib_index[i]] = -1;
} else {
neibs12[1][nn][neib_index[i]] = -1;
}
}
nn++;
}
nn++;
}
}
for (int nSplit = 0; nSplit < num_splits; nSplit++) {
// Calculate merged plane for each selection (and other), weighted average and store to split_quality
for (int nis = 0; nis < 2; nis++) {
plane_triads[nSplit][nis] = center_planes[nsTile0][np0].clone();
plane_triads[nSplit][nis].setWeight(center_pull * plane_triads[nSplit][nis].getWeight());
for (int dir = 0; dir <8; dir++){
int np = neibs12[nis][nSplit][dir];
if (np >= 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 = plane_triads[nSplit][nis].getPlaneToThis(
neib_planes[nsTile][np],
dl); // debugLevel);
// if (dl > 0) dbg_img[ 2 + dir] = other_plane.getPlaneDisparity(false);
if (other_plane != null){
if (plane_triads[nSplit][nis].getWeight() > 0.0){
plane_triads[nSplit][nis] = plane_triads[nSplit][nis].mergePlaneToThis(
other_plane, // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
preferDisparity,
dl); // int debugLevel)
for (int nSplit = 0; nSplit < num_splits; nSplit++) {
// Calculate merged plane for each selection (and other), weighted average and store to split_quality
for (int nis = 0; nis < 2; nis++) {
plane_triads[nSplit][nis] = center_planes[nsTile0][np0].clone();
plane_triads[nSplit][nis].scaleWeight(center_pull);
for (int dir = 0; dir <8; dir++){
int np = neibs12[nis][nSplit][dir];
if (np >= 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 = plane_triads[nSplit][nis].getPlaneToThis(
neib_planes[nsTile][np],
dl-1); // debugLevel);
// if (dl > 0) dbg_img[ 2 + dir] = other_plane.getPlaneDisparity(false);
if (other_plane != null){
if (plane_triads[nSplit][nis].getWeight() > 0.0){
plane_triads[nSplit][nis] = plane_triads[nSplit][nis].mergePlaneToThis(
other_plane, // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
dl-1); // int debugLevel)
} else {
plane_triads[nSplit][nis] = other_plane;
}
//if (dl > 0) dbg_img[10 + dir] = this_new_plane.getPlaneDisparity(false);
} else {
plane_triads[nSplit][nis] = other_plane;
plane_triads[nSplit][nis] = null;
break;
}
//if (dl > 0) dbg_img[10 + dir] = this_new_plane.getPlaneDisparity(false);
} else {
plane_triads[nSplit][nis] = null;
break;
}
}
} // for (int nis = 0; nis < 2; nis++) {
if ((plane_triads[nSplit][0] != null) && (plane_triads[nSplit][1] != null)){
double w1 = plane_triads[nSplit][0].getWeight();
double w2 = plane_triads[nSplit][1].getWeight();
split_quality[nSplit] = (w1 * plane_triads[nSplit][0].getValue() + w2 * plane_triads[nSplit][1].getValue())/
(w1 + w2);
if (dl >0){
plane_triads[nSplit][2] = plane_triads[nSplit][0].clone().mergePlaneToThis(
plane_triads[nSplit][1], // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
dl-1);
}
} else {
split_quality[nSplit] = Double.NaN;
}
if (dl >0){
System.out.println("breakPlanesToPairs(): split_quality["+nSplit+"] = "+split_quality[nSplit]);
}
} // for (int nis = 0; nis < 2; nis++) {
if ((plane_triads[nSplit][0] != null) && (plane_triads[nSplit][1] != null)){
double w1 = plane_triads[nSplit][0].getWeight();
double w2 = plane_triads[nSplit][1].getWeight();
split_quality[nSplit] = (w1 * plane_triads[nSplit][0].getValue() + w2 * plane_triads[nSplit][1].getValue())/
(w1 + w2);
} else {
split_quality[nSplit] = Double.NaN;
}
}
// find minimum in split_quality and generate a pair of plane objects, setting neighbors for each
// later use these plane pairs to assign tiles to each and generate a new eigenvalues/vectors
// TODO: How to handle a pair? Any special treatment (like fusing?),
// if the plane intersection line is inside supertile - use min/max for snapping
int best_index = -1;
for (int nSplit = 0; nSplit < num_splits; nSplit++) {
if (!Double.isNaN(split_quality[nSplit]) && ((best_index < 0) || (split_quality[nSplit] < split_quality[best_index]))){
best_index = nSplit;
// find minimum in split_quality and generate a pair of plane objects, setting neighbors for each
// later use these plane pairs to assign tiles to each and generate a new eigenvalues/vectors
// TODO: How to handle a pair? Any special treatment (like fusing?),
// if the plane intersection line is inside supertile - use min/max for snapping
int best_index = -1;
for (int nSplit = 0; nSplit < num_splits; nSplit++) {
if (!Double.isNaN(split_quality[nSplit]) && ((best_index < 0) || (split_quality[nSplit] < split_quality[best_index]))){
best_index = nSplit;
}
}
}
if (best_index >= 0) {
plane_triads[best_index][2] = plane_triads[best_index][0].clone().mergePlaneToThis(
plane_triads[best_index][1], // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
if (best_index >= 0) {
plane_triads[best_index][2] = plane_triads[best_index][0].clone().mergePlaneToThis(
plane_triads[best_index][1], // PlaneData otherPd,
1.0, // double scale_other,
false, // boolean ignore_weights,
true, // boolean sum_weights,
preferDisparity,
dl);
for (int nis = 0; nis < 2; nis++) {
plane_triads[best_index][nis].setNeibBest(neibs12[nis][best_index]);
dl-1);
// check quality
if ((plane_triads[best_index][2] != null) &&
(plane_triads[best_index][2].getValue()/split_quality[best_index] > splitMinQuality)) {
for (int nis = 0; nis < 2; nis++) {
plane_triads[best_index][nis].setNeibBest(neibs12[nis][best_index]);
}
rslt_planes[nsTile0][np0] = plane_triads[best_index];
if (dl > 0) {
int ss3 = 3 * superTileSize;
dbg_img[ 1] = plane_triads[best_index][0].getTriplePlaneDisparity();
dbg_img[ 2] = plane_triads[best_index][1].getTriplePlaneDisparity();
dbg_img[ 3] = plane_triads[best_index][2].getTriplePlaneDisparity();
dbg_img[ 4] = new double [dbg_img[ 1].length];
for (int i = 0; i< dbg_img[ 1].length; i++){
dbg_img[ 4][i] = dbg_img[ 1][i] - dbg_img[ 2][i];
}
int [] vby = new int [ss3];
double [] dbg_split = dbg_img[ 4];
for (int dx = 0; dx < ss3; dx ++){
vby[dx] = 0;
for (int dy = 1; dy < ss3; dy ++){
int indx = dy * ss3 + dx;
if (Math.abs(dbg_split[indx]) < Math.abs(dbg_split[vby[dx] * ss3 + dx])){
vby[dx] = dy; // indx;
}
}
}
for (int dy = 0; dy < ss3; dy ++){
int bx = 0;
for (int dx = 1; dx < ss3; dx ++){
if (Math.abs(dbg_split[dy * ss3 + dx]) < Math.abs(dbg_split[dy * ss3 + bx])){
bx = dx;
}
}
if ((bx > 0) && (bx < (ss3-1))) {
dbg_split[dy * ss3 + bx] = Double.NaN;
dbg_img[ 3][dy * ss3 + bx] = Double.NaN;
}
}
for (int dx = 0; dx < ss3; dx ++){
int by = vby[dx];
if ((by > 0) && (by < (ss3-1))) {
dbg_split[by * ss3 + dx] = Double.NaN;
dbg_img[ 3][by * ss3 + dx] = Double.NaN;
}
}
for (int dir = 0; dir <8; dir++){
int indx = (ss3 / 2) * (ss3 + 1);
int dindx = dirsYX[dir][0] * ss3 + dirsYX[dir][1];
for (int l = 0; l < (ss3 / 2 - 2); l++){
if ( l > 2){ // keep center not modified
if (plane_triads[best_index][0].getNeibBest(dir) >= 0){
dbg_img[ 1][indx] = Double.NaN;
}
if (plane_triads[best_index][1].getNeibBest(dir) >= 0){
dbg_img[ 2][indx] = Double.NaN;
}
}
indx += dindx;
}
}
System.out.println("breakPlanesToPairs(): num_splits="+num_splits+", best_index="+best_index);
for (int nSplit = 0; nSplit < num_splits; nSplit++) {
if ((plane_triads[nSplit][0] != null) && (plane_triads[nSplit][1] != null) && (plane_triads[nSplit][2] != null)){
System.out.print("breakPlanesToPairs():"+nSplit+" ");
for (int dir = 0; dir < 8; dir++){
System.out.print((neibs12[0][nSplit][dir] >=0)?"+":"-");
}
System.out.print(" ");
for (int dir = 0; dir < 8; dir++){
System.out.print((neibs12[1][nSplit][dir] >=0)?"+":"-");
}
System.out.print(" ");
for (int dir = 0; dir < 8; dir++){
System.out.print((plane_triads[nSplit][2].getNeibBest(dir) >=0)?"+":"-");
}
System.out.println(" : "+split_quality[nSplit]+
" "+plane_triads[nSplit][0].getValue()+
" "+plane_triads[nSplit][1].getValue()+
" "+plane_triads[nSplit][2].getValue()+
" w"+plane_triads[nSplit][0].getWeight()+
" w"+plane_triads[nSplit][1].getWeight()+
" w"+plane_triads[nSplit][2].getWeight()
);
}
}
// merged_eig_val are not set - will have to be recalculated when updating after changing tile selections
// to make each plane
// TODO save gain from splitting to planes
if (debugLevel > -1){
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(dbg_img, 3*superTileSize, 3*superTileSize, true, "breakPlanesToPairs"+stx0+"_y"+sty0+"_p"+np0, titles);
}
}
}
}
rslt_planes[nsTile0][np0] = plane_triads[best_index];
if (dl > 0) dbg_img[ 1] = plane_triads[best_index][0].getPlaneDisparity(false);
if (dl > 0) dbg_img[ 2] = plane_triads[best_index][1].getPlaneDisparity(false);
if (dl > 0) dbg_img[ 3] = plane_triads[best_index][2].getPlaneDisparity(false);
// merged_eig_val are not set - will have to be recalculated when updating after changing tile selections
// to make each plane
// TODO save gain from splitting to planes
}
if ((dl > 0) && (debugLevel > -1)){
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(dbg_img, superTileSize, superTileSize, true, "breakPlanesToPairs"+stx0+"_y"+sty0+"_p"+np0, titles);
}
}
}
......
......@@ -281,6 +281,10 @@ public class TilePlanes {
public void setWeight(double weight) {
this.weight = weight;
}
public void scaleWeight(double scale) {
this.weight *= scale;
}
public double [] getWorldXYZ(boolean correct_distortions)
{
return getWorldXYZ(correct_distortions,0);
......@@ -457,6 +461,7 @@ public class TilePlanes {
PlaneData otherPd,
double scale_other,
boolean ignore_weights,
boolean sum_weights,
boolean preferDisparity, // Always start with disparity-most axis (false - lowest eigenvalue)
int debugLevel)
{
......@@ -608,7 +613,12 @@ public class TilePlanes {
pd.setZxy(common_center.getColumnPackedCopy()); // set new center
// what weight to use? cloned is original weight for this supertile
// or use weighted average like below?
pd.setWeight(other_fraction * otherPd.weight + (1.0 - other_fraction) * this.weight);
if (sum_weights) {
pd.setWeight(sum_weight); // normalize while averaging by the caller
} else { // how it was before
pd.setWeight(other_fraction * otherPd.weight + (1.0 - other_fraction) * this.weight);
}
return pd;
}
......@@ -968,9 +978,9 @@ 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;
}
// if (Math.abs(covar.det()) < mindet){
// debugLevel = 5;
// }
EigenvalueDecomposition eig = covar.eig();
if (Double.isNaN(eig.getV().get(0, 0))){
......@@ -978,9 +988,9 @@ public class TilePlanes {
debugLevel = 20;
}
if (eig.getD().get(0, 0) == 0.0){
debugLevel = 10;
}
// 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);
......@@ -1014,7 +1024,7 @@ public class TilePlanes {
select = new boolean [4*stSize];
for (int i = 0; i < select.length; i++) select[i] = true;
}
int debugLevel1 = ((sTileXY[0] == 27) && (sTileXY[1] == 16))? 1: 0; // check why v[0][0] <0
// int debugLevel1 = ((sTileXY[0] == 27) && (sTileXY[1] == 16))? 1: 0; // check why v[0][0] <0
double [][][] rslt = getCovar(
......@@ -1022,7 +1032,7 @@ public class TilePlanes {
weight,
select,
0.0,
debugLevel1); //0); // debugLevel);
0); // debugLevel1); //0); // debugLevel);
if (rslt == null) return null;
int numPoints = (int) rslt[2][0][2];
double swc = rslt[2][0][0];
......
......@@ -2940,6 +2940,7 @@ public class TileProcessor {
final boolean updateStatus,
final int debugLevel)
{
trimCLTPasses(); // make possible to run this method multiple time - remove extra passes added by it last time
CLTPass3d scan_prev = clt_3d_passes.get(clt_3d_passes.size() -1); // get last one
SuperTiles st = scan_prev.getSuperTiles();
......@@ -3002,7 +3003,9 @@ public class TileProcessor {
st.resetPlanesMod(); // clean start
planes_mod = st.planesSmooth(
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,
clt_parameters.plStopBad, //Do not update supertile if any of connected neighbors is not good (false: just skip that neighbor)
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)
......@@ -3042,15 +3045,25 @@ public class TileProcessor {
TilePlanes.PlaneData[][][] split_planes =
st.breakPlanesToPairs(
st.getPlanes(), // Mod(), // final TilePlanes.PlaneData[][] center_planes, // measured_planes,
st.getPlanes(), // Mod(), // final TilePlanes.PlaneData[][] neib_planes, //mod_planes,
clt_parameters.plSplitPull , // final double center_pull,
clt_parameters.plSplitMinNeib , // min_neibs, // 2
st.getPlanes(), // Mod(), // final TilePlanes.PlaneData[][] neib_planes, //mod_planes,
clt_parameters.plSplitPull , // final double center_pull,
clt_parameters.plSplitMinNeib , // min_neibs, // 2
clt_parameters.plSplitMinWeight, // final double splitMinWeight, // = 2.0; // Minimal weight of split plains to show
clt_parameters.plSplitMinQuality, // final double splitMinQuality, // = 1.1; // Minimal split quality to show
clt_parameters.plPreferDisparity,
1, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
if (clt_parameters.show_planes){
double [] split_lines = st.showSplitLines(
split_planes,
1, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
int [] wh = st.getShowPlanesWidthHeight();
double [][] plane_data_nonan = st.getShowPlanes(
(planes_mod != null) ? st.getPlanesMod():st.getPlanes(),
......@@ -3068,7 +3081,7 @@ public class TileProcessor {
true, //boolean use_NaN)
0.0,
10.0);
double [][] plane_data = new double [plane_data_nonan.length + plane_data_nan.length][];
double [][] plane_data = new double [plane_data_nonan.length + plane_data_nan.length + 2][];
int indx = 0;
for (int i = 0; i < plane_data_nonan.length; i++){
plane_data[indx++] = plane_data_nonan[i];
......@@ -3076,6 +3089,13 @@ public class TileProcessor {
for (int i = 0; i < plane_data_nan.length; i++){
plane_data[indx++] = plane_data_nan[i];
}
plane_data[indx++] = split_lines;
plane_data[indx] = plane_data[indx-2].clone();
for (int i = 0; i < plane_data[indx].length;i++){
if (Double.isNaN(plane_data[indx][i])) plane_data[indx][i] = 0.0;
if (plane_data[indx-1][i] > 0) plane_data[indx][i] = Double.NaN;
}
sdfa_instance.showArrays(plane_data, wh[0], wh[1], true, "plane_data");
plane_data = st.getShowShells(
......
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