Commit 076baece authored by Andrey Filippov's avatar Andrey Filippov

Working on tiles assignment to planes

parent 9cfff83b
...@@ -2326,6 +2326,15 @@ public class EyesisCorrectionParameters { ...@@ -2326,6 +2326,15 @@ public class EyesisCorrectionParameters {
public double tsMaxSurStrength = 0.05; // Maximal strength of the surrounded unassigned tile to join public double tsMaxSurStrength = 0.05; // Maximal strength of the surrounded unassigned tile to join
public boolean tsCountDis = true; // Include disabled tiles/borders when counting assigned neighbors public boolean tsCountDis = true; // Include disabled tiles/borders when counting assigned neighbors
public boolean tsEnPlaneSeed = true; // Assign tiles that were used to generate planes
public boolean tsEnOnly = true; // Allow assignment only surface
public boolean tsEnGrow = true; // Grow the only surface assignments
public double tsGrowStrength = 0.01; // Maximal strength when growing the only surfaces
public boolean tsGrowStrong = true; // Grow over strong if disparity matches
public double tsContStrength = 0.1; // Minimal strength to continue grow with disparity match
public double tsContDiff = 0.1; // Maximal normalized disparity error to grow over strong tiles
public boolean tsEnSingle = true; // Allow assignment to the nearest surface with no competitors public boolean tsEnSingle = true; // Allow assignment to the nearest surface with no competitors
public boolean tsEnMulti = true; // Allow assignment when several surfaces fit public boolean tsEnMulti = true; // Allow assignment when several surfaces fit
...@@ -2336,7 +2345,11 @@ public class EyesisCorrectionParameters { ...@@ -2336,7 +2345,11 @@ public class EyesisCorrectionParameters {
public boolean tsLoopMulti = true; // Repeat multi-choice assignment while succeeding public boolean tsLoopMulti = true; // Repeat multi-choice assignment while succeeding
public boolean tsReset = false; // Reset tiles to surfaces assignment public boolean tsReset = false; // Reset tiles to surfaces assignment
public boolean tsShow = false; // Show results of tiles to surfaces assignment public boolean tsShow = false; // Show results of tiles to surfaces assignment
public int tsNumClust = 50; // Number of clusters to keep public int tsNumClust = 50; // Number of clusters to keep
public int tsConsensMode = 7; // Which assignments to match +1 - combo, +2 grown single, +4 plane seeds
public int tsConsensAgree = 1; // Minimal number of assignments to agree
public boolean replaceWeakOutlayers = true; // false; public boolean replaceWeakOutlayers = true; // false;
...@@ -2743,6 +2756,15 @@ public class EyesisCorrectionParameters { ...@@ -2743,6 +2756,15 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"tsMinNeib", this.tsMinNeib +""); properties.setProperty(prefix+"tsMinNeib", this.tsMinNeib +"");
properties.setProperty(prefix+"tsMaxSurStrength", this.tsMaxSurStrength +""); properties.setProperty(prefix+"tsMaxSurStrength", this.tsMaxSurStrength +"");
properties.setProperty(prefix+"tsCountDis", this.tsCountDis +""); properties.setProperty(prefix+"tsCountDis", this.tsCountDis +"");
properties.setProperty(prefix+"tsEnPlaneSeed", this.tsEnPlaneSeed+"");
properties.setProperty(prefix+"tsEnOnly", this.tsEnOnly+"");
properties.setProperty(prefix+"tsEnGrow", this.tsEnGrow+"");
properties.setProperty(prefix+"tsGrowStrength", this.tsGrowStrength +"");
properties.setProperty(prefix+"tsGrowStrong", this.tsGrowStrong+"");
properties.setProperty(prefix+"tsContStrength", this.tsContStrength +"");
properties.setProperty(prefix+"tsContDiff", this.tsContDiff +"");
properties.setProperty(prefix+"tsEnSingle", this.tsEnSingle+""); properties.setProperty(prefix+"tsEnSingle", this.tsEnSingle+"");
properties.setProperty(prefix+"tsEnMulti", this.tsEnMulti+""); properties.setProperty(prefix+"tsEnMulti", this.tsEnMulti+"");
properties.setProperty(prefix+"tsRemoveWeak1", this.tsRemoveWeak1+""); properties.setProperty(prefix+"tsRemoveWeak1", this.tsRemoveWeak1+"");
...@@ -2752,6 +2774,9 @@ public class EyesisCorrectionParameters { ...@@ -2752,6 +2774,9 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"tsShow", this.tsShow+""); properties.setProperty(prefix+"tsShow", this.tsShow+"");
properties.setProperty(prefix+"tsNumClust", this.tsNumClust +""); properties.setProperty(prefix+"tsNumClust", this.tsNumClust +"");
properties.setProperty(prefix+"tsConsensMode", this.tsConsensMode +"");
properties.setProperty(prefix+"tsConsensAgree", this.tsConsensAgree +"");
properties.setProperty(prefix+"dbg_migrate", this.dbg_migrate+""); properties.setProperty(prefix+"dbg_migrate", this.dbg_migrate+"");
properties.setProperty(prefix+"show_ortho_combine", this.show_ortho_combine+""); properties.setProperty(prefix+"show_ortho_combine", this.show_ortho_combine+"");
...@@ -3150,6 +3175,15 @@ public class EyesisCorrectionParameters { ...@@ -3150,6 +3175,15 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"tsMinNeib")!=null) this.tsMinNeib=Integer.parseInt(properties.getProperty(prefix+"tsMinNeib")); if (properties.getProperty(prefix+"tsMinNeib")!=null) this.tsMinNeib=Integer.parseInt(properties.getProperty(prefix+"tsMinNeib"));
if (properties.getProperty(prefix+"tsMaxSurStrength")!=null) this.tsMaxSurStrength=Double.parseDouble(properties.getProperty(prefix+"tsMaxSurStrength")); if (properties.getProperty(prefix+"tsMaxSurStrength")!=null) this.tsMaxSurStrength=Double.parseDouble(properties.getProperty(prefix+"tsMaxSurStrength"));
if (properties.getProperty(prefix+"tsCountDis")!=null) this.tsCountDis=Boolean.parseBoolean(properties.getProperty(prefix+"tsCountDis")); if (properties.getProperty(prefix+"tsCountDis")!=null) this.tsCountDis=Boolean.parseBoolean(properties.getProperty(prefix+"tsCountDis"));
if (properties.getProperty(prefix+"tsEnPlaneSeed")!=null) this.tsEnOnly=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnPlaneSeed"));
if (properties.getProperty(prefix+"tsEnOnly")!=null) this.tsEnOnly=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnOnly"));
if (properties.getProperty(prefix+"tsEnGrow")!=null) this.tsEnOnly=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnGrow"));
if (properties.getProperty(prefix+"tsGrowStrength")!=null) this.tsGrowStrength=Double.parseDouble(properties.getProperty(prefix+"tsGrowStrength"));
if (properties.getProperty(prefix+"tsGrowStrong")!=null) this.tsGrowStrong=Boolean.parseBoolean(properties.getProperty(prefix+"tsGrowStrong"));
if (properties.getProperty(prefix+"tsContStrength")!=null) this.tsGrowStrength=Double.parseDouble(properties.getProperty(prefix+"tsContStrength"));
if (properties.getProperty(prefix+"tsContDiff")!=null) this.tsContDiff=Double.parseDouble(properties.getProperty(prefix+"tsContDiff"));
if (properties.getProperty(prefix+"tsEnSingle")!=null) this.tsEnSingle=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnSingle")); if (properties.getProperty(prefix+"tsEnSingle")!=null) this.tsEnSingle=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnSingle"));
if (properties.getProperty(prefix+"tsEnMulti")!=null) this.tsEnMulti=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnMulti")); if (properties.getProperty(prefix+"tsEnMulti")!=null) this.tsEnMulti=Boolean.parseBoolean(properties.getProperty(prefix+"tsEnMulti"));
if (properties.getProperty(prefix+"tsRemoveWeak1")!=null) this.tsRemoveWeak1=Boolean.parseBoolean(properties.getProperty(prefix+"tsRemoveWeak1")); if (properties.getProperty(prefix+"tsRemoveWeak1")!=null) this.tsRemoveWeak1=Boolean.parseBoolean(properties.getProperty(prefix+"tsRemoveWeak1"));
...@@ -3160,6 +3194,8 @@ public class EyesisCorrectionParameters { ...@@ -3160,6 +3194,8 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"tsShow")!=null) this.tsShow=Boolean.parseBoolean(properties.getProperty(prefix+"tsShow")); if (properties.getProperty(prefix+"tsShow")!=null) this.tsShow=Boolean.parseBoolean(properties.getProperty(prefix+"tsShow"));
if (properties.getProperty(prefix+"tsNumClust")!=null) this.tsNumClust=Integer.parseInt(properties.getProperty(prefix+"tsNumClust")); if (properties.getProperty(prefix+"tsNumClust")!=null) this.tsNumClust=Integer.parseInt(properties.getProperty(prefix+"tsNumClust"));
if (properties.getProperty(prefix+"tsConsensMode")!=null) this.tsConsensMode=Integer.parseInt(properties.getProperty(prefix+"tsConsensMode"));
if (properties.getProperty(prefix+"tsConsensAgree")!=null) this.tsConsensAgree=Integer.parseInt(properties.getProperty(prefix+"tsConsensAgree"));
if (properties.getProperty(prefix+"dbg_migrate")!=null) this.dbg_migrate=Boolean.parseBoolean(properties.getProperty(prefix+"dbg_migrate")); if (properties.getProperty(prefix+"dbg_migrate")!=null) this.dbg_migrate=Boolean.parseBoolean(properties.getProperty(prefix+"dbg_migrate"));
...@@ -3590,6 +3626,15 @@ public class EyesisCorrectionParameters { ...@@ -3590,6 +3626,15 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Minimal number of neighbors of unassigned tile to join (the farthest)", this.tsMinNeib, 0); gd.addNumericField("Minimal number of neighbors of unassigned tile to join (the farthest)", this.tsMinNeib, 0);
gd.addNumericField("Maximal strength of the surrounded unassigned tile to join", this.tsMaxSurStrength, 6); gd.addNumericField("Maximal strength of the surrounded unassigned tile to join", this.tsMaxSurStrength, 6);
gd.addCheckbox ("Include disabled tiles/borders when counting assigned neighbors", this.tsCountDis); gd.addCheckbox ("Include disabled tiles/borders when counting assigned neighbors", this.tsCountDis);
gd.addCheckbox ("Assign tiles that were used to generate planes", this.tsEnPlaneSeed);
gd.addCheckbox ("Allow assignment only surface", this.tsEnOnly);
gd.addCheckbox ("Grow the only surface assignments", this.tsEnGrow);
gd.addNumericField("Maximal strength when growing the only surfaces", this.tsGrowStrength, 6);
gd.addCheckbox ("Grow over strong if disparity matches", this.tsGrowStrong);
gd.addNumericField("Minimal strength to continue grow with disparity match", this.tsContStrength, 6);
gd.addNumericField("Maximal normalized disparity error to grow over strong tiles", this.tsContDiff, 6);
gd.addCheckbox ("Allow assignment to the nearest surface with no competitors", this.tsEnSingle); gd.addCheckbox ("Allow assignment to the nearest surface with no competitors", this.tsEnSingle);
gd.addCheckbox ("Allow assignment when several surfaces fit", this.tsEnMulti); gd.addCheckbox ("Allow assignment when several surfaces fit", this.tsEnMulti);
gd.addCheckbox ("Remove weak clusters before growing", this.tsRemoveWeak1); gd.addCheckbox ("Remove weak clusters before growing", this.tsRemoveWeak1);
...@@ -3600,6 +3645,9 @@ public class EyesisCorrectionParameters { ...@@ -3600,6 +3645,9 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Show results of tiles to surfaces assignment", this.tsShow); gd.addCheckbox ("Show results of tiles to surfaces assignment", this.tsShow);
gd.addNumericField("Number of clusters to keep", this.tsNumClust, 0); gd.addNumericField("Number of clusters to keep", this.tsNumClust, 0);
gd.addNumericField("Which assignments to match +1 - combo, +2 grown single, +4 plane seeds", this.tsConsensMode, 0);
gd.addNumericField("Minimal number of assignments to agree", this.tsConsensAgree, 0);
gd.addCheckbox ("Test new mode after migration", this.dbg_migrate); gd.addCheckbox ("Test new mode after migration", this.dbg_migrate);
gd.addMessage ("--- Other debug images ---"); gd.addMessage ("--- Other debug images ---");
...@@ -4006,6 +4054,15 @@ public class EyesisCorrectionParameters { ...@@ -4006,6 +4054,15 @@ public class EyesisCorrectionParameters {
this.tsMaxSurStrength= gd.getNextNumber(); this.tsMaxSurStrength= gd.getNextNumber();
this.tsCountDis= gd.getNextBoolean(); this.tsCountDis= gd.getNextBoolean();
this.tsReset = false; // Reset tiles to surfaces assignment this.tsReset = false; // Reset tiles to surfaces assignment
this.tsEnPlaneSeed= gd.getNextBoolean();
this.tsEnOnly= gd.getNextBoolean();
this.tsEnGrow= gd.getNextBoolean();
this.tsGrowStrength= gd.getNextNumber();
this.tsGrowStrong= gd.getNextBoolean();
this.tsContStrength= gd.getNextNumber();
this.tsContDiff= gd.getNextNumber();
this.tsEnSingle= gd.getNextBoolean(); this.tsEnSingle= gd.getNextBoolean();
this.tsEnMulti= gd.getNextBoolean(); this.tsEnMulti= gd.getNextBoolean();
this.tsRemoveWeak1= gd.getNextBoolean(); this.tsRemoveWeak1= gd.getNextBoolean();
...@@ -4015,7 +4072,10 @@ public class EyesisCorrectionParameters { ...@@ -4015,7 +4072,10 @@ public class EyesisCorrectionParameters {
this.tsLoopMulti= gd.getNextBoolean(); this.tsLoopMulti= gd.getNextBoolean();
this.tsShow = gd.getNextBoolean(); this.tsShow = gd.getNextBoolean();
this.tsNumClust = (int) gd.getNextNumber(); this.tsNumClust = (int) gd.getNextNumber();
this.tsConsensMode = (int) gd.getNextNumber();
this.tsConsensAgree = (int) gd.getNextNumber();
this.dbg_migrate= gd.getNextBoolean(); this.dbg_migrate= gd.getNextBoolean();
this.show_ortho_combine= gd.getNextBoolean(); this.show_ortho_combine= gd.getNextBoolean();
...@@ -4049,7 +4109,7 @@ public class EyesisCorrectionParameters { ...@@ -4049,7 +4109,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Add to strengths when calculating pull of assigned tiles", this.tsAddStrength, 6); gd.addNumericField("Add to strengths when calculating pull of assigned tiles", this.tsAddStrength, 6);
gd.addNumericField("Radius of influence (in tiles) of the previously assigned tiles", this.tsSigma, 6); gd.addNumericField("Radius of influence (in tiles) of the previously assigned tiles", this.tsSigma, 6);
gd.addNumericField("Maximal relative to radius distance to calculate influence", this.tsNSigma, 6); gd.addNumericField("Maximal relative to radius distance to calculate influence", this.tsNSigma, 6);
gd.addNumericField(" Additional pull of each surface ", this.tsMinPull, 6); gd.addNumericField("Additional pull of each surface ", this.tsMinPull, 6);
gd.addNumericField("Minimal ratio of the best surface candidate to the next one to make selection", this.tsMinAdvantage, 6); gd.addNumericField("Minimal ratio of the best surface candidate to the next one to make selection", this.tsMinAdvantage, 6);
gd.addNumericField("Minimal size of a cluster to keep", this.tsClustSize, 0); gd.addNumericField("Minimal size of a cluster to keep", this.tsClustSize, 0);
gd.addNumericField("Minimal total weight of a cluster to keep", this.tsClustWeight, 6); gd.addNumericField("Minimal total weight of a cluster to keep", this.tsClustWeight, 6);
...@@ -4057,6 +4117,15 @@ public class EyesisCorrectionParameters { ...@@ -4057,6 +4117,15 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Maximal strength of the surrounded unassigned tile to join", this.tsMaxSurStrength, 6); gd.addNumericField("Maximal strength of the surrounded unassigned tile to join", this.tsMaxSurStrength, 6);
gd.addCheckbox ("Include disabled tiles/borders when counting assigned neighbors", this.tsCountDis); gd.addCheckbox ("Include disabled tiles/borders when counting assigned neighbors", this.tsCountDis);
gd.addCheckbox ("Reset tiles to surfaces assignment", false); gd.addCheckbox ("Reset tiles to surfaces assignment", false);
gd.addCheckbox ("Assign tiles that were used to generate planes", this.tsEnPlaneSeed);
gd.addCheckbox ("Allow assignment only surface", this.tsEnOnly);
gd.addCheckbox ("Grow the only surface assignments", this.tsEnGrow);
gd.addNumericField("Maximal strength when growing the only surfaces", this.tsGrowStrength, 6);
gd.addCheckbox ("Grow over strong if disparity matches", this.tsGrowStrong);
gd.addNumericField("Minimal strength to continue grow with disparity match", this.tsContStrength, 6);
gd.addNumericField("Maximal normalized disparity error to grow over strong tiles", this.tsContDiff, 6);
gd.addCheckbox ("Allow assignment to the nearest surface with no competitors", this.tsEnSingle); gd.addCheckbox ("Allow assignment to the nearest surface with no competitors", this.tsEnSingle);
gd.addCheckbox ("Allow assignment when several surfaces fit", this.tsEnMulti); gd.addCheckbox ("Allow assignment when several surfaces fit", this.tsEnMulti);
gd.addCheckbox ("Remove weak clusters before growing", this.tsRemoveWeak1); gd.addCheckbox ("Remove weak clusters before growing", this.tsRemoveWeak1);
...@@ -4066,6 +4135,10 @@ public class EyesisCorrectionParameters { ...@@ -4066,6 +4135,10 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Repeat multi-choice assignment while succeeding", this.tsLoopMulti); gd.addCheckbox ("Repeat multi-choice assignment while succeeding", this.tsLoopMulti);
gd.addCheckbox ("Show results of tiles to surfaces assignment", this.tsShow); gd.addCheckbox ("Show results of tiles to surfaces assignment", this.tsShow);
gd.addNumericField("Number of clusters to keep", this.tsNumClust, 0); gd.addNumericField("Number of clusters to keep", this.tsNumClust, 0);
gd.addNumericField("Which assignments to match +1 - combo, +2 grown single, +4 plane seeds", this.tsConsensMode, 0);
gd.addNumericField("Minimal number of assignments to agree", this.tsConsensAgree, 0);
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
...@@ -4091,6 +4164,15 @@ public class EyesisCorrectionParameters { ...@@ -4091,6 +4164,15 @@ public class EyesisCorrectionParameters {
this.tsMaxSurStrength= gd.getNextNumber(); this.tsMaxSurStrength= gd.getNextNumber();
this.tsCountDis= gd.getNextBoolean(); this.tsCountDis= gd.getNextBoolean();
this.tsReset= gd.getNextBoolean(); this.tsReset= gd.getNextBoolean();
this.tsEnPlaneSeed= gd.getNextBoolean();
this.tsEnOnly= gd.getNextBoolean();
this.tsEnGrow= gd.getNextBoolean();
this.tsGrowStrength= gd.getNextNumber();
this.tsGrowStrong= gd.getNextBoolean();
this.tsContStrength= gd.getNextNumber();
this.tsContDiff= gd.getNextNumber();
this.tsEnSingle= gd.getNextBoolean(); this.tsEnSingle= gd.getNextBoolean();
this.tsEnMulti= gd.getNextBoolean(); this.tsEnMulti= gd.getNextBoolean();
this.tsRemoveWeak1= gd.getNextBoolean(); this.tsRemoveWeak1= gd.getNextBoolean();
...@@ -4098,8 +4180,11 @@ public class EyesisCorrectionParameters { ...@@ -4098,8 +4180,11 @@ public class EyesisCorrectionParameters {
this.tsRemoveWeak2= gd.getNextBoolean(); this.tsRemoveWeak2= gd.getNextBoolean();
this.tsLoopMulti= gd.getNextBoolean(); this.tsLoopMulti= gd.getNextBoolean();
this.tsShow = gd.getNextBoolean(); this.tsShow = gd.getNextBoolean();
this.tsNumClust= (int) gd.getNextNumber(); this.tsNumClust= (int) gd.getNextNumber();
this.tsConsensMode = (int) gd.getNextNumber();
this.tsConsensAgree = (int) gd.getNextNumber();
return true; return true;
} }
......
/** /**
** **
** SurfaceData - represents rectangualar area with per-tile disparity ** SurfaceData - represents rectangular area with per-tile disparity
** **
** Copyright (C) 2017 Elphel, Inc. ** Copyright (C) 2017 Elphel, Inc.
** **
......
...@@ -104,7 +104,7 @@ public class TilePlanes { ...@@ -104,7 +104,7 @@ public class TilePlanes {
boolean preferDisparity = false; boolean preferDisparity = false;
// alternative "plane" calcualtions in the world coordinates // alternative "plane" calculations in the world coordinates
double [] wxyz = null; // [3] - plane center point when calculated in world coordinates (x, y , z) double [] wxyz = null; // [3] - plane center point when calculated in world coordinates (x, y , z)
double [][] wvectors = null; // [3][3] - eigenvectors calculated in the real world double [][] wvectors = null; // [3][3] - eigenvectors calculated in the real world
double [] wvalues = null; // [3] -eigenvalues calculated in the real world double [] wvalues = null; // [3] -eigenvalues calculated in the real world
...@@ -3607,7 +3607,11 @@ public class TilePlanes { ...@@ -3607,7 +3607,11 @@ public class TilePlanes {
} }
copyNeib(this, pd); copyNeib(this, pd);
pd.num_points = otherPd.num_points; // restore, maybe remove from copy_neib? pd.num_points = otherPd.num_points; // restore, maybe remove from copy_neib?
// copy other data from this tile
pd.setMeasSelection(this.measuredSelection);
if (this.measuredLayers != null) pd.measuredLayers = this.measuredLayers;
if (this.sel_mask != null) pd.sel_mask = this.sel_mask.clone();
copyStar(this,pd);
return pd; // make sure pd are updated // "this" is not used. Should it be used instead of pd? return pd; // make sure pd are updated // "this" is not used. Should it be used instead of pd?
} }
......
...@@ -3128,7 +3128,7 @@ public class TileProcessor { ...@@ -3128,7 +3128,7 @@ public class TileProcessor {
final boolean updateStatus, final boolean updateStatus,
final int debugLevel) final int debugLevel)
{ {
trimCLTPasses(); // make possible to run this method multiple time - remove extra passes added by it last time trimCLTPasses(); // make possible to run this method multiple times - remove extra passes added by it last time
CLTPass3d scan_prev = clt_3d_passes.get(clt_3d_passes.size() -1); // get last one CLTPass3d scan_prev = clt_3d_passes.get(clt_3d_passes.size() -1); // get last one
// boolean show_st = clt_parameters.stShow || (debugLevel > 1); // boolean show_st = clt_parameters.stShow || (debugLevel > 1);
SuperTiles st = scan_prev.getSuperTiles(); SuperTiles st = scan_prev.getSuperTiles();
...@@ -3136,10 +3136,11 @@ public class TileProcessor { ...@@ -3136,10 +3136,11 @@ public class TileProcessor {
if (tileSurface == null){ if (tileSurface == null){
return false; return false;
} }
/*
tileSurface.testSimpleConnected( tileSurface.testSimpleConnected(
230, // clt_parameters.tileX, 230, // clt_parameters.tileX,
131);//clt_parameters.tileY); 131);//clt_parameters.tileY);
*/
double [][][] dispStrength = st.getDisparityStrengths( double [][][] dispStrength = st.getDisparityStrengths(
clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert) clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
...@@ -3148,14 +3149,88 @@ public class TileProcessor { ...@@ -3148,14 +3149,88 @@ public class TileProcessor {
clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert) clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
// Reset/initialize assignments - if not done so yet or specifically requested // Reset/initialize assignments - if not done so yet or specifically requested
boolean first_run = !tileSurface.isInit() || clt_parameters.tsReset;
tileSurface.InitTilesAssignment( tileSurface.InitTilesAssignment(
clt_parameters.tsReset, clt_parameters.tsReset,
dispStrength, // final double [][][] dispStrength, dispStrength, // final double [][][] dispStrength,
tileSel, // final boolean [][] tileSel, tileSel, // final boolean [][] tileSel,
debugLevel); // final int debugLevel, debugLevel); // final int debugLevel,
// assign tiles that do not depend on other assigned tiles - single pass // assign tiles that do not depend on other assigned tiles - single pass
int [][] tile_layers = tileSurface.getTileLayersCopy();
int [][] tile_layers_single_surf = tileSurface.newTileLayers(tileSel); // final boolean [][] tileSel,)
int [][] tile_layers_planes = tileSurface.newTileLayers(tileSel); // final boolean [][] tileSel,)
int [] stats_single_surf= tileSurface.assignTilesToSingleSurface(
tile_layers_single_surf, //final int [][] tileLayers,
clt_parameters.tsNoEdge , // final boolean noEdge,
0, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
System.out.print("Assign the only surface :");
tileSurface.printStats(stats_single_surf);
// grow the only surface assignments
if (clt_parameters.tsEnGrow){
double [] growStrengths = new double [tile_layers_single_surf.length];
double [] contMinStrengths = new double [tile_layers_single_surf.length];
double [] growMaxDiffFar = new double [tile_layers_single_surf.length];
double [] growMaxDiffNear = new double [tile_layers_single_surf.length];
int [][] assign_conflicts = null;
for (int i = 0; i < growStrengths.length; i++){
growStrengths[i] = clt_parameters.tsGrowStrength; // save all the same, later can use different for different types of correlation
contMinStrengths[i] = clt_parameters.tsContStrength;
growMaxDiffFar[i]= clt_parameters.tsContDiff;
growMaxDiffNear[i]= clt_parameters.tsContDiff;
if ((tile_layers_single_surf[i] != null) && (assign_conflicts == null)){
assign_conflicts = new int[tile_layers_single_surf[i].length][];
}
}
stats_single_surf = tileSurface.growWeakAssigned(
tile_layers_single_surf, //final int [][] tileLayers,
assign_conflicts, // final int [][] conflicts,
clt_parameters.tsNoEdge , // final boolean noEdge,
growStrengths, // final double [] maxStrength,
(clt_parameters.tsGrowStrong? contMinStrengths: null), //final double [] minStrengthContinue,
(clt_parameters.tsEnGrow? growMaxDiffFar: null), // final double [] maxDiffFar, // null
(clt_parameters.tsEnGrow? growMaxDiffNear: null), // final double [] maxDiffNear, // null
clt_parameters.plDispNorm, // final double dispNorm, // disparity normalize (proportionally scale down disparity difference if above
dispStrength, // final double [][][] dispStrength,
2, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
System.out.print("growWeakAssigned():");
tileSurface.printStats(stats_single_surf);
}
int [] stats_planes = tileSurface.assignPlanesTiles(
true, // final boolean force,
tile_layers_planes, //final int [][] tileLayers,
st.planes_mod, // final TilePlanes.PlaneData[][] planes,
2, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
System.out.print("assignPlanesTiles():");
tileSurface.printStats(stats_planes);
if (clt_parameters.tsEnOnly){
tileSurface.combineTileLayers(
true, // final boolean overwrite,
tile_layers, // final int [][] dst,
tile_layers_single_surf); // final int [][] src);
}
if (clt_parameters.tsEnPlaneSeed) {
tileSurface.combineTileLayers(
true, // final boolean overwrite,
tile_layers, // final int [][] dst,
tile_layers_planes); // final int [][] src);
}
if (clt_parameters.tsEnSingle) { if (clt_parameters.tsEnSingle) {
int [] stats= tileSurface.assignTilesToSurfaces( int [] stats= tileSurface.assignTilesToSurfaces(
tile_layers, //final int [][] tileLayers,
clt_parameters.tsNoEdge , // final boolean noEdge, clt_parameters.tsNoEdge , // final boolean noEdge,
clt_parameters.tsUseCenter, // final boolean useCenter, clt_parameters.tsUseCenter, // final boolean useCenter,
clt_parameters.tsMaxDiff, //final double maxDiff, clt_parameters.tsMaxDiff, //final double maxDiff,
...@@ -3185,6 +3260,7 @@ public class TileProcessor { ...@@ -3185,6 +3260,7 @@ public class TileProcessor {
if (clt_parameters.tsEnMulti) { if (clt_parameters.tsEnMulti) {
for (int nTry = 0; nTry < 100; nTry++) { for (int nTry = 0; nTry < 100; nTry++) {
int [] stats= tileSurface.assignTilesToSurfaces( int [] stats= tileSurface.assignTilesToSurfaces(
tile_layers, //final int [][] tileLayers,
clt_parameters.tsNoEdge , // final boolean noEdge, clt_parameters.tsNoEdge , // final boolean noEdge,
clt_parameters.tsUseCenter, // final boolean useCenter, clt_parameters.tsUseCenter, // final boolean useCenter,
clt_parameters.tsMaxDiff, //final double maxDiff, clt_parameters.tsMaxDiff, //final double maxDiff,
...@@ -3217,6 +3293,7 @@ public class TileProcessor { ...@@ -3217,6 +3293,7 @@ public class TileProcessor {
// Single pass, before growing assigned tiles // Single pass, before growing assigned tiles
if (clt_parameters.tsRemoveWeak1) { if (clt_parameters.tsRemoveWeak1) {
int [] stats= tileSurface.removeSmallClusters( int [] stats= tileSurface.removeSmallClusters(
tile_layers, //final int [][] tileLayers,
clt_parameters.tsClustSize , // final int minSize, // ** clt_parameters.tsClustSize , // final int minSize, // **
clt_parameters. tsClustWeight, // final double minStrength, // ** clt_parameters. tsClustWeight, // final double minStrength, // **
dispStrength, // final double [][][] dispStrength, dispStrength, // final double [][][] dispStrength,
...@@ -3232,6 +3309,7 @@ public class TileProcessor { ...@@ -3232,6 +3309,7 @@ public class TileProcessor {
if (clt_parameters.tsGrowSurround) { if (clt_parameters.tsGrowSurround) {
for (int nTry = 0; nTry < 100; nTry++) { for (int nTry = 0; nTry < 100; nTry++) {
int [] stats= tileSurface.assignFromFarthest( int [] stats= tileSurface.assignFromFarthest(
tile_layers, //final int [][] tileLayers,
clt_parameters.tsNoEdge , // final boolean noEdge, clt_parameters.tsNoEdge , // final boolean noEdge,
clt_parameters.tsMinNeib , // final int minNeib, // ** clt_parameters.tsMinNeib , // final int minNeib, // **
clt_parameters.tsMaxSurStrength , // final double maxStrength, // ** clt_parameters.tsMaxSurStrength , // final double maxStrength, // **
...@@ -3255,6 +3333,7 @@ public class TileProcessor { ...@@ -3255,6 +3333,7 @@ public class TileProcessor {
// Single pass, after growing assigned tiles // Single pass, after growing assigned tiles
if (clt_parameters.tsRemoveWeak2) { if (clt_parameters.tsRemoveWeak2) {
int [] stats= tileSurface.removeSmallClusters( int [] stats= tileSurface.removeSmallClusters(
tile_layers, //final int [][] tileLayers,
clt_parameters.tsClustSize , // final int minSize, // ** clt_parameters.tsClustSize , // final int minSize, // **
clt_parameters. tsClustWeight, // final double minStrength, // ** clt_parameters. tsClustWeight, // final double minStrength, // **
dispStrength, // final double [][][] dispStrength, dispStrength, // final double [][][] dispStrength,
...@@ -3263,6 +3342,39 @@ public class TileProcessor { ...@@ -3263,6 +3342,39 @@ public class TileProcessor {
clt_parameters.tileY); clt_parameters.tileY);
tileSurface.printStats(stats); tileSurface.printStats(stats);
} }
// Just show current state
tileSurface.statTileLayers(
tile_layers, // final int [][] tileLayers,
tileSel, // final boolean [][] tileSel,
1); // final int debugLevel)
// removed tile_layers from globals, so multiple parallel assignments can be generated and then combined
// int [][] tile_layers = tileSurface.getTileLayersCopy();
// int [][] tile_layers_single_surf = tileSurface.newTileLayers(tileSel); // final boolean [][] tileSel,)
// int [][] tile_layers_planes = tileSurface.newTileLayers(tileSel); // final boolean [][] tileSel,)
int [][][] tile_assignments = {tile_layers, tile_layers_single_surf, tile_layers_planes};
for (int i = 0; i < tile_assignments.length; i++){
if ((clt_parameters.tsConsensMode & (1 << i)) == 0) {
tile_assignments[i] = null;
}
}
tileSurface.compareAssignments(
tile_assignments); // final int [][][] tileAssignments)
int [][][] opinions = new int [tile_layers.length][][];
tile_layers = tileSurface.getConsensusAssignment(
clt_parameters.tsConsensAgree, // final int min_agree,
opinions, // int [][][] opinions_in,
tile_assignments); // final int [][][] tileAssignments)
tileSurface.setTileLayers(tile_layers);
// Just show current state // Just show current state
tileSurface.InitTilesAssignment( tileSurface.InitTilesAssignment(
false, false,
......
...@@ -106,28 +106,75 @@ public class TileSurface { ...@@ -106,28 +106,75 @@ public class TileSurface {
} }
public int [][] getTileLayers()
{
return this.tileLayers;
}
public int [][] getTileLayersCopy()
{
if (this.tileLayers == null){
return null;
}
int [][] tl = this.tileLayers.clone();
for (int i = 0; i < tl.length; i++){
if (tl[i] != null){
tl[i] = tl[i].clone();
}
}
return this.tileLayers;
}
public void setTileLayers(int [][] tileLayers){
this.tileLayers = tileLayers;
}
public class TileData{ public class TileData{
double [] disp_strength; double [] disp_strength;
int indx = 0; int indx = 0;
int new_index = 0; int new_index = 0;
boolean enable = true; boolean enable = true;
int [] neighbors = {-1,-1,-1,-1,-1,-1,-1,-1}; int [] neighbors = {-1,-1,-1,-1,-1,-1,-1,-1};
int dbg_nsTile; int parent_nsTile;
int parent_layer;
// TilePlanes.PlaneData parent_plane;
public TileData ( public TileData (
double disparity, double disparity,
double strength) double strength)
{ {
setDisparityStrength(disparity,strength); setDisparityStrength(disparity,strength);
} }
/*
public void setDbgNsTile(int dbg_nsTile) public void setParentPlane (TilePlanes.PlaneData parent_plane)
{ {
this.dbg_nsTile = dbg_nsTile; this.parent_plane = parent_plane;
} }
public int getDbgNsTile() public TilePlanes.PlaneData getParentPlane ()
{
return this.parent_plane;
}
*/
public void setParentTileLayer (int parent_nsTile, int parent_layer)
{ {
return this.dbg_nsTile; this.parent_nsTile = parent_nsTile;
this.parent_layer = parent_layer;
}
public int getParentLayer ()
{
return this.parent_layer;
}
// public void setParentNsTile(int parent_nsTile)
// {
// this.parent_nsTile = parent_nsTile;
// }
public int getParentNsTile()
{
return this.parent_nsTile;
} }
public void setIndex(int indx) public void setIndex(int indx)
...@@ -958,7 +1005,10 @@ public class TileSurface { ...@@ -958,7 +1005,10 @@ public class TileSurface {
dual_mesh[indx] = new TileData( // now sets neighbors to -1 dual_mesh[indx] = new TileData( // now sets neighbors to -1
disp_strength[0][indx], // disparity disp_strength[0][indx], // disparity
disp_strength[1][indx]); // strength disp_strength[1][indx]); // strength
dual_mesh[indx].setDbgNsTile(nsTile); // dual_mesh[indx].setParentNsTile(nsTile);
dual_mesh[indx].setParentTileLayer(nsTile, np);
// dual_mesh[indx].setParentPlane(planes[nsTile][np]);
int dirThisfrom0 = getDirToStile(nsTile0, nsTile); // can be -1; int dirThisfrom0 = getDirToStile(nsTile0, nsTile); // can be -1;
int surf0 = getTileSurfaceNumber ( // Number of the surface for the tile itself int surf0 = getTileSurfaceNumber ( // Number of the surface for the tile itself
nsTile0, // int nsTile, nsTile0, // int nsTile,
...@@ -1099,7 +1149,7 @@ public class TileSurface { ...@@ -1099,7 +1149,7 @@ public class TileSurface {
int nTile1 = getNtileDir(nTile, dir); int nTile1 = getNtileDir(nTile, dir);
if (nTile1 >= 0) { if (nTile1 >= 0) {
if ((tile_data[nTile1] == null) || (tileData_src[nTile1][neibs[dir]] == null)){ if ((tile_data[nTile1] == null) || (tileData_src[nTile1][neibs[dir]] == null)){
int dbg_sstile = tile_data[nTile][i].getDbgNsTile(); int dbg_sstile = tile_data[nTile][i].getParentNsTile();
int dbg_stileX = dbg_sstile % stilesX; int dbg_stileX = dbg_sstile % stilesX;
int dbg_stileY = dbg_sstile / stilesX; int dbg_stileY = dbg_sstile / stilesX;
int dbg_tx = nTile % dbg_tilesX; int dbg_tx = nTile % dbg_tilesX;
...@@ -1168,7 +1218,7 @@ public class TileSurface { ...@@ -1168,7 +1218,7 @@ public class TileSurface {
if (nTile1 >= 0) { if (nTile1 >= 0) {
if ((tileData[nTile1] == null) || (tileData[nTile1][neibs[dir]] == null)){ if ((tileData[nTile1] == null) || (tileData[nTile1][neibs[dir]] == null)){
if (debugLevel > -1) { if (debugLevel > -1) {
int dbg_sstile = tileData[nTile][nl].getDbgNsTile(); int dbg_sstile = tileData[nTile][nl].getParentNsTile();
int dbg_stileX = dbg_sstile % stilesX; int dbg_stileX = dbg_sstile % stilesX;
int dbg_stileY = dbg_sstile / stilesX; int dbg_stileY = dbg_sstile / stilesX;
int dbg_tx = nTile % dbg_tilesX; int dbg_tx = nTile % dbg_tilesX;
...@@ -1187,7 +1237,7 @@ public class TileSurface { ...@@ -1187,7 +1237,7 @@ public class TileSurface {
int [] neibs_other = tileData[nTile1][neibs[dir]].getNeighbors(); int [] neibs_other = tileData[nTile1][neibs[dir]].getNeighbors();
if (neibs_other[(dir + 4) % 8] != nl){ if (neibs_other[(dir + 4) % 8] != nl){
if (debugLevel > -1) { if (debugLevel > -1) {
int dbg_sstile = tileData[nTile][nl].getDbgNsTile(); int dbg_sstile = tileData[nTile][nl].getParentNsTile();
int dbg_stileX = dbg_sstile % stilesX; int dbg_stileX = dbg_sstile % stilesX;
int dbg_stileY = dbg_sstile / stilesX; int dbg_stileY = dbg_sstile / stilesX;
int dbg_tx = nTile % dbg_tilesX; int dbg_tx = nTile % dbg_tilesX;
...@@ -1201,7 +1251,7 @@ public class TileSurface { ...@@ -1201,7 +1251,7 @@ public class TileSurface {
" nTile="+nTile+" ("+dbg_tx+":"+dbg_ty+")"+ " nTile="+nTile+" ("+dbg_tx+":"+dbg_ty+")"+
", deltas from src center: "+dbg_dx+":"+dbg_dy+ ", deltas from src center: "+dbg_dx+":"+dbg_dy+
", neibs_other["+((dir + 4) % 8)+"]="+neibs_other[(dir + 4) % 8]+ ", neibs_other["+((dir + 4) % 8)+"]="+neibs_other[(dir + 4) % 8]+
", dbg_nsTile other="+tileData[nTile1][neibs[dir]].getDbgNsTile()); ", dbg_nsTile other="+tileData[nTile1][neibs[dir]].getParentNsTile());
} }
neibs[dir] = -3; // not a mutual link (break only this side here) neibs[dir] = -3; // not a mutual link (break only this side here)
} }
...@@ -1255,7 +1305,7 @@ public class TileSurface { ...@@ -1255,7 +1305,7 @@ public class TileSurface {
if (nTile1 >= 0) { if (nTile1 >= 0) {
if ((tileData[nTile1] == null) || (tileData[nTile1][neibs[dir]] == null)){ if ((tileData[nTile1] == null) || (tileData[nTile1][neibs[dir]] == null)){
if (debugLevel > 0) { if (debugLevel > 0) {
int dbg_sstile = tileData[nTile][nl].getDbgNsTile(); int dbg_sstile = tileData[nTile][nl].getParentNsTile();
int dbg_stileX = dbg_sstile % stilesX; int dbg_stileX = dbg_sstile % stilesX;
int dbg_stileY = dbg_sstile / stilesX; int dbg_stileY = dbg_sstile / stilesX;
int dbg_tx = nTile % dbg_tilesX; int dbg_tx = nTile % dbg_tilesX;
...@@ -1274,7 +1324,7 @@ public class TileSurface { ...@@ -1274,7 +1324,7 @@ public class TileSurface {
int [] neibs_other = tileData[nTile1][neibs[dir]].getNeighbors(); int [] neibs_other = tileData[nTile1][neibs[dir]].getNeighbors();
if (neibs_other[(dir + 4) % 8] != nl){ if (neibs_other[(dir + 4) % 8] != nl){
if (debugLevel > 0) { if (debugLevel > 0) {
int dbg_sstile = tileData[nTile][nl].getDbgNsTile(); int dbg_sstile = tileData[nTile][nl].getParentNsTile();
int dbg_stileX = dbg_sstile % stilesX; int dbg_stileX = dbg_sstile % stilesX;
int dbg_stileY = dbg_sstile / stilesX; int dbg_stileY = dbg_sstile / stilesX;
int dbg_tx = nTile % dbg_tilesX; int dbg_tx = nTile % dbg_tilesX;
...@@ -1288,7 +1338,7 @@ public class TileSurface { ...@@ -1288,7 +1338,7 @@ public class TileSurface {
" nTile="+nTile+" ("+dbg_tx+":"+dbg_ty+")"+ " nTile="+nTile+" ("+dbg_tx+":"+dbg_ty+")"+
", deltas from src center: "+dbg_dx+":"+dbg_dy+ ", deltas from src center: "+dbg_dx+":"+dbg_dy+
", neibs_other["+((dir + 4) % 8)+"]="+neibs_other[(dir + 4) % 8]+ ", neibs_other["+((dir + 4) % 8)+"]="+neibs_other[(dir + 4) % 8]+
", dbg_nsTile other="+tileData[nTile1][neibs[dir]].getDbgNsTile()); ", dbg_nsTile other="+tileData[nTile1][neibs[dir]].getParentNsTile());
} }
if (neibs_other[(dir + 4) % 8] < 0 ){ if (neibs_other[(dir + 4) % 8] < 0 ){
neibs_other[(dir + 4) % 8] = nl; // adding back link instead of missing one neibs_other[(dir + 4) % 8] = nl; // adding back link instead of missing one
...@@ -1422,7 +1472,7 @@ public class TileSurface { ...@@ -1422,7 +1472,7 @@ public class TileSurface {
if (tileData[nTile] != null) { if (tileData[nTile] != null) {
for (int nl = 0; nl < tileData[nTile].length; nl++) if (tileData[nTile][nl] != null) { for (int nl = 0; nl < tileData[nTile].length; nl++) if (tileData[nTile][nl] != null) {
for (int indx = 0 ; indx < tileData.length; indx++){ for (int indx = 0 ; indx < tileData.length; indx++){
generators[nl][nTile] = tileData[nTile][nl].getDbgNsTile(); generators[nl][nTile] = tileData[nTile][nl].getParentNsTile();
} }
} }
} }
...@@ -1960,7 +2010,7 @@ public class TileSurface { ...@@ -1960,7 +2010,7 @@ public class TileSurface {
int nsTile = tileY * tilesX + tileX; int nsTile = tileY * tilesX + tileX;
if ((tileData[nsTile]!= null) && (tileData[nsTile].length > ns) && (tileData[nsTile][ns] != null)){ if ((tileData[nsTile]!= null) && (tileData[nsTile].length > ns) && (tileData[nsTile][ns] != null)){
int [] neibs = tileData[nsTile][ns].getNeighbors(); int [] neibs = tileData[nsTile][ns].getNeighbors();
int master_st = tileData[nsTile][ns].getDbgNsTile(); int master_st = tileData[nsTile][ns].getParentNsTile();
switch (l){ switch (l){
case 0: System.out.print(" "+ case 0: System.out.print(" "+
((neibs[7] >= 0)?neibs[7]:" ")+ ((neibs[7] >= 0)?neibs[7]:" ")+
...@@ -2120,6 +2170,488 @@ public class TileSurface { ...@@ -2120,6 +2170,488 @@ public class TileSurface {
} }
return stats_new; return stats_new;
} }
public void compareAssignments(
final int [][][] tileAssignments)
{
final int imgTiles = imageTilesX * imageTilesY;
final int num_in = tileAssignments.length;
String [] titles = new String [num_in + 2];
double [][] img_data = new double [titles.length][imgTiles];
for (int i =0 ; i < num_in; i++){
titles[i] = "inp_"+i;
}
titles[num_in] = "consensus";
titles[num_in+1] = "conflicts";
int [] combo = new int [imgTiles];
for (int nTile = 0; nTile < imgTiles; nTile++){
int nSurfTile = getSurfaceTileIndex(nTile);
HashSet <Integer> alts = new HashSet <Integer>();
boolean invalid = false;
for (int n = 0; n < num_in; n++)if (tileAssignments[n] != null){
img_data[n][nTile] = Double.NaN;
for (int ml = 0; ml < tileAssignments[n].length; ml++) if ((tileAssignments[n][ml] != null) && (tileAssignments[n][ml][nTile] != 0)){
if (tileAssignments[n][ml][nTile] < 0) {
combo[nTile] = tileAssignments[n][ml][nTile];
invalid = true;
break;
}
alts.add(tileAssignments[n][ml][nTile]);
img_data[n][nTile] = tileData[nSurfTile][tileAssignments[n][ml][nTile] - 1].getDisparity();
img_data[num_in][nTile] = tileData[nSurfTile][tileAssignments[n][ml][nTile] - 1].getDisparity();
}
if (invalid) break;
}
if (!invalid) {
combo[nTile] = alts.size();
}
if (combo[nTile] != 1 ){
img_data[num_in][nTile] = Double.NaN;
}
img_data[num_in+1][nTile] = combo[nTile];
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(img_data, imageTilesX, imageTilesY, true, "consensus",titles);
}
public int [][] getConsensusAssignment(
final int min_agree,
int [][][] opinions_in,
final int [][][] tileAssignments)
{
final int imgTiles = imageTilesX * imageTilesY;
final int num_in = tileAssignments.length;
final int num_ml = tileAssignments[0].length; // all should have same number of measurement layers
final int [][] consensus = new int [num_ml][];
final int [][][] opinions = (opinions_in != null) ? opinions_in : new int [num_ml][][];
for (int ml = 0; ml < num_ml; ml++){
boolean ml_exists = false;
for (int n = 0; n < num_in; n++) {
if ((tileAssignments[n] != null) && (tileAssignments[n][ml] != null)){
ml_exists = true;
break;
}
}
if (ml_exists) {
consensus[ml] = new int [imgTiles];
opinions[ml] = new int [imgTiles][];
for (int nTile = 0; nTile < imgTiles; nTile++){
if (nTile== 50109){
System.out.println("getConsensusAssignment(): nTile="+nTile);
}
int num_agree = 0;
ArrayList <Integer> alts = new ArrayList <Integer>();
for (int n = 0; n < num_in; n++)if (tileAssignments[n] != null){
int surf1 = tileAssignments[n][ml][nTile];
if (surf1 != 0){
consensus[ml][nTile] = surf1;
if (surf1 < 0) { // prohibited
break;
} else { // surface
if (!alts.contains(surf1)){
alts.add(surf1);
}
num_agree++;
}
}
}
if ((alts.size() > 1) || (num_agree < min_agree)){
consensus[ml][nTile] = 0; // not assigned
}
if (!alts.isEmpty()){
opinions[ml][nTile] = new int[alts.size()];
int indx = 0;
for (Integer i:alts){
opinions[ml][nTile][indx++] = i;
}
}
}
}
}
return consensus;
}
/**
* Assign tiles that were used to generate planes. Only tiles in the center (non-overlapping) part of the supertile
* @param force re-assign tile if it was already assigned
* @param tileLayers
* @param debugLevel
* @param dbg_X
* @param dbg_Y
* @return
*/
public int [] assignPlanesTiles(
final boolean force,
final int [][] tileLayers,
final TilePlanes.PlaneData[][] planes,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
int [] stats_new = new int [NUM_STATS];
final int nsTiles = stilesX * stilesY;
final int imgTiles = imageTilesX * imageTilesY;
// final TileNeibs tnImage = new TileNeibs(imageTilesX, imageTilesY);
// final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final int debug_stile = dbg_Y * stilesX + dbg_X;
final Thread[] threads = ImageDtt.newThreadArray((debugLevel > 1)? 1 : threadsMax);
final int numThreads = threads.length;
final int [][] stats_all = new int [numThreads][stats_new.length];
final AtomicInteger ai_numThread = new AtomicInteger(0);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int numThread = ai_numThread.getAndIncrement(); // unique number of thread to write to rslt_diffs[numThread]
for (int nsTile = ai.getAndIncrement(); nsTile < nsTiles; nsTile = ai.getAndIncrement()) if (planes[nsTile] != null){
int stx = nsTile % stilesX;
int sty = nsTile / stilesX;
// int dl = ((debugLevel > 1) && (nsTile == debug_stile)) ? 3: debugLevel;
int dl = ((debugLevel > 1) && ((nsTile == debug_stile) || (nsTile == (debug_stile + stilesX)))) ? 3: debugLevel;
if (dl > 2){
System.out.println("assignPlanesTiles(): nsTile = " + nsTile);
}
for (int np = 0; np < planes[nsTile].length; np++) if (planes[nsTile][np] != null){
boolean [][] meas_sel = planes[nsTile][np].getMeasSelection();
// is it needed or is tileLayers already initialized?
for (int ml = 0; ml < meas_sel.length; ml++) if (meas_sel[ml] != null){
if (tileLayers[ml] == null){
tileLayers[ml] = new int [imgTiles];
}
}
for (int dy = 0; dy < superTileSize; dy++){
for (int dx = 0; dx < superTileSize; dx++){
// center (unique) part of the supertilemask
int st_index = superTileSize*(superTileSize + 2 * dy) +(superTileSize/2 + dx);
// int nl = -1;
int nTile = -1;
int ns = -1;
for (int ml = 0; ml < meas_sel.length; ml++) if (meas_sel[ml] != null){
if (meas_sel[ml][st_index]){
if (ns < 0){ // find for the first used ml, if there are more - they will reuse
nTile = (superTileSize * sty + dy) * imageTilesX + (superTileSize * stx + dx);
int nSurfTile = getSurfaceTileIndex(nTile);
for (int i = 0; i < tileData[nSurfTile].length; i ++){
if ( (tileData[nSurfTile][i].getParentNsTile() == nsTile) &&
(tileData[nSurfTile][i].getParentLayer() == np)) {
ns = i;
break;
}
}
if (dl > 2){
System.out.println("assignPlanesTiles(): nsTile = " + nsTile+":"+np+
" stx:y="+stx+":"+sty+
" ("+ (superTileSize * stx + dx)+"/"+
(superTileSize * sty + dy)+")" +
" dx:y="+dx+":"+dy+" nTile="+nTile+" nSurfTile="+nSurfTile+" ns="+ns);
}
if (ns < 0) {
System.out.println("assignPlanesTiles(): BUG? Could not find a surface with parent supertile "+
nsTile+":"+np+" for image tile = "+nTile+" ("+ (superTileSize * stx + dx)+"/"+
(superTileSize * sty + dy)+")");
}
}
if ((ns >= 0) && (force || (tileLayers[ml][nTile] == 0))) {
tileLayers[ml][nTile] = ns + 1;
stats_all[numThread][NEW_ASSIGNED] ++;
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
for (int nt = 0; nt < numThreads; nt ++){
for (int i = 0 ; i < stats_new.length; i++ ){
stats_new[i] += stats_all[nt][i];
}
}
return stats_new;
}
/**
* Assign tiles to a disparity surface if there is only one surface at all
* @param tileLayers per measured layer, per tile: assigned index plus1, 0 - empty, or negative - prohibited
* @param noEdge do not assign tiles to the surface edges (can not add border later)
* @param debugLevel debug level
* @param dbg_X debug tile X coordinate
* @param dbg_Y debug tile Y coordinate
* @return statistics array
*/
public int [] assignTilesToSingleSurface(
final int [][] tileLayers,
final boolean noEdge,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
int [] stats_new = new int [NUM_STATS];
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final int numThreads = threads.length;
final int [][] stats_all = new int [numThreads][stats_new.length];
final AtomicInteger ai_numThread = new AtomicInteger(0);
final AtomicInteger ai = new AtomicInteger(0);
for (int ml = 0; ml < tileLayers.length; ml++) if (tileLayers[ml] != null){
final int fml = ml;
ai_numThread.set(0);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int numThread = ai_numThread.getAndIncrement(); // unique number of thread to write to rslt_diffs[numThread]
for (int nTile = ai.getAndIncrement(); nTile < tileLayers[fml].length; nTile = ai.getAndIncrement()) {
if (tileLayers[fml][nTile] == 0){ // unassigned only
// calculate index in tileData (has different dimensions - TODO: trim?
int nSurfTile = getSurfaceTileIndex(nTile);
if ((tileData[nSurfTile] == null) || (tileData[nSurfTile].length == 0)){
stats_all[numThread][NO_SURF] ++;
tileLayers[fml][nTile] = IMPOSSIBLE;
} else {
if (tileData[nSurfTile].length == 1) {
boolean bad_edge = noEdge;
if (bad_edge) {
bad_edge = false;
int []neibs = tileData[nSurfTile][0].getNeighbors();
for (int i = 0; i < neibs.length; i++) if (neibs[i] < 0) {
bad_edge = true;
break;
}
}
if (bad_edge) {
stats_all[numThread][NO_SURF] ++;
tileLayers[fml][nTile] = IMPOSSIBLE;
} else {
tileLayers[fml][nTile] = 1; // first and only surface
stats_all[numThread][NEW_ASSIGNED] ++;
}
} else {
stats_all[numThread][NOT_UNIQUE] ++;
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
for (int nt = 0; nt < numThreads; nt ++){
for (int i = 0 ; i < stats_new.length; i++ ){
stats_new[i] += stats_all[nt][i];
}
}
return stats_new;
}
/**
* Grow assigned tiles while strength is below maxStrength OR normalized (dispNorm) disparity error is below
* maxDiff AND new tile is unassigned. Combines all measured layers, assumes same cell was not assigned to
* different surfaces on different measured layers (some assigned, some not is OK)
* @param tileLayers per measured layer, per tile: assigned index plus1, 0 - empty, or negative - prohibited
* @param conflicts detected conflicts while growing - both strength and disparity errors match requirements,
* but the cell is occupied by other assigned tile on different layer. Per tile, a pair of the surface index
* plus 0 and direction to offending cell . Outer array should be initialized
* @param noEdge do not assign tiles to the surface edges (can not add border later)
* (individual per measurement layer)
* @param maxStrength maximal processed (floor subtracted) correlation strength to grow over any disparity error
* @param minStrengthContinue minimal strength to continue growing with disparity match ( >maxStrength)
* if minStrengthContinue is null, any tile above maxStrength will be the last (not spawn any new neighbor ones)
* @param maxDiffFar maximal (normalized) disparity difference for strong tiles farther from the camera than the surface
* @param maxDiffNear maximal (normalized) disparity difference for strong tiles closer to the camera than the surface
* If any of maxDiffFar, maxDiffNear are null, they are ignored and only weak tiles are permitted
* TODO: Another option to expand - no valid competitor
* @param dispNorm disparity normalization - disparity difference with average above it will be scaled down
* @param dispStrength per measurement layer, combined disparity and strength array ([num_ml][2][])
* @param debugLevel debug level
* @param dbg_X debug tile X coordinate
* @param dbg_Y debug tile Y coordinate
* @return statistics array
*/
public int [] growWeakAssigned(
final int [][] tileLayers,
final int [][] conflicts,
final boolean noEdge,
final double [] maxStrength,
final double [] minStrengthContinue,
final double [] maxDiffFar,
final double [] maxDiffNear,
final double dispNorm, // disparity normalize (proportionally scale down disparity difference if above
final double [][][] dispStrength,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
// final int tiles = stilesX * superTileSize * stilesY * superTileSize;
final boolean en_strong = (maxDiffFar != null) && (maxDiffNear != null); // both should be specified
final boolean en_continue = minStrengthContinue != null;
final int img_tiles = imageTilesX * imageTilesY;
// final TileNeibs tnSurface = new TileNeibs(stilesX * superTileSize, stilesY * superTileSize);
final TileNeibs tnImage = new TileNeibs(imageTilesX, imageTilesY);
final int [] flat_assign = new int [ img_tiles];
final int [] stats = new int [NUM_STATS];
int [] dbg_flat_assign = null;
ArrayList<Point> tiles_list = new ArrayList<Point>();
for (int nTile = 0; nTile < img_tiles; nTile++){
for (int ml = 0; ml < tileLayers.length; ml++) if (tileLayers[ml] != null){
if (tileLayers[ml][nTile] != 0) {
flat_assign[nTile] = tileLayers[ml][nTile];
break;
}
}
}
if (debugLevel > 1) {
dbg_flat_assign = flat_assign.clone();
}
for (int nTile = 0; nTile < img_tiles; nTile++){
if (flat_assign[nTile] > 0) {
for (int dir = 0; dir < 8; dir++){
int nTile1 = tnImage.getNeibIndex(nTile, dir);
if ((nTile1 >= 0) && (flat_assign[nTile1] >=0 ) && (flat_assign[nTile1] != flat_assign[nTile])){
tiles_list.add(new Point(nTile,flat_assign[nTile]-1));
break;
}
}
}
}
while (!tiles_list.isEmpty()){
// int nTile = tiles_list.remove(0);
Point pTile = tiles_list.remove(0);
// calculate index in tileData (has different dimensions - TODO: trim?
int nSurfTile = getSurfaceTileIndex(pTile.x);
boolean is_weak_start = true;
for (int ml = 0; ml < tileLayers.length; ml ++) if (dispStrength[ml] != null) {
double strength = dispStrength[ml][1][pTile.x];
if (strength > maxStrength[ml]){
is_weak_start = false;
break;
}
}
if (!is_weak_start && !en_continue) {
continue; // only can grow from weak single candidate planes or in continue mode
}
int [] neibs = tileData[nSurfTile][pTile.y].getNeighbors();
int [] conflict = {pTile.y,0};
for (int dir = 0; dir < 8; dir++) if (neibs[dir] >= 0){
int nTile1 = tnImage.getNeibIndex(pTile.x, dir); // image index, not surface index
// check it does not already belong to the same surface
if (nTile1 == 49451) { // pTile.x==33324){
System.out.println("growWeakAssigned() nTile1="+nTile1);
}
if ((nTile1 >= 0) && // (nTile1 >= 0) should always be as it is connected!
(flat_assign[nTile1] != (neibs[dir] + 1)) && // not the same surface
(flat_assign[nTile1] >= 0)){// not the prohibited surface
// if noEdge, check it has all 8 neighbors
// calculate index in tileData (has different dimensions - TODO: trim?
int nSurfTile1 = getSurfaceTileIndex(nTile1);
int ns1 = neibs[dir];
System.out.println("growWeakAssigned(): nTile="+pTile.x+" ns="+pTile.y+" dir = "+dir+
" nSurfTile="+nSurfTile+" nSurfTile1="+nSurfTile1+" ns1="+ns1);
boolean bad_edge = noEdge;
if (bad_edge) {
bad_edge = false;
int [] neibs1 = tileData[nSurfTile1][ns1].getNeighbors(); //oob 1
for (int i = 0; i < neibs1.length; i++) if (neibs1[i] < 0) {
bad_edge = true;
break;
}
}
if (!bad_edge) {
// check if it fits before looking - is it an empty or already or belongs to other surface
// for each measurement layer separately
double surf_disparity = tileData[nSurfTile1][ns1].getDisparity();
boolean is_good_tile = true;
for (int ml = 0; ml < tileLayers.length; ml ++) if (dispStrength[ml] != null) {
double strength = dispStrength[ml][1][nTile1];
boolean is_weak_new = strength <= maxStrength[ml];
boolean good_disparity = false;
if (en_strong && !is_weak_new) {
double surf_disp_diff = getNormDispFromSurface (
dispStrength[ml][0][nTile1], // double disp_tile,
surf_disparity, // double disp_surf,
dispNorm); //double disp_norm)
good_disparity = (surf_disp_diff <= maxDiffNear[ml]) && (surf_disp_diff >= -maxDiffFar[ml]);
}
// Strong tiles can only be near the end of expansion - should not go back to weak after strong
// if started from weak, can add any weak or with disparity
if (is_weak_start) {
if (!is_weak_new && !good_disparity){
is_good_tile = false;
break;
}
// if started from not weak - disparity should match and the tile should be "really strong" ( > minStrengthContinue)
}else {
if (!good_disparity || !en_continue || (strength < minStrengthContinue[ml])) {
is_good_tile = false;
break;
}
}
}
if (is_good_tile) {
// here - OK to add a new tile
// is it a conflict?
if (flat_assign[nTile1] > 0) { // yes, a conflict
conflict[1] |= 1 << dir;
} else { // new empty cell - add it
flat_assign[nTile1] = ns1 + 1;
tiles_list.add(new Point(nTile1, ns1));
stats[NEW_ASSIGNED] ++;
}
}
}
}
}
if (conflict[1] != 0){
conflicts[pTile.x] = conflict;
}
}
//copy assignments to all measured layers
for (int nTile = 0; nTile < img_tiles; nTile++){
for (int ml = 0; ml < tileLayers.length; ml++) if (tileLayers[ml] != null){
if (flat_assign[nTile] != 0) {
tileLayers[ml][nTile] = flat_assign[nTile];
}
}
}
if (debugLevel > 1){
final String [] titles = {"surf","ini_assign", "assign", "confl_surf", "confl_dirs"};
final double [][] dbg_img = new double [titles.length][img_tiles];
for (int nTile = 0; nTile < img_tiles; nTile++){
dbg_img[1][nTile] = dbg_flat_assign[nTile];
dbg_img[2][nTile] = flat_assign[nTile];
if (flat_assign[nTile] > 0) {
double surf_disparity = tileData[getSurfaceTileIndex(nTile)][flat_assign[nTile]-1].getDisparity();
dbg_img[0][nTile] = surf_disparity;
} else {
dbg_img[0][nTile] = Double.NaN;
}
if (conflicts[nTile] != null){
dbg_img[3][nTile] = conflicts[nTile][0];
dbg_img[4][nTile] = conflicts[nTile][1];
}
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(dbg_img, imageTilesX, imageTilesY, true, "only_surface_grow",titles);
}
return stats;
}
public void printStats(int []stats) public void printStats(int []stats)
{ {
...@@ -2197,6 +2729,7 @@ public class TileSurface { ...@@ -2197,6 +2729,7 @@ public class TileSurface {
/** /**
* Unassign tiles that have too few connected other tiles (or total weight of the cluster is too small) * Unassign tiles that have too few connected other tiles (or total weight of the cluster is too small)
* This is a single-threaded method * This is a single-threaded method
* @param tileLayers integer array of per measurement layer, per tile of assigned surface indices (modifiesd)
* @param minSize minimal tiles in the cluster * @param minSize minimal tiles in the cluster
* @param minStrength minimal total strength of the cluster * @param minStrength minimal total strength of the cluster
* @param dispStrength per measurement layer, combined disparity and strength array ([num_ml][2][]) * @param dispStrength per measurement layer, combined disparity and strength array ([num_ml][2][])
...@@ -2206,6 +2739,8 @@ public class TileSurface { ...@@ -2206,6 +2739,8 @@ public class TileSurface {
* @return {number of tiles, number of clusters} removed * @return {number of tiles, number of clusters} removed
*/ */
public int [] removeSmallClusters( public int [] removeSmallClusters(
final int [][] tileLayers,
final int minSize, final int minSize,
final double minStrength, final double minStrength,
final double [][][] dispStrength, final double [][][] dispStrength,
...@@ -2271,6 +2806,7 @@ public class TileSurface { ...@@ -2271,6 +2806,7 @@ public class TileSurface {
/** /**
* Assign (weak) tile surrounded by assigned one to the disparity of the farthest tile (lowest disparity). * Assign (weak) tile surrounded by assigned one to the disparity of the farthest tile (lowest disparity).
* This is a single-threaded method * This is a single-threaded method
* @param tileLayers integer array of per measurement layer, per tile of assigned surface indices (modifiesd)
* @param noEdge do not assign tiles to the surface edges (can not add border later) * @param noEdge do not assign tiles to the surface edges (can not add border later)
* @param minNeib minimal number of occupied directions (of 8), several occupied levels count as one * @param minNeib minimal number of occupied directions (of 8), several occupied levels count as one
* @param maxStrength maximal strength of the tile to assign (strong one may make trust its disparity after all) * @param maxStrength maximal strength of the tile to assign (strong one may make trust its disparity after all)
...@@ -2284,6 +2820,7 @@ public class TileSurface { ...@@ -2284,6 +2820,7 @@ public class TileSurface {
*/ */
public int [] assignFromFarthest( public int [] assignFromFarthest(
final int [][] tileLayers,
final boolean noEdge, final boolean noEdge,
final int minNeib, final int minNeib,
final double maxStrength, final double maxStrength,
...@@ -2293,7 +2830,6 @@ public class TileSurface { ...@@ -2293,7 +2830,6 @@ public class TileSurface {
final int dbg_X, final int dbg_X,
final int dbg_Y) final int dbg_Y)
{ {
final int [][] tileLayers_src = tileLayers.clone(); final int [][] tileLayers_src = tileLayers.clone();
for (int i = 0; i < tileLayers_src.length; i++){ for (int i = 0; i < tileLayers_src.length; i++){
if (tileLayers_src[i] != null){ if (tileLayers_src[i] != null){
...@@ -2394,6 +2930,7 @@ public class TileSurface { ...@@ -2394,6 +2930,7 @@ public class TileSurface {
/** /**
* Assign tiles to a certain disparity surface if there is only one surface candidate * Assign tiles to a certain disparity surface if there is only one surface candidate
* @param tileLayers integer array of per measurement layer, per tile of assigned surface indices (modifiesd)
* @param noEdge do not assign tiles to the surface edges (can not add border later) * @param noEdge do not assign tiles to the surface edges (can not add border later)
* @param useCenter only assign outside of 8x8 center if no suitable alternative * @param useCenter only assign outside of 8x8 center if no suitable alternative
* @param maxDiff maximal (normalized) disparity difference * @param maxDiff maximal (normalized) disparity difference
...@@ -2421,6 +2958,7 @@ public class TileSurface { ...@@ -2421,6 +2958,7 @@ public class TileSurface {
*/ */
public int [] assignTilesToSurfaces( public int [] assignTilesToSurfaces(
final int [][] tileLayers,
final boolean noEdge, final boolean noEdge,
final boolean useCenter, final boolean useCenter,
final double maxDiff, final double maxDiff,
...@@ -2534,9 +3072,9 @@ public class TileSurface { ...@@ -2534,9 +3072,9 @@ public class TileSurface {
if (Math.abs(surf_disp_diff) <= minDiffOther){ if (Math.abs(surf_disp_diff) <= minDiffOther){
num_fit_other ++; num_fit_other ++;
} }
// separately calculate for center of the tiles getDbgNsTile // separately calculate for center of the tiles getParentNsTile
TileData td = tileData[nSurfTile][ns]; TileData td = tileData[nSurfTile][ns];
if (tileData[nSurfTile][ns].getDbgNsTile() == nSurfSuperTile){ if (tileData[nSurfTile][ns].getParentNsTile() == nSurfSuperTile){
center_surface[ns] = true; center_surface[ns] = true;
if (Math.abs(surf_disp_diff) <= maxDiff){ if (Math.abs(surf_disp_diff) <= maxDiff){
fit_center = ns; // no rating for fit "quality" here fit_center = ns; // no rating for fit "quality" here
...@@ -2838,6 +3376,49 @@ public class TileSurface { ...@@ -2838,6 +3376,49 @@ public class TileSurface {
return stats_new; return stats_new;
} }
boolean isInit()
{
return this.tileLayers != null;
}
public int [][] combineTileLayers(
final boolean overwrite,
final int [][] dst,
final int [][] src
){
for (int ml = 0; ml < dst.length; ml++){
if (src[ml] != null){
if (dst[ml] == null) {
dst[ml] = src[ml].clone();
} else {
for (int i = 0; i < src[ml].length; i++) if ((src[ml][i] != 0) && (overwrite || (dst[ml][i] == 0))){
dst[ml][i] = src[ml][i];
}
}
}
}
return dst;
}
public int [][] newTileLayers(
final boolean [][] tileSel
){
int [][] tileLayers = new int [tileSel.length][];
for (int ml = 0; ml < tileSel.length; ml++){
if (tileSel[ml] != null){
tileLayers[ml] = new int [tileSel[ml].length];
for (int i = 0; i < tileSel[ml].length; i++){
tileLayers[ml][i] = tileSel[ml][i] ? 0: -1; // 0 - unassigned, -1 - prohibited
}
}
}
return tileLayers;
}
public int [] InitTilesAssignment( public int [] InitTilesAssignment(
final boolean force, final boolean force,
...@@ -2846,16 +3427,7 @@ public class TileSurface { ...@@ -2846,16 +3427,7 @@ public class TileSurface {
final int debugLevel) final int debugLevel)
{ {
if (force || (this.tileLayers == null)) { if (force || (this.tileLayers == null)) {
int [][] tileLayers = new int [tileSel.length][]; this.tileLayers = newTileLayers(tileSel);
for (int ml = 0; ml < tileSel.length; ml++){
if (tileSel[ml] != null){
tileLayers[ml] = new int [tileSel[ml].length];
for (int i = 0; i < tileSel[ml].length; i++){
tileLayers[ml][i] = tileSel[ml][i] ? 0: -1; // 0 - unassigned, -1 - prohibited
}
}
}
this.tileLayers = tileLayers;
} }
int []stats = getTilesAssignStats(tileLayers); int []stats = getTilesAssignStats(tileLayers);
if (debugLevel >= -1) { if (debugLevel >= -1) {
...@@ -2868,6 +3440,22 @@ public class TileSurface { ...@@ -2868,6 +3440,22 @@ public class TileSurface {
return stats; return stats;
} }
public int [] statTileLayers(
final int [][] tileLayers,
final boolean [][] tileSel,
final int debugLevel)
{
int []stats = getTilesAssignStats(tileLayers);
if (debugLevel >= -1) {
System.out.println("sortTilesToSurfaces(): using "+stats[STAT_NUM_ML] +" measurement layers"+
", number of assigned tiles: "+stats[STAT_ASSIGNED]+
", number of unassigned tiles: "+stats[STAT_UNASSIGNED]+
", number of prohibited tiles: "+stats[STAT_PROHIBITED]+
", number of impossible tiles: "+stats[STAT_IMPOSSIBLE]);
}
return stats;
}
public boolean [][] extractSelection( public boolean [][] extractSelection(
final int debugLevel, final int debugLevel,
......
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