Commit b267218c authored by Andrey Filippov's avatar Andrey Filippov

testing planes

parent 5467504f
......@@ -143,10 +143,15 @@ public class CLTPass3d{
superTiles = null;
}
public boolean [] getSelected(){
return selected;
}
public void setSelected (boolean [] selected) {
this.selected = selected;
}
public void fixNaNDisparity()
{
fixNaNDisparity(
......
......@@ -34,7 +34,7 @@ public class DisparityProcessor {
0b11111111, // middle
0b11110001, // middle right
0b00000111, // bottom left
0b11000111, // mottom middle
0b11000111, // bottom middle
0b11000001}; // bottom right
TileProcessor tp;
......@@ -48,12 +48,26 @@ public class DisparityProcessor {
this.scale_dz_dx = scale_dz_dx;
}
public int [] getNeighbors( // creates neighbors mask from bitmask
int [] surf_indices,
int indx,
int tilesX)
{
boolean [] selected = new boolean [surf_indices.length];
for (int i = 0; i < surf_indices.length; i++){
selected[i] = surf_indices[i] == indx;
}
return getNeighbors(selected, tilesX);
}
public int [] getNeighbors( // creates neighbors mask from bitmask
boolean [] selected,
int tilesX
)
{
int [] neibs = new int [selected.length];
int tilesY = selected.length/tilesX;
final int [] dirs8 = {-tilesX, -tilesX + 1, 1, tilesX +1, tilesX, tilesX - 1, -1, -tilesX - 1};
for (int nTile = 0; nTile < selected.length; nTile++) {
......@@ -68,7 +82,7 @@ public class DisparityProcessor {
} else {
tileType = 1;
}
} else if (tileX == (tilesX - 1)) {
} else if (tileY == (tilesY - 1)) {
if (tileX == 0){
tileType = 6;
} else if (tileX == (tilesX - 1)) {
......@@ -93,11 +107,10 @@ public class DisparityProcessor {
}
}
else {
neibs[nTile] = 0;
neibs[nTile] = 0; // change to -1?
}
}
return neibs;
}
public double [] dbgShowNeighbors(
......@@ -114,7 +127,8 @@ public class DisparityProcessor {
int height = tilesY * tile_size;
double [] rslt = new double [width*height];
for (int i = 0; i < rslt.length; i++) rslt[i] = bgnd;
for (int nTile = 0; nTile < neighbors.length; nTile++)if (selected[nTile]) { // if (neighbors[nTile] != 0) {
for (int nTile = 0; nTile < neighbors.length; nTile++) {
if ((neighbors [nTile] >=0) && ((selected == null) || selected[nTile])) { // if (neighbors[nTile] != 0) {
int tileY = nTile / tilesX;
int tileX = nTile % tilesX;
for (int i = -1; i<= 1; i++){
......@@ -130,6 +144,7 @@ public class DisparityProcessor {
}
}
}
}
return rslt;
}
......@@ -267,7 +282,7 @@ public class DisparityProcessor {
int numBorder = 0, numInternal = 0;
for (int i = 0; i < len; i++){
if ((border != null) && border[i]) numBorder++;
else if (selected[i]) numInternal++; // only if not border
else if (selected[i] && (neighbors[i] >= 0)) numInternal++; // only if not border
}
final int numTiles = (((mask & 1) != 0)? numInternal : 0) + (((mask & 2) != 0)? numBorder : 0);
final int [] indices = new int [numBorder + numInternal]; // internal excludes border
......@@ -275,7 +290,7 @@ public class DisparityProcessor {
for (int i = 0; i < len; i++){
if ((border != null) && border[i]){
if ((mask & 2) != 0) indices[indx++] = i;
} else if (selected[i]) {
} else if (selected[i] && (neighbors[i] >= 0)) {
if ((mask & 1) != 0) indices[indx++] = i;
}
}
......@@ -329,7 +344,7 @@ public class DisparityProcessor {
if ((debugLevel > 0) &&(nTile == dbg_tile)) {
System.out.println("smoothDisparity() nTile = "+nTile+" tileX="+tileX+" tileY="+tileY);
}
for (int i = 0; i < dirs8.length; i++) if ((neighbors[nTile] & (1 << i)) !=0) {
for (int i = 0; i < dirs8.length; i++) if ((neighbors[nTile] >= 0) && ((neighbors[nTile] & (1 << i)) != 0)) {
double w = rigid8[i]; // no strength here strength[nTile + dirs8[i]]
int dbg_dirs8 = nTile + dirs8[i];
double dbg_d = disp_data[0][nTile + dirs8[i]];
......@@ -475,12 +490,12 @@ public class DisparityProcessor {
final int len = disparity.length;
int numTiles = 0;
for (int i = 0; i < len; i++){
if (selected[i]) numTiles++; // only if not border
if (selected[i] && (neighbors[i] >= 0)) numTiles++; // only if not border
}
final int [] indices = new int [numTiles]; // internal excludes border
int indx = 0;
for (int i = 0; i < len; i++){
if (selected[i]) {
if (selected[i] && (neighbors[i] >= 0)) {
indices[indx++] = i;
}
}
......@@ -488,9 +503,6 @@ public class DisparityProcessor {
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
final double [][] deriv3HV = new double [2][len]; // 4-th derivative [0] - horizontal, 1 - vertical
// neighbors
// final int [][] neib_data = {neighbors, new int [len]};
// final double [] k4_3 = { 1.0, -3.0, 3.0, -1.0}; // 3-rd
final double [] k4_3 = {-1.0, 3.0, -3.0, 1.0}; // 3-rd
final double [] k4_2 = {-1.0, 1.0, 1.0, -1.0}; // - 2-nd (average for 2 sides)
final double [] k4 = (mode == 2)? k4_2 : k4_3;
......@@ -504,6 +516,7 @@ public class DisparityProcessor {
// int tileX = nTile - (tileY * tilesX);
// double deriv4;
int neib = neighbors[nTile];
if (neib < 0) neib = 0; // should not get here
// try break horizontally (always - to the right)
int b = (1 << 2); // "E" (right)
int rb = (1 << 6); // "W" (left)
......@@ -518,7 +531,7 @@ public class DisparityProcessor {
if ((neib & rb) != 0) deriv += k4[0]*disparity[nTile - 1];
else if (extend_flat) deriv += k4[0]*disparity[nTile];
else break hor_label;
if ((neighbors[nTile + 1] & b) != 0) deriv += k4[3]* disparity[nTile + 2];
if ((neighbors[nTile + 1] >=0) && ((neighbors[nTile + 1] & b) != 0)) deriv += k4[3]* disparity[nTile + 2];
else if (extend_flat) deriv += k4[3]* disparity[nTile + 1];
else break hor_label;
switch (mode){
......@@ -547,8 +560,8 @@ public class DisparityProcessor {
if ((neib & rb) != 0) deriv += k4[0]*disparity[nTile - tilesX];
else if (extend_flat) deriv += k4[0]*disparity[nTile];
else break vert_label;
if ((neighbors[nTile + tilesX] & b) != 0) deriv += k4[3]*disparity[nTile + 2 * tilesX];
else if (extend_flat) deriv += k4[3]*disparity[nTile + tilesX];
if ((neighbors[nTile + + tilesX] >=0) && ((neighbors[nTile + tilesX] & b) != 0)) deriv += k4[3] * disparity[nTile + 2 * tilesX];
else if (extend_flat) deriv += k4[3] * disparity[nTile + tilesX];
else break vert_label;
switch (mode){
case 1:
......@@ -624,6 +637,7 @@ public class DisparityProcessor {
int tileY = nTile/tilesX;
int tileX = nTile - (tileY * tilesX);
int neib = neighbors_in[nTile];
if (neib < 0) neib = 0;
if (Math.abs(deriv3HV[0][nTile]) >= break3) neib &= ~0b00001110; // break all right side
if (Math.abs(deriv3HV[1][nTile]) >= break3) neib &= ~0b00111000; // break all down side
if ((tileX > 0) && selected[nTile - 1] && (Math.abs(deriv3HV[0][nTile - 1]) >= break3)) neib &= ~0b11100000; // break all left side
......@@ -655,6 +669,7 @@ public class DisparityProcessor {
int tileY = nTile/tilesX;
int tileX = nTile - (tileY * tilesX);
int neib = neighbors_in[nTile];
if (neib < 0) neib = 0;
if (deriv3HV[0][nTile] >= break3) neib &= ~0b00001110; // break all right side
if (deriv3HV[1][nTile] >= break3) neib &= ~0b00111000; // break all down side
if ((tileX > 0) && selected[nTile - 1] && (deriv3HV[0][nTile - 1] >= break3)) neib &= ~0b11100000; // break all left side
......@@ -709,12 +724,12 @@ public class DisparityProcessor {
final int len = disparity.length;
int numTiles = 0;
for (int i = 0; i < len; i++){
if (selected[i]) numTiles++; // only if not border
if (selected[i] && (neighbors[i] >= 0)) numTiles++; // only if not border
}
final int [] indices = new int [numTiles]; // internal excludes border
int indx = 0;
for (int i = 0; i < len; i++){
if (selected[i]) {
if (selected[i] && (neighbors[i] >= 0)) {
indices[indx++] = i;
}
}
......@@ -730,7 +745,7 @@ public class DisparityProcessor {
int tileY = nTile/tilesX;
int tileX = nTile - (tileY * tilesX);
int neib = neighbors[nTile];
if (neib < 0) neib = 0;
int b = (1 << 2); // "E" (right)
if (((neib & b) == 0) && (tileX < (tilesX - 1) && selected[nTile + 1])) {
if (Math.abs(disparity[nTile] - disparity[nTile + 1]) < maxDiffOrto){
......@@ -806,12 +821,12 @@ public class DisparityProcessor {
final int len = neighbors.length;
int numTiles = 0;
for (int i = 0; i < len; i++){
if (selected[i]) numTiles++; // only if not border
if (selected[i] && (neighbors[i] >= 0)) numTiles++; // only if not border
}
final int [] indices = new int [numTiles]; // internal excludes border
int indx = 0;
for (int i = 0; i < len; i++){
if (selected[i]) {
if (selected[i] && (neighbors[i] >= 0)) {
indices[indx++] = i;
}
}
......@@ -823,7 +838,7 @@ public class DisparityProcessor {
for (int iTile = ai.getAndIncrement(); iTile < indices.length; iTile = ai.getAndIncrement()) {
int nTile = indices[iTile];
int neib = neighbors[nTile];
if (neib < 0) neib = 0;
if (
((neib & (1 << 0)) != 0) &&
((neighbors[nTile - tilesX] & (1 << 2)) != 0)){
......@@ -943,6 +958,7 @@ public class DisparityProcessor {
for (int ty = 0; ty < tilesY; ty++){
for (int tx = 0; tx < tilesX; tx++){
int neib = neighbors[ty * tilesX + tx];
if (neib < 0) neib = 0;
int []cell = field[ty + 1][tx + 1];
if ( neib!= 0) {
cell[0] = ((neib & NEIB_RIGHT) == 0)? FLD_EMPTY:FLD_CONN;
......@@ -1070,7 +1086,7 @@ public class DisparityProcessor {
int numTilesAll = 0;
// final boolean [] selectedAll = new boolean[len];
for (int i = 0; i < len; i++){
if (selected[i] || border[i]) {
if ((selected[i] && (neighbors[i] >= 0)) || border[i]) {
// selectedAll[i] = true;
numTilesAll++;
if (!border[i]) numTiles++;
......@@ -1081,7 +1097,7 @@ public class DisparityProcessor {
int indx = 0;
int indxAll = 0;
for (int i = 0; i < len; i++){
if (selected[i] || border[i]) {
if ((selected[i] && (neighbors[i] >= 0)) || border[i]) {
indicesAll[indxAll++] = i;
if (!border[i]) indices[indx++] = i;
}
......@@ -1204,7 +1220,7 @@ public class DisparityProcessor {
* For each cluster returns 3 arrays: indiced of internal cells, indices of fixed border cells (alpha = 0, disparity fixed)
* and floating border cells (alpha = 0, disparity - from neighbors)
* @param diag_en true - 8 directions, false - only 4 orthogonal
* @param neighbors array of per-cell bitmaps - which neighbors curtrent cell is connected to (+1 - to N, +2 - to NE,...+128 = to NW)
* @param neighbors array of per-cell bitmaps - which neighbors current cell is connected to (+1 - to N, +2 - to NE,...+128 = to NW)
* @param selected boolean array of celected (internal) cells
* @param border boolean array of border cells (added for alpha)
* @param threadsMax maximal number of threads for multi-threaded application
......
......@@ -2152,16 +2152,26 @@ public class EyesisCorrectionParameters {
public boolean plDbgMerge = true; // Combine 'other' plane with current
public double plWorstWorsening = 1.0; // Worst case worsening after merge
public boolean plMutualOnly = true; // keep only mutual links, remove weakest if conflict
public boolean plFillSquares = true; // Add diagonals to full squares
public boolean plCutCorners = true; // Add ortho to 45-degree corners
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 int plPrecision = 6; // Maximal step difference (1/power of 10)
public boolean plFuse = true; // Fuse planes together (off for debug only)
public boolean plKeepOrphans = true; // Keep unconnected supertiles
public double plMinOrphan = 2.0; // Minimal strength unconnected supertiles to keep
public double plSnapDisp = .2; // Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength
public double plSnapDispAny = .2; // Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength
public double plSnapStrengthAny = .2; // Maximal strength to fit any distance (if does not fit otherwise - treat as zero str4ength
public double plSnapNegAny = .5; // Maximal negative disparity difference from the best match
public double plSnapDispMax = .5; // Maximal (scaled by plDispNorm) disparity difference to snap to plane at low strength
public double plSnapDispWeight = .5; // Maximal disparity diff. by weight product to snap to plane
public int plSnapZeroMode = 1; // Zero strength snap mode: 0: no special treatment, 1 - strongest, 2 - farthest
public boolean replaceWeakOutlayers = true; // false;
// other debug images
......@@ -2407,16 +2417,22 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"plWorstWorsening", this.plWorstWorsening +"");
properties.setProperty(prefix+"plMutualOnly", this.plMutualOnly+"");
properties.setProperty(prefix+"plFillSquares", this.plFillSquares+"");
properties.setProperty(prefix+"plCutCorners", this.plCutCorners+"");
properties.setProperty(prefix+"plPull", this.plPull +"");
properties.setProperty(prefix+"plIterations", this.plIterations+"");
properties.setProperty(prefix+"plPrecision", this.plPrecision+"");
properties.setProperty(prefix+"plFuse", this.plFuse+"");
properties.setProperty(prefix+"plKeepOrphans", this.plKeepOrphans+"");
properties.setProperty(prefix+"plMinOrphan", this.plMinOrphan +"");
properties.setProperty(prefix+"plSnapDisp", this.plSnapDisp +"");
properties.setProperty(prefix+"plSnapDispAny", this.plSnapDispAny +"");
properties.setProperty(prefix+"plSnapStrengthAny",this.plSnapStrengthAny +"");
properties.setProperty(prefix+"plSnapNegAny", this.plSnapNegAny +"");
properties.setProperty(prefix+"plSnapDispMax", this.plSnapDispMax +"");
properties.setProperty(prefix+"plSnapDispWeight", this.plSnapDispWeight +"");
properties.setProperty(prefix+"plSnapZeroMode", this.plSnapZeroMode+"");
properties.setProperty(prefix+"show_ortho_combine", this.show_ortho_combine+"");
properties.setProperty(prefix+"show_refine_supertiles", this.show_refine_supertiles+"");
......@@ -2652,16 +2668,22 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"plWorstWorsening")!=null) this.plWorstWorsening=Double.parseDouble(properties.getProperty(prefix+"plWorstWorsening"));
if (properties.getProperty(prefix+"plMutualOnly")!=null) this.plMutualOnly=Boolean.parseBoolean(properties.getProperty(prefix+"plMutualOnly"));
if (properties.getProperty(prefix+"plFillSquares")!=null) this.plFillSquares=Boolean.parseBoolean(properties.getProperty(prefix+"plFillSquares"));
if (properties.getProperty(prefix+"plCutCorners")!=null) this.plCutCorners=Boolean.parseBoolean(properties.getProperty(prefix+"plCutCorners"));
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+"plPrecision")!=null) this.plPrecision=Integer.parseInt(properties.getProperty(prefix+"plPrecision"));
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"));
if (properties.getProperty(prefix+"plMinOrphan")!=null) this.plMinOrphan=Double.parseDouble(properties.getProperty(prefix+"plMinOrphan"));
if (properties.getProperty(prefix+"plSnapDisp")!=null) this.plSnapDisp=Double.parseDouble(properties.getProperty(prefix+"plSnapDisp"));
if (properties.getProperty(prefix+"plSnapDispAny")!=null) this.plSnapDispAny=Double.parseDouble(properties.getProperty(prefix+"plSnapDispAny"));
if (properties.getProperty(prefix+"plSnapStrengthAny")!=null) this.plSnapStrengthAny=Double.parseDouble(properties.getProperty(prefix+"plSnapStrengthAny"));
if (properties.getProperty(prefix+"plSnapNegAny")!=null) this.plSnapNegAny=Double.parseDouble(properties.getProperty(prefix+"plSnapNegAny"));
if (properties.getProperty(prefix+"plSnapDispMax")!=null) this.plSnapDispMax=Double.parseDouble(properties.getProperty(prefix+"plSnapDispMax"));
if (properties.getProperty(prefix+"plSnapDispWeight")!=null) this.plSnapDispWeight=Double.parseDouble(properties.getProperty(prefix+"plSnapDispWeight"));
if (properties.getProperty(prefix+"plSnapZeroMode")!=null) this.plPrecision=Integer.parseInt(properties.getProperty(prefix+"plSnapZeroMode"));
if (properties.getProperty(prefix+"show_ortho_combine")!=null) this.show_ortho_combine=Boolean.parseBoolean(properties.getProperty(prefix+"show_ortho_combine"));
if (properties.getProperty(prefix+"show_refine_supertiles")!=null) this.show_refine_supertiles=Boolean.parseBoolean(properties.getProperty(prefix+"show_refine_supertiles"));
......@@ -2919,17 +2941,23 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Worst case worsening after merge", this.plWorstWorsening, 6);
gd.addCheckbox ("Keep only mutual links, remove weakest if conflict", this.plMutualOnly);
gd.addCheckbox ("Add diagonals to full squares", this.plFillSquares);
gd.addCheckbox ("Add ortho to 45-degree corners", this.plCutCorners);
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.addNumericField("Maximal step difference (1/power of 10) ", this.plPrecision, 0);
gd.addNumericField("Maximal step difference (1/power of 10)", this.plPrecision, 0);
gd.addCheckbox ("Fuse planes together (off for debug only)", this.plFuse);
gd.addCheckbox ("Keep unconnected supertiles", this.plKeepOrphans);
gd.addNumericField("Minimal strength unconnected supertiles to keep", this.plMinOrphan, 6);
gd.addMessage ("--- Snap to planes ---");
gd.addNumericField("Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength", this.plSnapDisp, 6);
gd.addNumericField("Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength", this.plSnapDispAny, 6);
gd.addNumericField("Maximal strength to fit any distance (if does not fit otherwise - treat as zero strength", this.plSnapStrengthAny, 6);
gd.addNumericField("Maximal negative disparity difference from the best match", this.plSnapNegAny, 6);
gd.addNumericField("Maximal (scaled by plDispNorm) disparity difference to snap to plane at low strength", this.plSnapDispMax, 6);
gd.addNumericField("Maximal disparity diff. by weight product to snap to plane", this.plSnapDispWeight, 6);
gd.addNumericField("Zero strength snap mode: 0: no special treatment, 1 - strongest, 2 - farthest",this.plSnapZeroMode, 0);
gd.addMessage ("--- Other debug images ---");
gd.addCheckbox ("Show 'ortho_combine'", this.show_ortho_combine);
......@@ -3174,16 +3202,22 @@ public class EyesisCorrectionParameters {
this.plWorstWorsening= gd.getNextNumber();
this.plMutualOnly= gd.getNextBoolean();
this.plFillSquares= gd.getNextBoolean();
this.plCutCorners= gd.getNextBoolean();
this.plPull= gd.getNextNumber();
this.plIterations= (int) gd.getNextNumber();
this.plPrecision= (int) gd.getNextNumber();
this.plFuse= gd.getNextBoolean();
this.plKeepOrphans= gd.getNextBoolean();
this.plMinOrphan= gd.getNextNumber();
this.plSnapDisp= gd.getNextNumber();
this.plSnapDispAny= gd.getNextNumber();
this.plSnapStrengthAny= gd.getNextNumber();
this.plSnapNegAny= gd.getNextNumber();
this.plSnapDispMax= gd.getNextNumber();
this.plSnapDispWeight= gd.getNextNumber();
this.plSnapZeroMode= (int) gd.getNextNumber();
this.show_ortho_combine= gd.getNextBoolean();
this.show_refine_supertiles=gd.getNextBoolean();
......
......@@ -507,6 +507,7 @@ private Panel panel1,
addButton("CLT reset 3D", panelClt1, color_stop);
addButton("CLT 3D", panelClt1, color_conf_process);
addButton("CLT planes", panelClt1, color_conf_process);
addButton("CLT OUT 3D", panelClt1, color_process);
add(panelClt1);
}
......@@ -4756,6 +4757,9 @@ private Panel panel1,
UPDATE_STATUS, //final boolean updateStatus,
DEBUG_LEVEL); //final int debugLevel);
if (configPath!=null) {
saveTimestampedProperties( // save config again
configPath, // full path or null
......@@ -4772,14 +4776,88 @@ private Panel panel1,
System.out.println("QUAD_CLT is null, nothing to show");
return;
}
//"CLT planes"
QUAD_CLT.showCLTPlanes(
CLT_PARAMETERS, // EyesisCorrectionParameters.DCTParameters dct_parameters,
THREADS_MAX, //final int threadsMax, // maximal number of threads to launch
UPDATE_STATUS, //final boolean updateStatus,
DEBUG_LEVEL); //final int debugLevel);
return;
} else if (label.equals("CLT OUT 3D")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (QUAD_CLT == null){
System.out.println("QUAD_CLT is null, nothing to show (will add previous steps)");
return;
}
String configPath=null;
if (EYESIS_CORRECTIONS.correctionsParameters.saveSettings) {
configPath=EYESIS_CORRECTIONS.correctionsParameters.selectResultsDirectory(
true,
true);
if (configPath==null){
String msg="No results directory selected, command aborted";
System.out.println("Warning: "+msg);
IJ.showMessage("Warning",msg);
return;
}
configPath+=Prefs.getFileSeparator()+"autoconfig";
try {
saveTimestampedProperties(
configPath, // full path or null
null, // use as default directory if path==null
true,
PROPERTIES);
} catch (Exception e){
String msg="Failed to save configuration to "+configPath+", command aborted";
System.out.println("Error: "+msg);
IJ.showMessage("Error",msg);
return;
}
}
/*
public boolean output3d(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
*/
boolean OK = QUAD_CLT.output3d(
CLT_PARAMETERS, // EyesisCorrectionParameters.DCTParameters dct_parameters,
COLOR_PROC_PARAMETERS, //EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
RGB_PARAMETERS, //EyesisCorrectionParameters.RGBParameters rgbParameters,
THREADS_MAX, //final int threadsMax, // maximal number of threads to launch
UPDATE_STATUS, //final boolean updateStatus,
DEBUG_LEVEL); //final int debugLevel);
if (!OK) {
String msg="Image data not initialized, run 'CLT 3D' command first";
System.out.println("Error: "+msg);
IJ.showMessage("Error",msg);
}
/*
if (configPath!=null) {
saveTimestampedProperties( // save config again
configPath, // full path or null
null, // use as default directory if path==null
true,
PROPERTIES);
}
*/
return;
//
// End of buttons code
}
......
......@@ -52,6 +52,9 @@ public class QuadCLT {
TileProcessor tp = null;
String image_name = null;
double [][][] image_data = null;
// magic scale should be set before using TileProcessor (calculated disparities depend on it)
public void setTiles (ImagePlus imp, // set tp.tilesX, tp.tilesY
......@@ -4474,6 +4477,30 @@ public class QuadCLT {
}
tp.showPlanes(
clt_parameters,
geometryCorrection,
threadsMax,
updateStatus,
debugLevel);
// CLTPass3d last_scan = tp.clt_3d_passes.get(tp.clt_3d_passes.size() -1); // get last one
}
public void out3d(
EyesisCorrectionParameters.CLTParameters clt_parameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
if (tp == null){
System.out.println("showCLTPlanes(): tp is null");
return;
}
if (tp.clt_3d_passes == null){
System.out.println("showCLTPlanes(): tp.clt_3d_passes is null");
return;
}
tp.showPlanes(
clt_parameters,
geometryCorrection,
threadsMax,
updateStatus,
debugLevel);
......@@ -4683,7 +4710,7 @@ public class QuadCLT {
clt_parameters.colors_equalize,
channelFiles,
imp_srcs,
setNames.get(nSet), // just for debug messeges == setNames.get(nSet)
setNames.get(nSet), // just for debug messages == setNames.get(nSet)
debugLevel);
}
// once per quad here
......@@ -4740,6 +4767,11 @@ public class QuadCLT {
setTiles (imp_quad[0], // set global tp.tilesX, tp.tilesY
clt_parameters,
threadsMax);
this.image_name = name;
this.image_data = image_data;
tp.resetCLTPasses();
tp.setTrustedCorrelation(clt_parameters.grow_disp_trust);
final int tilesX = tp.getTilesX();
......@@ -5083,11 +5115,15 @@ public class QuadCLT {
geometryCorrection,
threadsMax, // maximal number of threads to launch
updateStatus,
2); // debugLevel);
0); // 2); // debugLevel);
// get images for predefined regions and disparities. First - with just fixed scans 1 .. list.size()
// TEMPORARY EXIT
// Save tp.clt_3d_passes.size() to roll back without restarting the program
tp.saveCLTPasses();
if (tp.clt_3d_passes.size() > 0) {
System.out.println("-------- temporary exit after secondPassSetup() ------- ");
return null; // just to fool compiler
......@@ -5206,6 +5242,167 @@ public class QuadCLT {
return imp_bgnd; // relative (to x3d directory) path - (String) imp_bgnd.getProperty("name");
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// public ImagePlus output3d(
public boolean output3d(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.ColorProcParameters colorProcParameters,
EyesisCorrectionParameters.RGBParameters rgbParameters,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
final int tilesX = tp.getTilesX();
final int tilesY = tp.getTilesY();
if (this.image_data == null){
return false;
}
tp.trimCLTPasses(); // make possible to run this method multiple time - remove extra passes added by it last time
int next_pass = tp.clt_3d_passes.size(); //
tp.showScan(
tp.clt_3d_passes.get(next_pass-1), // CLTPass3d scan,
"after_pass2-"+(next_pass-1)); //String title)
tp.thirdPassSetup( // prepare tile tasks for the second pass based on the previous one(s)
clt_parameters,
clt_parameters.bgnd_range, // double disparity_far,
clt_parameters.grow_disp_max, // other_range, //double disparity_near, //
geometryCorrection,
threadsMax, // maximal number of threads to launch
updateStatus,
0); // final int debugLevel)
tp.showScan(
tp.clt_3d_passes.get(next_pass-1), // CLTPass3d scan,
"after_pass3-"+(next_pass-1)); //String title)
// create x3d file
X3dOutput x3dOutput = new X3dOutput(
clt_parameters,
correctionsParameters,
geometryCorrection,
tp.clt_3d_passes);
x3dOutput.generateBackground();
String x3d_path= correctionsParameters.selectX3dDirectory(
true, // smart,
true); //newAllowed, // save
for (int scanIndex = next_pass; scanIndex < tp.clt_3d_passes.size(); scanIndex++){
if (debugLevel > 0){
System.out.println("FPGA processing scan #"+scanIndex);
}
CLTPass3d scan = CLTMeasure( // perform single pass according to prepared tiles operations and disparity
image_data, // first index - number of image in a quad
clt_parameters,
scanIndex,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
/**
if ((scanIndex == 49) || (scanIndex == 54) ) tp.showScan(
scan, // tp.clt_3d_passes.get(scanIndex), // CLTPass3d scan,
"MEASURED-"+scanIndex);
*/
}
// TEMPORARY EXIT
// if (tp.clt_3d_passes.size() > 0) return null; // just to fool compiler
// int scan_limit = 10;
for (int scanIndex = next_pass; (scanIndex < tp.clt_3d_passes.size()) && (scanIndex < clt_parameters.max_clusters); scanIndex++){ // just temporary limiting
if (debugLevel > -1){
System.out.println("Generating cluster images (limit is set to "+clt_parameters.max_clusters+") largest, scan #"+scanIndex);
}
// ImagePlus cluster_image = getPassImage( // get image form a single pass
String texturePath = getPassImage( // get image from a single pass
clt_parameters,
colorProcParameters,
rgbParameters,
this.image_name+"-img"+scanIndex,
scanIndex,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
CLTPass3d scan = tp.clt_3d_passes.get(scanIndex);
if ((scanIndex == 73) ) {
tp.showScan(
tp.clt_3d_passes.get(scanIndex), // CLTPass3d scan,
"SELECTED-"+scanIndex);
}
// TODO: use new updated disparity, for now just what was forced for the picture
double [] scan_disparity = new double [tilesX * tilesY];
int indx = 0;
// boolean [] scan_selected = scan.getSelected();
for (int ty = 0; ty < tilesY; ty ++) for (int tx = 0; tx < tilesX; tx ++){
// scan_selected[indx] = scan.tile_op[ty][tx] != 0;
scan_disparity[indx++] = scan.disparity[ty][tx];
}
if (clt_parameters.avg_cluster_disp){
double sw = 0.0, sdw = 0.0;
for (int i = 0; i< scan_disparity.length; i++){
if (scan.selected[i] && !scan.border_tiles[i]){
double w = scan.disparity_map[ImageDtt.DISPARITY_STRENGTH_INDEX][i];
sw +=w;
sdw += scan_disparity[i]*w;
}
}
sdw/=sw;
for (int i = 0; i< scan_disparity.length; i++){
scan_disparity[i] = sdw;
}
}
if ((scanIndex == 73)) {
tp.showScan(
tp.clt_3d_passes.get(scanIndex), // CLTPass3d scan,
"X3D-"+scanIndex);
}
boolean showTri = ((scanIndex < next_pass + 1) && clt_parameters.show_triangles) ||(scanIndex == 73);
// boolean showTri = ((scanIndex < next_pass + 1) && clt_parameters.show_triangles) ||(scanIndex == 49) || (scanIndex == 54);
generateClusterX3d(
x3dOutput,
texturePath,
scan.bounds,
scan.selected,
scan_disparity, // scan.disparity_map[ImageDtt.DISPARITY_INDEX_CM],
clt_parameters.transform_size,
clt_parameters.correct_distortions, // requires backdrop image to be corrected also
showTri, // (scanIndex < next_pass + 1) && clt_parameters.show_triangles,
clt_parameters.bgnd_range, // 0.3
clt_parameters.grow_disp_max, // other_range, // 2.0 'other_range - difference from the specified (*_CM)
clt_parameters.maxDispTriangle);
}
// now generate and save texture files (start with full, later use bounding rectangle?)
if (x3d_path != null){
x3d_path+=Prefs.getFileSeparator()+this.image_name+".x3d";
x3dOutput.generateX3D(x3d_path);
}
return true;
// return imp_bgnd; // relative (to x3d directory) path - (String) imp_bgnd.getProperty("name");
}
//*****************************************************************
public void generateClusterX3d(
X3dOutput x3dOutput,
String texturePath,
......
......@@ -52,16 +52,17 @@ public class SuperTiles{
double [][][] maxMinMax = null;
double [] bgDisparity = null;
double [] bgStrength = null;
// TileProcessor.CLTPass3d cltPass3d;
// TileProcessor.CLTPass3d cltPass3d;
CLTPass3d cltPass3d;
// ArrayList<TilePlanes.PlaneData>[] planes = null;
// ArrayList<TilePlanes.PlaneData>[] planes = null;
TilePlanes.PlaneData [][] planes = null;
//
TilePlanes.PlaneData [][] planes_mod = null;
double [][][] fuse_coeff = null; // coefficients to fuse planes in neighbor supertiles
int [][] shell_map = null; // per supertile, per disparity plane - shell index + 1 (0 - none)
double [][] surfaces; // per shell, per tile (linescan order) disparity value or NaN in missing supertiles
double [][][] fuse_coeff = null; // coefficients to fuse planes in neighbor supertiles
public SuperTiles(
CLTPass3d cltPass3d,
......@@ -84,7 +85,7 @@ public class SuperTiles{
this.strength_floor = strength_floor;
this.strength_pow = strength_pow;
this.stBlurSigma = stBlurSigma;
// this.step_threshold_near = this.step_threshold_far * this.step_far / step_near;
// this.step_threshold_near = this.step_threshold_far * this.step_far / step_near;
this.step_threshold_near = this.step_threshold_far * step_near / this.step_far ;
this.bin_far = this.step_threshold_far / this.step_far;
this.bin_near = this.step_threshold_far / this.step_far * (Math.log(this.step_near/this.step_far) + 1);
......@@ -217,8 +218,8 @@ public class SuperTiles{
} else {
bin = (int) Math.round(bin_near + (x - step_threshold_near) / step_near);
}
// if (bin < 0) bin = 0;
// else if (bin >= numBins) bin = numBins - 1;
// if (bin < 0) bin = 0;
// else if (bin >= numBins) bin = numBins - 1;
return bin;
}
......@@ -372,7 +373,7 @@ public class SuperTiles{
final double [][] dispHist = this.disparityHistograms;
final double sigma = this.stBlurSigma;
final int sTiles = dispHist.length;
// final int numBins = dispHist[0].length;
// final int numBins = dispHist[0].length;
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
......@@ -537,7 +538,7 @@ public class SuperTiles{
final int sTiles = dispHist.length;
final int sTilesY = sTiles / sTilesX;
// final int numBins = dispHist[0].length; // [0] - weight
// final int numBins = dispHist[0].length; // [0] - weight
final int sTileHeight = (sTileHeight0 > 0)? sTileHeight0 : numBins;
final double [] maxHist = new double [sTiles];
......@@ -594,10 +595,10 @@ public class SuperTiles{
final double [] strengthHist = stStrength;
final int sTilesX = (tileProcessor.getTilesX() + superTileSize -1)/superTileSize;
// final int sTiles = disparityHistograms.length;
// final int sTiles = disparityHistograms.length;
final int sTiles = maxMinMax.length;
final int sTilesY = sTiles / sTilesX;
// final int numBins = dispHist[0].length; // [0] - weight
// final int numBins = dispHist[0].length; // [0] - weight
final int sTileHeight = (sTileHeight0 > 0)? sTileHeight0 : numBins;
final double [] maxHist = new double [sTiles];
......@@ -722,7 +723,7 @@ public class SuperTiles{
}
}
//maxIndex is what we need. Which strength to use - individual or accumulated? Use individual.
/// bgDisparity[nsTile] = min_disparity + mmm[2 * maxIndex][0] * step_disparity;
/// bgDisparity[nsTile] = min_disparity + mmm[2 * maxIndex][0] * step_disparity;
bgDisparity[nsTile] = binToDisparity (mmm[2 * maxIndex][0]);
bgStrength[nsTile] = mmm[2 * maxIndex][1];
}
......@@ -922,7 +923,7 @@ public class SuperTiles{
}
}
/*
/*
double [][][] rslt = {
eig.getD().getArray(),
eig.getV().getArray(),
......@@ -1157,7 +1158,7 @@ public class SuperTiles{
{
double corrV = maxEigen;
if ((dispNorm > 0.0) && (disparity > dispNorm)) {
// double dd = (dispNorm + z0)/ dispNorm; // > 1
// double dd = (dispNorm + z0)/ dispNorm; // > 1
double dd = disparity/ dispNorm; // > 1
corrV *= dd * dd; // > original
}
......@@ -1183,7 +1184,7 @@ public class SuperTiles{
final int dbg_Y)
{
if (maxMinMax == null) getMaxMinMax();
// final int np_min = 5; // minimal number of points to consider
// final int np_min = 5; // minimal number of points to consider
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
......@@ -1202,13 +1203,13 @@ public class SuperTiles{
final int len2 = superTileSize2*superTileSize2;
final double [] double_zero = new double [len2];
final boolean [] boolean_zero = new boolean [len2];
//ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];
// this.planes = (ArrayList<TilePlanes.PlaneData>[]) new ArrayList[nStiles];
//ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];
// this.planes = (ArrayList<TilePlanes.PlaneData>[]) new ArrayList[nStiles];
this.planes = new TilePlanes.PlaneData[nStiles][];
// final int debug_stile = 18 * stilesX + 25;
// final int debug_stile = 20 * stilesX + 24;
// final int debug_stile = 16 * stilesX + 27; // 10;
// final int debug_stile = 18 * stilesX + 25;
// final int debug_stile = 20 * stilesX + 24;
// final int debug_stile = 16 * stilesX + 27; // 10;
final int debug_stile = (debugLevel > -1)? (dbg_Y * stilesX + dbg_X):-1;
......@@ -1263,15 +1264,15 @@ public class SuperTiles{
planes[nsTile] = null;
if (sw >0){
ArrayList<TilePlanes.PlaneData> st_planes = new ArrayList<TilePlanes.PlaneData>();
// int dl = ((nsTile >= debug_stile-1) && (nsTile <= debug_stile+1) ) ? 1 : 0;
// int dl = ((stileY == 17) && (stileX > 4)) ? 1 : 0;
// int dl = (stileY >= 0) ? 1 : 0;
// int dl = ((nsTile >= debug_stile-1) && (nsTile <= debug_stile+1) ) ? 1 : 0;
// int dl = ((stileY == 17) && (stileX > 4)) ? 1 : 0;
// int dl = (stileY >= 0) ? 1 : 0;
int dl1 = (nsTile == debug_stile) ? 3 : 0;
// int dl = (nsTile == debug_stile) ? 3 : 0;
// int dl = ((stileY >= 15) && (stileY <= 18) && (stileX >= 5) && (stileX <= 31)) ? 1 : 0;
// int dl = ((stileY == 16) && (stileX == 27) ) ? 3 : 0;
// int dl = (nsTile == debug_stile) ? 3 : 0;
// int dl = ((stileY >= 15) && (stileY <= 18) && (stileX >= 5) && (stileX <= 31)) ? 1 : 0;
// int dl = ((stileY == 16) && (stileX == 27) ) ? 3 : 0;
int dl = (nsTile == debug_stile) ? 3 : 0;
// int debugLevel1 = ((sTileXY[0] == 27) && (sTileXY[1] == 16))? 1: 0; // check why v[0][0] <0
// int debugLevel1 = ((sTileXY[0] == 27) && (sTileXY[1] == 16))? 1: 0; // check why v[0][0] <0
boolean [] sel_all = stSel.clone();
......@@ -1472,7 +1473,7 @@ public class SuperTiles{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
int [] wh = {
......@@ -1500,10 +1501,10 @@ public class SuperTiles{
final int [][] dirsYX = {{-1, 0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
TilePlanes.PlaneData [][] neib_planes = new TilePlanes.PlaneData[stilesY * stilesX][];
TilePlanes tpl = null; // new TilePlanes(tileSize,superTileSize, geometryCorrection);
// final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
// final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
final int debug_stile = dbg_Y * stilesX + dbg_X;
// final int debug_stile = -1;
// final int debug_stile = -1;
for (int sty0 = 0; sty0 < stilesY; sty0++){
int sty = sty0 + dirsYX[dir][0];
......@@ -1589,7 +1590,7 @@ public class SuperTiles{
return neib_planes;
}
/**
/**
* Measure how merging of two plains degrades individual flatness (smaller - better). For comparing divide by (w1+w2) to make strong
* planes score better
* @param L1 smallest eigenvalue of the first plane
......@@ -1608,10 +1609,10 @@ public class SuperTiles{
double w1,
double w2)
{
// double Lav = Math.sqrt((L1*L1*w1 + L2*L2*w2)/(w1+w2));
// double Lav = Math.sqrt((L1*L1*w1 + L2*L2*w2)/(w1+w2));
double Lav = (L1*w1 + L2*w2)/(w1+w2);
/// double wors = (L - Lav)*(w1+w2)*(w1+w2) /(Lav*w1*w2);
/// double rquality = (L - Lav)*(w1+w2) /(Lav*w1*w2); // ==wors/(w1+w2) to amplify stronger planes
/// double wors = (L - Lav)*(w1+w2)*(w1+w2) /(Lav*w1*w2);
/// double rquality = (L - Lav)*(w1+w2) /(Lav*w1*w2); // ==wors/(w1+w2) to amplify stronger planes
double rquality = (L - Lav)*(w1+w2)*(w1+w2) /(Lav*w1*w2);
return rquality;
}
......@@ -1623,14 +1624,14 @@ public class SuperTiles{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
final double [] nan_plane = new double [superTileSize*superTileSize];
for (int i = 0; i < nan_plane.length; i++) nan_plane[i] = Double.NaN;
final int [][] dirsYX = {{-1, 0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
// final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 20 * stilesX + 27;
final int debug_stile = dbg_Y * stilesX + dbg_X;
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
......@@ -1647,13 +1648,13 @@ public class SuperTiles{
System.out.println("matchPlanes(): nsTile0 ="+nsTile0);
}
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
// planes[nsTile0][np0].initNeibBest(); //
// planes[nsTile0][np0].initNeibBest(); //
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
this_plane.initMergedValue();
for (int dir = 0; dir < 4; dir++){ // just half directions - relations are symmetrical
int stx = stx0 + dirsYX[dir][1];
int sty = sty0 + dirsYX[dir][0];
// if ((sty < stilesY) && (sty > 0) && (stx < 0)) {
// if ((sty < stilesY) && (sty > 0) && (stx < 0)) {
if ((stx < stilesX) && (sty < stilesY) && (sty > 0)) {
int nsTile = sty * stilesX + stx; // from where to get
if (nsTile >= planes.length){
......@@ -1705,11 +1706,11 @@ public class SuperTiles{
if ( planes[nsTile0] != null) {
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
// this_plane.initMergedValue();
// this_plane.initMergedValue();
for (int dir = 4; dir < 8; dir++){ // other half - copy from opposite
int stx = stx0 + dirsYX[dir][1];
int sty = sty0 + dirsYX[dir][0];
// if ((stx < stilesX) && (sty < stilesY) && (sty > 0)) {
// if ((stx < stilesX) && (sty < stilesY) && (sty > 0)) {
if ((sty < stilesY) && (sty > 0) && (stx > 0)) {
int nsTile = sty * stilesX + stx; // from where to get
......@@ -1726,7 +1727,7 @@ public class SuperTiles{
if (other_planes[np] != null) { // && (other_planes[np].getMergedValue(dir-4) != null)) {
double [] nm = other_planes[np].getMergedValue(dir-4);
if (nm != null) {
// this_plane.setNeibMatch(dir,np, other_planes[np].getMergedValue(dir-4, np0)); //
// this_plane.setNeibMatch(dir,np, other_planes[np].getMergedValue(dir-4, np0)); //
this_plane.setNeibMatch(dir,np, nm[np0]); //
}
}
......@@ -1744,7 +1745,7 @@ public class SuperTiles{
ImageDtt.startAndJoin(threads);
}
// Oscolete?
// Oscolete?
public void selectNeighborPlanes(
final double worst_worsening,
final boolean mutual_only,
......@@ -1753,15 +1754,15 @@ public class SuperTiles{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
final double [] nan_plane = new double [superTileSize*superTileSize];
for (int i = 0; i < nan_plane.length; i++) nan_plane[i] = Double.NaN;
final int [][] dirsYX = {{-1, 0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
// final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
// final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
......@@ -1769,8 +1770,8 @@ public class SuperTiles{
threads[ithread] = new Thread() {
public void run() {
for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) {
// int sty0 = nsTile0 / stilesX;
// int stx0 = nsTile0 % stilesX;
// int sty0 = nsTile0 / stilesX;
// int stx0 = nsTile0 % stilesX;
// int dl = (nsTile0 == debug_stile) ? 1:0;
if ( planes[nsTile0] != null) {
int np0_min = (planes[nsTile0].length > 1) ? 1:0; // Modify if overall plane will be removed
......@@ -1811,7 +1812,7 @@ public class SuperTiles{
for (int nsTile0 = ai.getAndIncrement(); nsTile0 < nStiles; nsTile0 = ai.getAndIncrement()) {
int sty0 = nsTile0 / stilesX;
int stx0 = nsTile0 % stilesX;
// int dl = (nsTile0 == debug_stile) ? 1:0;
// int dl = (nsTile0 == debug_stile) ? 1:0;
if ( planes[nsTile0] != null) {
for (int np0 = 0; np0 < planes[nsTile0].length; np0++){ // nu
TilePlanes.PlaneData this_plane = planes[nsTile0][np0];
......@@ -1835,10 +1836,10 @@ public class SuperTiles{
double w_this = this_plane.getWeight()+other_planes[other_np].getWeight();
double w_other = other_planes[other_np].getWeight() + planes[nsTile0][other_other_np].getWeight();
if (w_this > w_other){ // kill other's love
// other_planes[other_np].setNeibBest(dir + 4, -1);
// other_planes[other_np].setNeibBest(dir + 4, -1);
other_planes[other_np].setNeibBest(dir + 4, np0);
} else { // kill my love
// this_plane.setNeibBest(dir, -1);
// this_plane.setNeibBest(dir, -1);
this_plane.setNeibBest(dir, -1);
}
} else { // other points nowhere, point it to this
......@@ -1858,8 +1859,163 @@ public class SuperTiles{
ImageDtt.startAndJoin(threads);
}
}
public void fillSquares()
{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
for (int stY = 0; stY < (stilesY - 1); stY++ ) {
for (int stX = 0; stX < (stilesX - 1); stX++ ) {
int nsTile = stY * stilesX + stX;
TilePlanes.PlaneData [][] planes4 = {
planes[nsTile],
planes[nsTile + 1],
planes[nsTile + stilesX],
planes[nsTile + stilesX + 1]};
if ((planes4[0] != null) && (planes4[1] != null) && (planes4[2] != null) && (planes4[3] != null)){
for (int np = 0; np < planes4[0].length; np++){
if (planes4[0][np] == null) continue;
int [] neibs0 = planes4[0][np].getNeibBest();
if ((neibs0[2] < 0) || (neibs0[4] < 0)) continue;
if (planes4[1][neibs0[2]] == null) continue;
if (planes4[2][neibs0[4]] == null) continue;
int [] neibs1 = planes4[1][neibs0[2]].getNeibBest();
int [] neibs2 = planes4[2][neibs0[4]].getNeibBest();
if ((neibs1[4] < 0) || (neibs2[2] < 0) || (neibs1[4] != neibs2[2])) continue;
int [] neibs3 = planes4[3][neibs1[4]].getNeibBest();
// got full square, does it already have diagonals
if (neibs0[3] < 0) {
neibs0[3] = neibs1[4];
neibs3[7] = np;
}
if (neibs1[5] < 0){
neibs1[5] = neibs0[4];
neibs2[1] = neibs0[2];
}
}
}
}
}
}
/**
public void cutCorners()
{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
for (int stY = 0; stY < (stilesY - 1); stY++ ) {
for (int stX = 0; stX < (stilesX - 1); stX++ ) {
int nsTile = stY * stilesX + stX;
TilePlanes.PlaneData [][] planes4 = {
planes[nsTile],
planes[nsTile + 1],
planes[nsTile + stilesX],
planes[nsTile + stilesX + 1]};
if (planes4[0] != null) { // && (planes4[1] != null) && (planes4[2] != null)){
for (int np = 0; np < planes4[0].length; np++){
if (planes4[0][np] != null) {
int [] neibs0 = planes4[0][np].getNeibBest();
if ((neibs0[2] >= 0) && (neibs0[4] < 0)){
if (planes4[1][neibs0[2]] != null) {
int [] neibs1 = planes4[1][neibs0[2]].getNeibBest();
if (neibs1[5] >= 0) {
neibs0[4] = neibs1[5];
int [] neibs2 = planes4[2][neibs1[5]].getNeibBest();
neibs2[0] = np; //?
}
}
}
if ((neibs0[2] < 0) && (neibs0[4] >= 0)){
if (planes4[2][neibs0[4]] != null) {
int [] neibs2 = planes4[2][neibs0[4]].getNeibBest();
if (neibs2[1] >= 0) {
neibs0[2] = neibs2[1];
int [] neibs1 = planes4[1][neibs2[1]].getNeibBest();
neibs1[6] = np;
}
}
}
if ((neibs0[2] >= 0) && (neibs0[3] >= 0)){
int [] neibs1 = planes4[1][neibs0[2]].getNeibBest();
int [] neibs3 = planes4[3][neibs0[3]].getNeibBest();
if (neibs1[4] < 0) {
neibs1[4] = neibs0[3];
neibs3[0] = neibs0[2]; //?
}
}
if ((neibs0[3] >= 0) && (neibs0[4] >= 0)){
int [] neibs3 = planes4[3][neibs0[3]].getNeibBest();
int [] neibs2 = planes4[2][neibs0[4]].getNeibBest();
if (neibs2[2] < 0) {
neibs2[2] = neibs0[3];
neibs3[6] = neibs0[4];
}
}
}
}
}
if (planes4[3] != null) { // && (planes4[1] != null) && (planes4[2] != null)){
for (int np = 0; np < planes4[3].length; np++){
if (planes4[3][np] != null){
int [] neibs3 = planes4[3][np].getNeibBest();
if ((neibs3[0] >= 0) && (neibs3[7] >= 0)){
int [] neibs0 = planes4[0][neibs3[7]].getNeibBest();
int [] neibs1 = planes4[1][neibs3[0]].getNeibBest();
if (neibs0[2] < 0) {
neibs0[2] = neibs3[0];
neibs1[6] = neibs3[7];
}
}
if ((neibs3[6] >= 0) && (neibs3[7] >= 0)){
int [] neibs0 = planes4[0][neibs3[7]].getNeibBest();
int [] neibs2 = planes4[2][neibs3[6]].getNeibBest();
if (neibs0[4] < 0) {
neibs0[4] = neibs3[6];
neibs2[0] = neibs3[7]; //?
}
}
if ((neibs3[7] >= 0) && (neibs3[6] < 0)){
int [] neibs0 = planes4[0][neibs3[7]].getNeibBest();
if (neibs0[4] >= 0) {
int [] neibs2 = planes4[2][neibs0[4]].getNeibBest();
neibs3[6] = neibs0[4];
neibs2[2] = np; //?
}
}
if ((neibs3[6] >= 0) && (neibs3[0] < 0)){
int [] neibs2 = planes4[2][neibs3[6]].getNeibBest();
if (neibs2[1] >= 0) {
int [] neibs1 = planes4[1][neibs2[1]].getNeibBest();
neibs3[0] = neibs2[1]; //?
neibs1[4] = np;
}
}
}
}
}
}
}
}
/**
* Find mutual links between multi-layer planes for supertiles. requires that for each plane there are calculated smalles eigenvalues
* for merging with each plane for each of 8 neighbors
* @param rquality maximal degradation by merging (does not depend on the total weight)
......@@ -1881,16 +2037,16 @@ public class SuperTiles{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int nStiles = stilesX * stilesY;
final double [] nan_plane = new double [superTileSize*superTileSize];
for (int i = 0; i < nan_plane.length; i++) nan_plane[i] = Double.NaN;
final int [][] dirsYX = {{-1, 0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
// final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
// final int debug_stile = 9 * stilesX + 26;
// final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
// final int debug_stile = 9 * stilesX + 26;
final int debug_stile = dbg_Y * stilesX + dbg_X;
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
......@@ -1974,7 +2130,7 @@ public class SuperTiles{
merge_ev[np], // double L,
w1, // double w1,
w2); // double w2)
// if (this_rq <= rquality) { // compare with the threshold before applying strengths
// if (this_rq <= rquality) { // compare with the threshold before applying strengths
if ((w1 + w2) * this_rq <= rquality) { // forgive more for weak planes
this_rq /= (w1 + w2); // for comparision reduce this value for stronger planes
if (Double.isNaN(best_rqual) || (this_rq < best_rqual)){ // OK if Double.isNaN(this_rq[np])
......@@ -1998,7 +2154,7 @@ public class SuperTiles{
this_matched[best_pair[0]] = true;
other_matched[best_pair[1]] = true;
// neib_best should be initialized as int [8];
// planes[nsTile0][0].initNeibBest();
// planes[nsTile0][0].initNeibBest();
planes[nsTile0][best_pair[0]].setNeibBest(dir,best_pair[1]);
planes[nsTile][best_pair[1]].setNeibBest(dir + 4,best_pair[0]);
}
......@@ -2037,7 +2193,7 @@ public class SuperTiles{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int width = stilesX * superTileSize; // * tileSize;
......@@ -2053,9 +2209,9 @@ public class SuperTiles{
superTileSize - 1,
-1,
-superTileSize - 1};
// final int debug_stile = 17 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
final int debug_stile = 20 * stilesX + 27;
// final int debug_stile = 19 * stilesX + 27;
// final int debug_stile = 19 * stilesX + 27;
// scan all get maximal number of satisfying planes
int num_planes = 0;
for (int i = 0; i < planes.length; i++) {
......@@ -2158,7 +2314,7 @@ public class SuperTiles{
final int tilesX = tileProcessor.getTilesX();
final int tilesY = tileProcessor.getTilesY();
final int superTileSize = tileProcessor.getSuperTileSize();
// final int tileSize = tileProcessor.getTileSize();
// final int tileSize = tileProcessor.getTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
final int stilesY = (tilesY + superTileSize -1)/superTileSize;
final int width = stilesX * superTileSize; // * tileSize;
......@@ -2183,7 +2339,7 @@ public class SuperTiles{
stilesX - 1,
-1,
-stilesX - 1};
// final int debug_stile = 17 * stilesX + 27;
// final int debug_stile = 17 * stilesX + 27;
final int debug_stile = -1; // 18 * stilesX + 30;
int num_shells = 0;
......@@ -2493,7 +2649,7 @@ public class SuperTiles{
}
}
}
if (dl > 0){
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);
}
......@@ -2572,6 +2728,9 @@ public class SuperTiles{
final int [] dirs= {-stilesX, -stilesX+1, 1, stilesX+1, stilesX, stilesX-1, -1, -stilesX-1};
boolean [][] field = new boolean [planes.length][];
for (int nsTile = 0; nsTile < planes.length; nsTile++){
if (nsTile==724){
System.out.println("createSupertileShells()1 nsTile="+nsTile);
}
if (planes[nsTile] != null){
field[nsTile] = new boolean [planes[nsTile].length];
if (selection != null) {
......@@ -2580,19 +2739,23 @@ public class SuperTiles{
}
}
if (!use_all && (planes[nsTile].length > 1)){
field[nsTile][0] = false;
field[nsTile][0] = true; // used/prohibited
}
}
}
ArrayList<ArrayList<TPW>> listShells = new ArrayList<ArrayList<TPW>>();
for (int nsTile = 0; nsTile < field.length; nsTile++){
if (nsTile==724){
System.out.println("createSupertileShells()2 nsTile="+nsTile);
}
if (field[nsTile] != null){
for (int np = 0; np < field[nsTile].length; np++){
if (!field[nsTile][np]){
// see if
ArrayList<TPW> listWave = new ArrayList<TPW>();
int read_p = 0;
// int num_cluster = listShells.size()+1;
// int num_cluster = listShells.size()+1;
TPW sp = new TPW(nsTile,np);
field[sp.t][sp.p] = true; // just 1 would be OK
listWave.add(sp);
......@@ -2663,4 +2826,527 @@ public class SuperTiles{
}
return shells;
}
} // end of class SuperTiles
public double normDispADiff(
double disp1,
double disp2,
double disp_norm
)
{
double disp_avg = 0.5* (disp1 + disp2);
double adiff = Math.abs(disp1 - disp2);
return (disp_avg <= disp_norm) ? adiff : (adiff * disp_norm / disp_avg);
}
public double [] snapDisparity(
final double [] disparity,
final double [] strength,
final boolean [] selection, // can be null
final double dispNorm, // plDispNorm
final double snapDispAny, // = .2, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength
final double snapStrengthAny, // = .2, // Maximal strength to fit any distance (if does not fit otherwise - treat as zero strength
final double snapNegAny, // = .2, // Maximal negative disparity difference from the best match
final double snapDispMax, // = .5, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at low strength
final double snapDispWeight, // = .5, // Maximal disparity diff. by weight product to snap to plane
final int snapZeroMode, // Zero strength snap mode: 0: no special treatment, 1 - strongest, 2 - farthest
final int debugLevel)
{
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 double [][] surfaces = getSurfaces();
final int [][] shell_map = getShellMap();
final TilePlanes.PlaneData [][] planes = getPlanesMod(); // to get strength;
final double [] snap_disp = disparity.clone();
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < disparity.length; nTile = ai.getAndIncrement()) {
if ((selection == null) || selection[nTile]) {
int tX = nTile % tilesX;
int tY = nTile / tilesX;
int stX = tX / superTileSize;
int stY = tY / superTileSize;
int nsTile = stY * stilesX + stX;
int nTile_st = (tY * stilesX * superTileSize) + tX; // surfaces maybe (is) larger than tilesX *tilesY if
// tilesX, tilesY are not multiples of superTileSize !
if (nsTile == 724){
// System.out.println("snapDisparity(): tX:tY = "+tX+":"+tY+", stX:stY="+stX+":"+stY+
// ", nTile="+nTile+", nsTile="+nsTile+", nTile_st = "+nTile_st);
}
// is there any surface to snap to?
boolean no_surf = true;
if (shell_map[nsTile] != null){
for (int np = 0; no_surf && (np < shell_map[nsTile].length); np++){
if (shell_map[nsTile][np] > 0) no_surf = false;
}
}
if (!no_surf) {
double [] surf_disparity = new double[shell_map[nsTile].length];
for (int np = 0; np < surf_disparity.length; np++){
if (shell_map[nsTile][np] > 0) {
surf_disparity[np] = surfaces[shell_map[nsTile][np] -1][nTile_st];
} else {
surf_disparity[np] = Double.NaN;
}
}
int best_indx = -1;
double best_disp_diff = Double.NaN;
double this_disp = disparity[nTile];
double this_strength = strength[nTile];
if (Double.isNaN(this_disp)){
this_disp = 0.0;
this_strength = 0.0;
}
for (int np = 0; np < surf_disparity.length; np++){
if (shell_map[nsTile][np] > 0) {
double disp_diff = normDispADiff (this_disp,surf_disparity[np], dispNorm);
if ((best_indx < 0) || (disp_diff < best_disp_diff)) {
best_disp_diff = disp_diff;
best_indx = np;
}
}
}
if ((this_strength > 0.0) || (snapZeroMode == 0)){
if ((best_disp_diff <= snapDispAny) ||
((best_disp_diff <= snapDispMax) && (best_disp_diff * this_strength < snapDispWeight )) ||
((best_disp_diff <= snapNegAny) && (this_disp < surf_disparity[best_indx])) // farther than surface - higher tolerance
){
snap_disp[nTile] = surf_disparity[best_indx]; // snapped (default - keep source disparity
} else if ((this_strength < snapStrengthAny) && (snapZeroMode != 0)){ // treat as zero strength?
this_strength = 0.0;
}
}
if ((this_strength == 0) && (snapZeroMode > 0)) {
if (snapZeroMode == 1) { // zero strength and non-zero snapZeroMode, consider 1 (strongest shell)
best_indx = -1;
double best_strength = Double.NaN;
for (int np = 0; np < surf_disparity.length; np++){
if (shell_map[nsTile][np] > 0) {
double w = planes[nsTile][np].getWeight();
if ((best_indx < 0) || (w > best_strength)) {
best_strength = w;
best_indx = np;
}
}
}
snap_disp[nTile] = surf_disparity[best_indx]; // snapped (default - keep source disparity
} else { // zero strength and snapZeroMode > 1 (now only 2) - farthest surface (smallest disparity)
best_indx = -1;
double smallest_disparity = Double.NaN;
for (int np = 0; np < surf_disparity.length; np++){
if (shell_map[nsTile][np] > 0) {
if ((best_indx < 0) || ( surf_disparity[np] < smallest_disparity)) {
smallest_disparity = surf_disparity[np];
best_indx = np;
}
}
}
snap_disp[nTile] = surf_disparity[best_indx]; // snapped (default - keep source disparity
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return snap_disp;
}
/**
* Get number of used surfaces (some may be empty)
* @param snap_surf surface indices (per-tile), 0 - unmatched
* @param selected boolean tile selection or null (use all tiles)
* @return maximal number of surface used
*/
public int getNumSurf(
int [] snap_surf,
boolean [] selected) // or null
{
final int tilesX = tileProcessor.getTilesX();
final int superTileSize = tileProcessor.getSuperTileSize();
final int stilesX = (tilesX + superTileSize -1)/superTileSize;
int num_surf = 0;
for (int nTile = 0; nTile < snap_surf.length; nTile ++) if (snap_surf[nTile] > 0){
int tX = nTile % tilesX;
int tY = nTile / tilesX;
int stX = tX / superTileSize;
int stY = tY / superTileSize;
int nsTile = stY * stilesX + stX;
int np = snap_surf[nTile] - 1;
if ((shell_map[nsTile][np] > num_surf) && ((selected == null) || selected[nTile])) {
num_surf = shell_map[nsTile][np];
}
}
return num_surf;
}
/**
* Get number of unmatched tiles
* @param snap_surf surface indices (per-tile), 0 - unmatched
* @param selected boolean tile selection or null (use all tiles)
* @return number of unmatched tiles
*/
public int getNumNotMatched(
int [] snap_surf,
boolean [] selected) // or null
{
int num_notmatched = 0;
for (int i = 0; i < snap_surf.length; i++){
if ((snap_surf[i] == 0) && ((selected == null) || selected[i])) {
num_notmatched ++;
}
}
return num_notmatched;
}
public int getNeibMask(
int x,
int y,
int width,
int height)
{
final int [] corn_side_neib = { // of +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
0b00011100, // top left corner
0b01111100, // top middle
0b01110000, // top right
0b00011111, // middle left
0b11111111, // middle
0b11110001, // middle right
0b00000111, // bottom left
0b11000111, // bottom middle
0b11000001}; // bottom right
int tileType = getNeibType(
x,
y,
width,
height);
return corn_side_neib[tileType];
}
/**
* Returns 8-element array - which supertile neighbor enables this tile neighbor (-1 - none)
* @param x horizontal position of the tile in supertile
* @param y vertical position of the tile in supertile
* @param width supertile width
* @param height supertile height
* @return 8-element array
*/
public int[] getNeibBordDir(
int x,
int y,
int width,
int height)
{
final int [][] dir_dir = { // of +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
//N NE E SE S SW W NW
{ 0, 0, -1, -1, -1, 6, 6, 7}, // top left corner
{ 0, 0, -1, -1, -1, -1, -1, 0}, // top middle
{ 0, 1, 2, 2, -1, -1, -1, -1}, // top right
{-1, -1, -1, -1, -1, 6, 6, 6}, // middle left
{-1, -1, -1, -1, -1, -1, -1, -1}, // middle
{ 0, 2, 2, 2, -1, -1, -1, -1}, // middle right
{-1, -1, -1, 4, 4, 5, 6, 6}, // bottom left
{-1, -1, -1, 4, 4, 4, -1, -1}, // bottom middle
{-1, 2, 2, 3, 4, 4, -1, -1}}; // bottom right
int tileType = getNeibType(
x,
y,
width,
height);
return dir_dir[tileType];
}
public int getNeibType(
int x,
int y,
int width,
int height)
{
int tileType = 4;
int hm1 = height -1;
int wm1 = width - 1;
if (y == 0){
if (x == 0){
tileType = 0;
} else if (x == wm1) {
tileType = 2;
} else {
tileType = 1;
}
} else if (y == hm1) {
if (x == 0){
tileType = 6;
} else if (x == wm1) {
tileType = 8;
} else {
tileType = 7;
}
} else {
if (x == 0){
tileType = 3;
} else if (x == wm1) {
tileType = 5;
}
}
return tileType;
}
/**
* Build tile connections to neighbors form optional selection, per-tile plane indices,
* and a surface index.
* @param selected tile selection (or null)
* @param snap_surf per tile array of supertile plane index plus 1 or 0 for unmatched tiles
* @param surf_index number of the surface to extract
* @return per-tile array of -256 for unselected tiles or 8-bit bit mask of the neighbors (0 - N, 1 - NE, ...)
*/
public int [] getNeighbors( // creates neighbors mask from bitmask
final boolean [] selected, // or null
final int [] snap_surf, // use this size - it matches image, not supertiles
final int surf_index)
{
// TODO: see which are needed
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 double [][] surfaces = getSurfaces();
final int [][] shell_map = getShellMap();
final TilePlanes.PlaneData [][] planes = getPlanesMod(); // to get strength and connections
final int [] neibs = new int [selected.length];
final int [] dirs8 = {-tilesX, -tilesX + 1, 1, tilesX + 1, tilesX, tilesX - 1, -1, -tilesX - 1};
// final int [] dirs8st = {-stilesX, -stilesX + 1, 1, stilesX + 1, stilesX, stilesX - 1, -1, -stilesX - 1};
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final int surf_index_plus1 = surf_index + 1;
final int emptyTile = -256;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < snap_surf.length; nTile = ai.getAndIncrement()) {
neibs[nTile] = emptyTile;
if ((selected == null) || selected[nTile]) {
int np = snap_surf[nTile] - 1;
if (np >= 0) {
int tX = nTile % tilesX;
int tY = nTile / tilesX;
int stX = tX / superTileSize;
int stY = tY / superTileSize;
int fX = tX % superTileSize;
int fY = tY % superTileSize;
int nsTile = stY * stilesX + stX;
if (nsTile == 724){
// System.out.println("getNeighbors(): tX:tY = "+tX+":"+tY+", stX:stY="+stX+":"+stY+
// ", nTile="+nTile+", nsTile="+nsTile);
}
if (shell_map[nsTile][np] == surf_index_plus1) {
int tileMask = getNeibMask(
tX,
tY,
tilesX,
tilesY);
int localMask = getNeibMask(
fX,
fY,
superTileSize,
superTileSize);
int [] dir_dir = getNeibBordDir(
fX,
fY,
superTileSize,
superTileSize);
neibs[nTile] = tileMask;
for (int i = 0; i < 8; i++) {
int b = 1 << i;
if ((neibs[nTile] & b) != 0){ // that will prevent tile array bounds violation
int nTile1 = nTile + dirs8[i];
if (!(((selected == null) || selected[nTile1]) && (snap_surf[nTile1] == snap_surf[nTile]))){
neibs[nTile] &= ~b; // same supertile, different index
} else if ((localMask & b) == 0) {// going to the other supertile
int [] neib_best = planes[nsTile][np].getNeibBest(); // array of connected planes indices/ -1s
if ((dir_dir[i] < 0) || (neib_best[dir_dir[i]] != (snap_surf[nTile1] -1))) {
neibs[nTile] &= ~b;
}
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return neibs;
}
/**
* Sort per-tile disparity map values to one of the surfaces
* @param disparity per-tile array of disparity values
* @param strength per-tile array of correlation strength values
* @param selection tile selection (or null to process all tiles)
* @param dispNorm disparity difference normalization - differences for average disparities
* below this value are unchanged, above - proportionally scaled down)
* @param snapDispAny tiles with disparity difference below this will snap to the nearest
* surface for any correlation strength
* @param snapStrengthAny tiles that have lower strength and can not be snapped otherwise are
* treated as zero-strength and obey snapZeroMode parameter
* @param snapNegAny allow snap for tiles that are below (farther) than the closest surface,
* if the disparity difference is below this value
* @param snapDispMax do not snap low-strength tiles if they are farther from the nearest surface
* than this.
* @param snapDispWeight snap tiles in the range snapDispAny and snapDispMax if the product
* of the disparity difference by the strength is below this
* @param snapZeroMode : 0 - no special treatment, 1 snap to strongest surface,
* 2 - snap to the farthest (lowest disparity) surface
* @param debugLevel debug level
* @return integer array with per-tile elements. 0 - no surface candidate found (keep original
* disparity), > 0 - number of the plane plus 1 (use shell_map to get
* the surface number)
*/
public int [] snapSort(
final double [] disparity,
final double [] strength,
final boolean [] selection, // can be null
final double dispNorm, // plDispNorm
final double snapDispAny, // = .2, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength
final double snapStrengthAny, // = .2, // Maximal strength to fit any distance (if does not fit otherwise - treat as zero strength
final double snapNegAny, // = .2, // Maximal negative disparity difference from the best match
final double snapDispMax, // = .5, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at low strength
final double snapDispWeight, // = .5, // Maximal disparity diff. by weight product to snap to plane
final int snapZeroMode, // Zero strength snap mode: 0: no special treatment, 1 - strongest, 2 - farthest
final int debugLevel)
{
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 double [][] surfaces = getSurfaces();
final int [][] shell_map = getShellMap();
final TilePlanes.PlaneData [][] planes = getPlanesMod(); // to get strength;
// final double [] snap_disp = disparity.clone();
final int [] snap_sort = new int [disparity.length];
final Thread[] threads = ImageDtt.newThreadArray(tileProcessor.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < disparity.length; nTile = ai.getAndIncrement()) {
if ((selection == null) || selection[nTile]) {
int tX = nTile % tilesX;
int tY = nTile / tilesX;
int stX = tX / superTileSize;
int stY = tY / superTileSize;
int nsTile = stY * stilesX + stX;
int nTile_st = (tY * stilesX * superTileSize) + tX; // surfaces maybe (is) larger than tilesX *tilesY if
// tilesX, tilesY are not multiples of superTileSize !
if (nsTile == 724){
// System.out.println("snapDisparity(): tX:tY = "+tX+":"+tY+", stX:stY="+stX+":"+stY+
// ", nTile="+nTile+", nsTile="+nsTile+", nTile_st = "+nTile_st);
}
// is there any surface to snap to?
boolean no_surf = true;
if (shell_map[nsTile] != null){
for (int np = 0; no_surf && (np < shell_map[nsTile].length); np++){
if (shell_map[nsTile][np] > 0) no_surf = false;
}
}
if (!no_surf) {
double [] surf_disparity = new double[shell_map[nsTile].length];
for (int np = 0; np < surf_disparity.length; np++){
if (shell_map[nsTile][np] > 0) {
surf_disparity[np] = surfaces[shell_map[nsTile][np] -1][nTile_st];
} else {
surf_disparity[np] = Double.NaN;
}
}
int best_indx = -1;
double best_disp_diff = Double.NaN;
double this_disp = disparity[nTile];
double this_strength = strength[nTile];
if (Double.isNaN(this_disp)){
this_disp = 0.0;
this_strength = 0.0;
}
for (int np = 0; np < surf_disparity.length; np++){
if (shell_map[nsTile][np] > 0) {
double disp_diff = normDispADiff (this_disp,surf_disparity[np], dispNorm);
if ((best_indx < 0) || (disp_diff < best_disp_diff)) {
best_disp_diff = disp_diff;
best_indx = np;
}
}
}
if ((this_strength > 0.0) || (snapZeroMode == 0)){
if ((best_disp_diff <= snapDispAny) ||
((best_disp_diff <= snapDispMax) && (best_disp_diff * this_strength < snapDispWeight )) ||
((best_disp_diff <= snapNegAny) && (this_disp < surf_disparity[best_indx])) // farther than surface - higher tolerance
){
snap_sort[nTile] = best_indx+1; // snapped (default - keep source disparity
} else if ((this_strength < snapStrengthAny) && (snapZeroMode != 0)){ // treat as zero strength?
this_strength = 0.0;
}
}
if ((this_strength == 0) && (snapZeroMode > 0)) {
if (snapZeroMode == 1) { // zero strength and non-zero snapZeroMode, consider 1 (strongest shell)
best_indx = -1;
double best_strength = Double.NaN;
for (int np = 0; np < surf_disparity.length; np++){
if (shell_map[nsTile][np] > 0) {
double w = planes[nsTile][np].getWeight();
if ((best_indx < 0) || (w > best_strength)) {
best_strength = w;
best_indx = np;
}
}
}
snap_sort[nTile] = best_indx+1; // snapped (default - keep source disparity
} else { // zero strength and snapZeroMode > 1 (now only 2) - farthest surface (smallest disparity)
best_indx = -1;
double smallest_disparity = Double.NaN;
for (int np = 0; np < surf_disparity.length; np++){
if (shell_map[nsTile][np] > 0) {
if ((best_indx < 0) || ( surf_disparity[np] < smallest_disparity)) {
smallest_disparity = surf_disparity[np];
best_indx = np;
}
}
}
snap_sort[nTile] = best_indx+1;
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return snap_sort;
}
} // end of class SuperTiles
......@@ -764,10 +764,10 @@ public class TilePlanes {
// double px = tileSize*(superTileSize * sTileXY[0] + superTileSize/2) + zxy[1]; // [3] - plane point {disparity, x, y), x=0, y=0 is a 4,4 point of an 8x8 supertile
// double py = tileSize*(superTileSize * sTileXY[1] + superTileSize/2) + zxy[2];
double [] px_py = getCenterPxPy();
if ((px_py[0] == 1760) && (px_py[1] == 1056)){ // 27, 15
System.out.println("getWorldXYZ, px_py = {"+px_py[0]+","+px_py[1]+"}");
debugLevel = 2;
}
// if ((px_py[0] == 1760) && (px_py[1] == 1056)){ // 27, 15
// System.out.println("getWorldXYZ, px_py = {"+px_py[0]+","+px_py[1]+"}");
// debugLevel = 2;
// }
double px = px_py[0] + zxy[1];
double py = px_py[1] + zxy[2];
......@@ -780,6 +780,10 @@ public class TilePlanes {
Matrix xyz = new Matrix(center_xyz, 3); // column matrix
Matrix dpxpy = new Matrix(vectors[0],3); // 3 rows, 1 column
if (debugLevel > 0){
// if (sTileXY[0] == 27 ){
// System.out.println("STOP");
//
// }
System.out.println("getWorldXYZ("+sTileXY[0]+","+sTileXY[1]+"), correctDistortions="+correctDistortions+", xyz= {"+
xyz.get(0, 0)+","+xyz.get(1, 0)+","+xyz.get(2, 0)+"}, weight = "+getWeight());
// xyz.print(10, 6); // w,d
......@@ -842,7 +846,7 @@ public class TilePlanes {
}
norm_xyz.timesEquals(1.0/norm_xyz.normF()); // unity normal vector;
if (debugLevel > 0){
if (debugLevel > 1){
System.out.println("+getWorldXYZ("+sTileXY[0]+","+sTileXY[1]+"): unit plane normal={"+
norm_xyz.get(0, 0)+", "+norm_xyz.get(1, 0)+", "+norm_xyz.get(2, 0)+"})");
double dotprod = xyz.transpose().times(norm_xyz).get(0,0);
......@@ -1070,7 +1074,7 @@ public class TilePlanes {
int numRemoved = 0;
for (; (pd.getValue() > targetEigen) && (numRemoved < maxRemoved); numRemoved++){
if (debugLevel > 2){
System.out.println("removePlaneOutliers(): numRemoved = "+numRemoved+" eigenValue = "+pd.getValue()+" target = "+targetEigen);
System.out.println("removePlaneOutliers("+sTileXY[0]+":"+sTileXY[1]+"): numRemoved = "+numRemoved+" eigenValue = "+pd.getValue()+" target = "+targetEigen);
}
// make a plane and find the worst (largest disparity difference) tile
// z = -(x*Vx + y*Vy)/Vz
......
......@@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class TileProcessor {
public ArrayList <CLTPass3d> clt_3d_passes = null;
public int clt_3d_passes_size = 0; //clt_3d_passes size after initial processing
private int tilesX;
private int tilesY;
private double corr_magic_scale = 0.85; // reported correlation offset vs. actual one (not yet understood)
......@@ -82,8 +83,22 @@ public class TileProcessor {
public void resetCLTPasses(){
clt_3d_passes = new ArrayList<CLTPass3d>();
clt_3d_passes_size = 0;
}
public void saveCLTPasses(){
clt_3d_passes_size = clt_3d_passes.size();
}
public void trimCLTPasses(){
while (clt_3d_passes.size() > clt_3d_passes_size){
clt_3d_passes.remove(clt_3d_passes_size);
}
}
/**
* Basic combining: find smallest residual disparity and use the tile data from it
* Copy link to texture tile from the same pass, "forced" bit in tile_op is copied too
......@@ -1319,7 +1334,7 @@ public class TileProcessor {
clusterSize++;
bcluster[i] = true;
}
if (debugLevel > 1) {
if (debugLevel > -1) {
System.out.println("createTileTasks(), cluster #"+ncl+", cluster size = "+clusterSize);
}
if ((clusterSize < minClusterArea) || (clusterSize == 0)) break;
......@@ -1438,6 +1453,116 @@ public class TileProcessor {
public int createTileTasks(
int maxClusters,
int minClusterArea,
double [] disparity_in,
int [] clusters_in,
int debugLevel)
{
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
// adding 1-tile frame around to avoid checking for the borders
int tilesX4 = tilesX + 4;
int tilesY4 = tilesY + 4;
int tlen4 = tilesX4*tilesY4;
double [] disparity0 = new double [tlen4];
int [] clusters = new int [tlen4];
for (int i = 0; i < tlen4; i++) {
clusters[i] = 0;
}
for (int i = 0; i < tilesY; i++) {
for (int j = 0; j < tilesX; j++) {
clusters[(i + 2) * tilesX4 + j + 2] = clusters_in[i * tilesX + j];
disparity0[(i + 2) * tilesX4 + j + 2] = disparity_in[i * tilesX + j];
}
}
int [] dirs8 = {-tilesX4, -tilesX4 + 1, 1, tilesX4 +1, tilesX4, tilesX4 - 1, -1, -tilesX4 - 1};
int [] dirs = dirs8;
int op = ImageDtt.setImgMask(0, 0xf);
op = ImageDtt.setPairMask(op,0xf);
op = ImageDtt.setForcedDisparity(op,true);
int tlen = clusters.length;
int numClusters = 0;
for (int ncl = 0; (maxClusters == 0) || (ncl < maxClusters); ncl++){ // need to break;
double [] disparity = disparity0.clone();
boolean [] bcluster = new boolean [tlen];
int clusterSize = 0;
int cindx = ncl + 1;
for (int i = 0; i < tlen; i++) if (clusters[i] == cindx) {
clusterSize++;
bcluster[i] = true;
}
if (debugLevel > -1) {
System.out.println("createTileTasks(), cluster #"+ncl+", cluster size = "+clusterSize);
}
if ((clusterSize < minClusterArea) || (clusterSize == 0)) break;
boolean [] grown_clusters = bcluster.clone();
growTiles(
2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
grown_clusters,
null,
tilesX4,
tilesY4);
// now fill border pixels disparity disregarding known for that tile
for (int i = 0; i < tlen ; i++){
if (!bcluster[i] && grown_clusters[i]){ // only border
double sd = 0.0;
int n = 0;
for (int d = 0; d < dirs.length; d++){
int indx = i + dirs[d];
if (bcluster[indx]){
sd += disparity[indx];
n++;
}
}
if (n > 0){
disparity[i] = sd/n;
} else {
System.out.println("**** Program BUG, should not happen ****");
disparity[i] = 0.0;
}
}
}
// return to original dimensions
double [][] disparityTask = new double [tilesY][tilesX];
int [][] tile_op = new int [tilesY][tilesX];
boolean [] borderTiles = new boolean[tilesY*tilesX]; // to zero alpha in the images
for (int ty = 0; ty < tilesY; ty++) for (int tx = 0; tx <tilesX; tx++){
int indx = tilesX * ty + tx;
int indx4 = tilesX4 * (ty+2) + (tx + 2);
if (grown_clusters[indx4]){
disparityTask[ty][tx] = disparity[indx4];
tile_op[ty][tx] = op;
borderTiles[indx] = !bcluster[indx4];
} else {
disparityTask[ty][tx] = 0.0;
tile_op[ty][tx] = 0;
borderTiles[indx] = false;
}
}
// Create FPGA task for this cluster
CLTPass3d scan_next =new CLTPass3d(this);
scan_next.disparity = disparityTask;
scan_next.tile_op = tile_op;
scan_next.border_tiles = borderTiles;
clt_3d_passes.add(scan_next);
numClusters++;
}
return numClusters;
}
// temporary - simple separation until continuous tile areas are split along disparity steps
public int [] enumerateClusters(
......@@ -2810,12 +2935,31 @@ public class TileProcessor {
//======================
public void showPlanes(
EyesisCorrectionParameters.CLTParameters clt_parameters,
GeometryCorrection geometryCorrection,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
CLTPass3d scan_prev = clt_3d_passes.get(clt_3d_passes.size() -1); // get last one
SuperTiles st = scan_prev.getSuperTiles();
// moved here
st.processPlanes2(
null, // final boolean [] selected, // or null
0.3, // final double min_disp,
false, // final boolean invert_disp, // use 1/disparity
clt_parameters.plDispNorm, // = 2.0; // Normalize disparities to the average if above
clt_parameters.plMinPoints, // = 5; // Minimal number of points for plane detection
clt_parameters.plTargetEigen, // = 0.1; // Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below
clt_parameters.plFractOutliers, // = 0.3; // Maximal fraction of outliers to remove
clt_parameters.plMaxOutliers, // = 20; // Maximal number of outliers to remove
geometryCorrection,
clt_parameters.correct_distortions,
0, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
......@@ -2831,6 +2975,15 @@ public class TileProcessor {
0, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
if (clt_parameters.plFillSquares){
st.fillSquares();
}
if (clt_parameters.plCutCorners){
st.cutCorners();
}
TilePlanes.PlaneData [][] planes_mod = null;
// smooth planes (by averaging with neighbors and the "measured" one with variable "pull")
......@@ -2936,6 +3089,104 @@ public class TileProcessor {
10.0, // double arrow_dark,
10.0); // double arrow_white)
sdfa_instance.showArrays(plane_data, wh[0], wh[1], true, "shells");
// also test snap here
int [] snap_surf = st.snapSort(
st.cltPass3d.getDisparity(), // final double [] disparity,
st.cltPass3d.getStrength(), // final double [] strength,
st.cltPass3d.getSelected(), // null, // this_selection, // final boolean [] selection, // can be null
clt_parameters.plDispNorm, // final double dispNorm, // plDispNorm
clt_parameters.plSnapDispAny, //final double snapDispAny, // = .2, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength
clt_parameters.plSnapStrengthAny,//final double snapStrengthAny, // = .2, // Maximal strength to fit any distance (if does not fit otherwise - treat as zero strength
clt_parameters.plSnapNegAny, //final double snapNegAny, // = .2, // Maximal negative disparity difference from the best match
clt_parameters.plSnapDispMax, // final double snapDispMax, // = .5, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at low strength
clt_parameters.plSnapDispWeight, // final double snapDispWeight, // = .5, // Maximal disparity diff. by weight product to snap to plane
clt_parameters.plSnapZeroMode, // final int snapZeroMode, // Zero strength snap mode: 0: no special treatment, 1 - strongest, 2 - farthest
1); // final int debugLevel)
double [] snap_disparity = st.snapDisparity(
st.cltPass3d.getDisparity(), // final double [] disparity,
st.cltPass3d.getStrength(), // final double [] strength,
null, // this_selection, // final boolean [] selection, // can be null
clt_parameters.plDispNorm, // final double dispNorm, // plDispNorm
clt_parameters.plSnapDispAny, //final double snapDispAny, // = .2, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength
clt_parameters.plSnapStrengthAny,//final double snapStrengthAny, // = .2, // Maximal strength to fit any distance (if does not fit otherwise - treat as zero strength
clt_parameters.plSnapNegAny, //final double snapNegAny, // = .2, // Maximal negative disparity difference from the best match
clt_parameters.plSnapDispMax, // final double snapDispMax, // = .5, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at low strength
clt_parameters.plSnapDispWeight, // final double snapDispWeight, // = .5, // Maximal disparity diff. by weight product to snap to plane
clt_parameters.plSnapZeroMode, // final int snapZeroMode, // Zero strength snap mode: 0: no special treatment, 1 - strongest, 2 - farthest
1); // final int debugLevel)
double [] snap_disparity_masked = snap_disparity.clone();
double [] disparity_masked = st.cltPass3d.getDisparity().clone();
double [] strength_masked = st.cltPass3d.getStrength().clone();
boolean [] selected = st.cltPass3d.getSelected();
for (int i = 0; i < snap_disparity_masked.length; i++){
if ( !selected[i]){
disparity_masked[i] = Double.NaN;
snap_disparity_masked[i] = Double.NaN;
strength_masked[i] = Double.NaN;
}
}
String [] snap_titles = {"disp","snap_disp","strength","disp_masked","snap_disp_masked","unmatched","strength_masked"};
double [][] snap_img = new double [snap_titles.length][];
snap_img[5] = new double [snap_surf.length];
for (int i = 0; i < snap_surf.length; i++){
snap_img[5][i] = (selected[i] && (snap_surf[i] == 0)) ? 10.0: 0.0;
}
snap_img[0] = st.cltPass3d.getDisparity();
snap_img[1] = snap_disparity;
snap_img[2] = st.cltPass3d.getStrength();
snap_img[3] = disparity_masked;
snap_img[4] = snap_disparity_masked;
snap_img[6] = strength_masked;
sdfa_instance.showArrays(snap_img, tilesX, tilesY, true, "snap",snap_titles);
boolean [] these_tiles = scan_prev.getSelected();
DisparityProcessor dp = new DisparityProcessor(this, clt_parameters.transform_size * geometryCorrection.getScaleDzDx());
boolean [] grown = these_tiles.clone();
growTiles(
2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
grown, // boolean [] tiles,
null); // boolean [] prohibit)
boolean [] border = grown.clone();
for (int i = 0; i < border.length; i++) border[i] &= !these_tiles[i];
int num_unmatched = st.getNumNotMatched(
snap_surf,
these_tiles);
int num_surf = st.getNumSurf(
snap_surf,
null); // these_tiles);
if (debugLevel > -1){
System.out.println("thirdPassSetup(): surfaces = "+num_surf+" left unmatched="+num_unmatched);
}
int [][] neib_surf = new int [num_surf][];
double [][] dbg_neibs = new double [num_surf][];
for (int ns = 0 ; ns < num_surf; ns ++){
neib_surf[ns] = st.getNeighbors( // creates neighbors mask from bitmask
these_tiles, // final boolean [] selected, // or null
snap_surf, // final int [] snap_surf, // use this size - it matches image, not supertiles
ns); // final int surf_index)
dbg_neibs[ns]= dp.dbgShowNeighbors(
these_tiles, // grown, // these_tiles,
neib_surf[ns], // _orig, // int [] neighbors,
clt_parameters.transform_size, // int tile_size,
-1.0, // Double.NaN, // double bgnd,
10.0); // double fgnd)
}
sdfa_instance.showArrays(dbg_neibs,
tilesX*clt_parameters.transform_size,
tilesY*clt_parameters.transform_size,
true,
"surf-neighbors");
}
}
......@@ -3043,8 +3294,27 @@ public class TileProcessor {
scan_prev.combineHorVertStrength(true, false); // strength now max of original and horizontal. Use scale instead of boolean?
}
double [] this_disparity = scan_prev.getDisparity(); // returns a copy of the FPGA-generated disparity combined with the target one
double [] this_strength = scan_prev.getStrength(); // cloned, can be modified/ read back
String [] dbg_test_titles = {"was_selected","these_tiles", "disparity","strength"};
double [][] dbg_test_img = new double [dbg_test_titles.length][];
dbg_test_img[0] = new double [tilesX * tilesY];
dbg_test_img[1] = new double [tilesX * tilesY];
boolean [] dbg_test_selected = scan_prev.getSelected();
for (int i = 0; i < dbg_test_img[0].length; i++){
if (dbg_test_selected != null) dbg_test_img[0][i] = dbg_test_selected[i]?1.0:0.0;
dbg_test_img[1][i] = these_tiles[i]?1.0:0.0;
}
dbg_test_img[2] = this_disparity;
dbg_test_img[3] = this_strength;
if (sdfa_instance != null) sdfa_instance.showArrays(dbg_test_img, tilesX, tilesY, true, "dbg_test_img",dbg_test_titles);
scan_prev.setSelected(these_tiles); // New
//************************************************
// Show supertiles histograms
......@@ -3090,7 +3360,7 @@ public class TileProcessor {
if (show_st){
sdfa_instance.showArrays(dbg_hist, hist_width0, hist_height0, true, "disparity_supertiles_histograms",dbg_st_titles);
}
/**
st.processPlanes2(
null, // final boolean [] selected, // or null
0.3, // final double min_disp,
......@@ -3107,13 +3377,6 @@ public class TileProcessor {
clt_parameters.tileY);
if (debugLevel < 100) {
return; // just temporarily
}
if (use_supertiles) {
scan_prev.getBgDispStrength( // calculate (check non-null)?
clt_parameters.stMinBgDisparity, // final double minBgDisparity,
......@@ -3131,9 +3394,61 @@ public class TileProcessor {
if (dbg_with_super_disp != null) dbg_with_super_disp = dbg_with_super_disp.clone(); // else no super disparity available
}
*/
}
// replace weak outlier tiles with weighted averages (modifies disparity)
boolean[] outlayers = scan_prev.replaceWeakOutlayers(
// return scan_next;
}
//==================
public void thirdPassSetup( // prepare tile tasks for the second pass based on the previous one(s)
EyesisCorrectionParameters.CLTParameters clt_parameters,
double disparity_far, //
double disparity_near, //
GeometryCorrection geometryCorrection,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
CLTPass3d scan_prev = clt_3d_passes.get(clt_3d_passes.size() -1); // get last one
/// double [] dbg_orig_disparity = null;
/// double [] dbg_with_super_disp = null;
/// double [] dbg_outlayers = null;
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
boolean [] these_tiles = scan_prev.getSelected();
double [] this_disparity = scan_prev.getDisparity(); // returns a copy of the FPGA-generated disparity combined with the target one
double [] this_strength = scan_prev.getStrength(); // cloned, can be modified/ read back
scan_prev.fixNaNDisparity(
null, // border, // boolean [] select, // which tiles to correct (null - all)
scan_prev.getDisparity(), // double [] disparity,
scan_prev.getStrength()); // double [] strength)
/// dbg_orig_disparity = this_disparity.clone();
SuperTiles st = scan_prev.getSuperTiles();
// if (clt_parameters.plSnapDispAny >= 0.0) {
double [] snap_disparity = st.snapDisparity(
this_disparity, // final double [] disparity,
this_strength, // final double [] strength,
null, // this_selection, // final boolean [] selection, // can be null
clt_parameters.plDispNorm, // final double dispNorm, // plDispNorm
clt_parameters.plSnapDispAny, //final double snapDispAny, // = .2, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength
clt_parameters.plSnapStrengthAny,//final double snapStrengthAny, // = .2, // Maximal strength to fit any distance (if does not fit otherwise - treat as zero strength
clt_parameters.plSnapNegAny, //final double snapNegAny, // = .2, // Maximal negative disparity difference from the best match
clt_parameters.plSnapDispMax, // final double snapDispMax, // = .5, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at low strength
clt_parameters.plSnapDispWeight, // final double snapDispWeight, // = .5, // Maximal disparity diff. by weight product to snap to plane
clt_parameters.plSnapZeroMode, // final int snapZeroMode, // Zero strength snap mode: 0: no special treatment, 1 - strongest, 2 - farthest
1); // final int debugLevel)
System.arraycopy(snap_disparity, 0, this_disparity, 0, snap_disparity.length);
// }
/**
// Replace weak outlayers
if (clt_parameters.replaceWeakOutlayers) {
// boolean[] outlayers =
scan_prev.replaceWeakOutlayers(
null, // final boolean [] selection,
clt_parameters.outlayerStrength , //final double weakStrength, // strength to be considered weak, subject to this replacement
clt_parameters.outlayerDiff, // final double maxDiff)
......@@ -3143,6 +3458,231 @@ public class TileProcessor {
2.0 * disparity_near,
debugLevel);
}
*/
int [] snap_surf = st.snapSort(
this_disparity, // final double [] disparity,
this_strength, // final double [] strength,
null, // this_selection, // final boolean [] selection, // can be null
clt_parameters.plDispNorm, // final double dispNorm, // plDispNorm
clt_parameters.plSnapDispAny, //final double snapDispAny, // = .2, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength
clt_parameters.plSnapStrengthAny,//final double snapStrengthAny, // = .2, // Maximal strength to fit any distance (if does not fit otherwise - treat as zero strength
clt_parameters.plSnapNegAny, //final double snapNegAny, // = .2, // Maximal negative disparity difference from the best match
clt_parameters.plSnapDispMax, // final double snapDispMax, // = .5, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at low strength
clt_parameters.plSnapDispWeight, // final double snapDispWeight, // = .5, // Maximal disparity diff. by weight product to snap to plane
clt_parameters.plSnapZeroMode, // final int snapZeroMode, // Zero strength snap mode: 0: no special treatment, 1 - strongest, 2 - farthest
1); // final int debugLevel)
//
DisparityProcessor dp = new DisparityProcessor(this, clt_parameters.transform_size * geometryCorrection.getScaleDzDx());
boolean [] grown = these_tiles.clone();
growTiles(
2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
grown, // boolean [] tiles,
null); // boolean [] prohibit)
boolean [] border = grown.clone();
for (int i = 0; i < border.length; i++) border[i] &= !these_tiles[i];
int num_unmatched = st.getNumNotMatched(
snap_surf,
these_tiles);
int num_surf = st.getNumSurf(
snap_surf,
null); // these_tiles);
if (debugLevel > -1){
System.out.println("thirdPassSetup(): surfaces = "+num_surf+" left unmatched="+num_unmatched);
}
int [][] neib_surf = new int [num_surf][];
double [][] dbg_neibs = new double [num_surf][];
for (int ns = 0 ; ns < num_surf; ns ++){
neib_surf[ns] = st.getNeighbors( // creates neighbors mask from bitmask
these_tiles, // final boolean [] selected, // or null
snap_surf, // final int [] snap_surf, // use this size - it matches image, not supertiles
ns); // final int surf_index)
dbg_neibs[ns]= dp.dbgShowNeighbors(
these_tiles, // grown, // these_tiles,
neib_surf[ns], // _orig, // int [] neighbors,
clt_parameters.transform_size, // int tile_size,
-1.0, // Double.NaN, // double bgnd,
10.0); // double fgnd)
}
sdfa_instance.showArrays(dbg_neibs,
tilesX*clt_parameters.transform_size,
tilesY*clt_parameters.transform_size,
true,
"surf-neighbors");
int numScans0 = 0;
for (int ns = 0 ; ns < num_surf; ns ++){
// for (int ns = 1 ; (ns < num_surf) && (ns < 2); ns ++){
boolean [] surface_selection = new boolean [these_tiles.length];
for (int i = 0; i < surface_selection.length; i++) {
surface_selection[i] = these_tiles[i] && (neib_surf[ns][i] >= 0);
}
grown = surface_selection.clone();
growTiles(
2, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
grown, // boolean [] tiles,
null); // boolean [] prohibit)
border = grown.clone();
for (int i = 0; i < border.length; i++) border[i] &= !these_tiles[i];
int [] enum_clusters = enumerateClusters(
true, // boolean diag_en,
surface_selection); // grown); // these_tiles); // boolean [] tiles_src)
double [] new_disparity0 = this_disparity.clone();
numScans0 += createTileTasks(
50, // int maxClusters,
0, // int minClusterArea,
new_disparity0, // this_disparity, // [] disparity_in, masked ok too
enum_clusters, // int [] clusters_in,
(ns == 1)?2:0); // debugLevel);
if (debugLevel > -1){
System.out.println("thirdPassSetup(): surface=" + ns + " created "+ numScans0+ " FPGA passes.");
}
}
/**
int [] neighbors = dp.getNeighbors( // creates neighbors mask from bitmask
grown, // these_tiles, // grown, // these_tiles, // boolean [] selected,
tilesX);
// int [] neighbors_orig = neighbors.clone();
double [] dbg_neib = dp.dbgShowNeighbors(
grown, // these_tiles, // grown, // these_tiles,
neighbors, // _orig, // int [] neighbors,
clt_parameters.transform_size, // int tile_size,
-1.0, // double bgnd,
1.0); // double fgnd)
double [] new_disparity = this_disparity.clone();
double [][]dbgDeriv = new double [2][]; // [these_tiles.length];
// sdfa_instance.showArrays(dbg_neib,tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,"neighbors");
dp.smoothDisparity(
clt_parameters.tiDispPull, // final double dispPull, // clt_parameters.tiDispPull or 0.0
3, // final int mask, // 1 - work on internal elements, 2 - on border elements, 3 - both (internal first);
clt_parameters.tiIterations, // final int num_passes,
Math.pow(10.0, -clt_parameters.tiPrecision), // final double maxDiff, // maximal change in any of the disparity values
neighbors, // final int [] neighbors, // +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
this_disparity, // final double [] measured_disparity, // measured disparity
this_strength, // final double [] strength,
null, // this_hor_disparity, // final double hor_disparity, // not yet used
null, // hor_strength_conv, // final double hor_strength, // not yet used
these_tiles, // grown, // these_tiles, // final boolean [] selected,
border, // final boolean [] border,
clt_parameters,
// dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
int [][][] clustersNO= dp.extractNonOlerlap(
true, // diag_en,
neighbors, // +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
grown, // these_tiles, // final boolean [] selected, // only inner?
border, // border should be diagonal!
threadsMax, // maximal number of threads to launch
debugLevel);
int numScans= 0;
if (clt_parameters.shUseFlaps) {
numScans = createTileOverlapTasks(
clt_parameters.max_clusters, // 50, // int maxClusters,
clt_parameters.shMinArea, // int minClusterArea,
new_disparity, // [] disparity_in, masked ok too
this_strength, // double [] strength_in,
Math.pow(10.0, -clt_parameters.tiPrecision), // double maxChange, // adjust border disparity until change is below this.
clt_parameters.shMinStrength, // double minStrength,
clustersNO, // int [] clusters_in,
disparity_far,
disparity_near,
clt_parameters.show_shells,
debugLevel);
} else {
int [] enum_clusters = enumerateClusters(
true, // boolean diag_en,
grown); // these_tiles); // boolean [] tiles_src)
numScans = createTileTasks(
50, // int maxClusters,
0, // int minClusterArea,
new_disparity, // this_disparity, // [] disparity_in, masked ok too
this_strength, // double [] strength_in,
0.0, // double minStrength,
enum_clusters, // int [] clusters_in,
disparity_far,
disparity_near,
debugLevel);
}
if (debugLevel > -1){
System.out.println("thirdPassSetup(): created "+ numScans+ " FPGA passes.");
}
*/
}
public void thirdPassSetupOld( // prepare tile tasks for the second pass based on the previous one(s)
EyesisCorrectionParameters.CLTParameters clt_parameters,
double disparity_far, //
double disparity_near, //
GeometryCorrection geometryCorrection,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
CLTPass3d scan_prev = clt_3d_passes.get(clt_3d_passes.size() -1); // get last one
double [] dbg_orig_disparity = null;
double [] dbg_with_super_disp = null;
double [] dbg_outlayers = null;
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
boolean [] these_tiles = scan_prev.getSelected();
double [] this_disparity = scan_prev.getDisparity(); // returns a copy of the FPGA-generated disparity combined with the target one
double [] this_strength = scan_prev.getStrength(); // cloned, can be modified/ read back
dbg_orig_disparity = this_disparity.clone();
SuperTiles st = scan_prev.getSuperTiles();
if (clt_parameters.plSnapDispAny >= 0.0) {
double [] snap_disparity = st.snapDisparity(
this_disparity, // final double [] disparity,
this_strength, // final double [] strength,
null, // this_selection, // final boolean [] selection, // can be null
clt_parameters.plDispNorm, // final double dispNorm, // plDispNorm
clt_parameters.plSnapDispAny, //final double snapDispAny, // = .2, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at any strength
clt_parameters.plSnapStrengthAny,//final double snapStrengthAny, // = .2, // Maximal strength to fit any distance (if does not fit otherwise - treat as zero strength
clt_parameters.plSnapNegAny, //final double snapNegAny, // = .2, // Maximal negative disparity difference from the best match
clt_parameters.plSnapDispMax, // final double snapDispMax, // = .5, // Maximal (scaled by plDispNorm) disparity difference to snap to plane at low strength
clt_parameters.plSnapDispWeight, // final double snapDispWeight, // = .5, // Maximal disparity diff. by weight product to snap to plane
clt_parameters.plSnapZeroMode, // final int snapZeroMode, // Zero strength snap mode: 0: no special treatment, 1 - strongest, 2 - farthest
1); // final int debugLevel)
System.arraycopy(snap_disparity, 0, this_disparity, 0, snap_disparity.length);
}
if (clt_parameters.replaceWeakOutlayers) {
boolean[] outlayers = scan_prev.replaceWeakOutlayers(
null, // final boolean [] selection,
clt_parameters.outlayerStrength , //final double weakStrength, // strength to be considered weak, subject to this replacement
clt_parameters.outlayerDiff, // final double maxDiff)
clt_parameters.outlayerDiffPos, // final double maxDiff)
clt_parameters.outlayerDiffNeg, // final double maxDiff)
0.5 * disparity_far,
2.0 * disparity_near,
debugLevel);
dbg_outlayers = new double[outlayers.length];
for (int i = 0; i < outlayers.length; i++){
......@@ -3153,19 +3693,19 @@ public class TileProcessor {
if (clt_parameters.stShow){
String [] dbg_disp_tiltes={"masked", "filtered", "disp_combo", "disparity","st_disparity", "strength", "st_strength","outlayers"};
double [][] dbg_disp = new double [dbg_disp_tiltes.length][];
dbg_disp[0] = masked_filtered;
dbg_disp[1] = scan_prev.getDisparity();
dbg_disp[2] = dbg_with_super_disp;
dbg_disp[3] = dbg_orig_disparity;
dbg_disp[0] = masked_filtered; //+
dbg_disp[1] = scan_prev.getDisparity(); //+
dbg_disp[2] = dbg_with_super_disp; // -
dbg_disp[3] = dbg_orig_disparity; //+
dbg_disp[4] = scan_prev.getBgDisparity();
dbg_disp[5] = scan_prev.getStrength();
dbg_disp[5] = scan_prev.getStrength(); //+
dbg_disp[6] = scan_prev.getBgStrength();
dbg_disp[7] = dbg_outlayers;
dbg_disp[7] = dbg_outlayers; // + (all 0)
sdfa_instance.showArrays(dbg_disp, tilesX, tilesY, true, "disparity_supertiles",dbg_disp_tiltes);
}
}
//clt_parameters.transform_size;
//clt_parameters.transform_size;
DisparityProcessor dp = new DisparityProcessor(this, clt_parameters.transform_size * geometryCorrection.getScaleDzDx());
boolean [] grown = these_tiles.clone();
......@@ -3175,20 +3715,21 @@ public class TileProcessor {
null); // boolean [] prohibit)
boolean [] border = grown.clone();
for (int i = 0; i < border.length; i++) border[i] &= !these_tiles[i];
// double [] dbg_before = scan_prev.getDisparity().clone();
// double [] dbg_before = scan_prev.getDisparity().clone();
scan_prev.fixNaNDisparity(
grown, // border, // boolean [] select, // which tiles to correct (null - all)
scan_prev.getDisparity(), // double [] disparity,
scan_prev.getStrength()); // double [] strength)
// double [] dbg_after = scan_prev.getDisparity().clone();
for (int i = 0; i < masked_filtered.length; i++){
if (!grown[i]) masked_filtered[i] = Double.NaN;
}
// double [] dbg_after = scan_prev.getDisparity().clone();
/// for (int i = 0; i < masked_filtered.length; i++){
/// if (!grown[i]) masked_filtered[i] = Double.NaN;
/// }
int [] neighbors = dp.getNeighbors( // creates neighbors mask from bitmask
grown, // these_tiles, // grown, // these_tiles, // boolean [] selected,
tilesX);
// int [] neighbors_orig = neighbors.clone();
// int [] neighbors_orig = neighbors.clone();
double [] dbg_neib = dp.dbgShowNeighbors(
grown, // these_tiles, // grown, // these_tiles,
neighbors, // _orig, // int [] neighbors,
......@@ -3198,7 +3739,7 @@ public class TileProcessor {
double [] new_disparity = this_disparity.clone();
double [][]dbgDeriv = new double [2][]; // [these_tiles.length];
// sdfa_instance.showArrays(dbg_neib,tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,"neighbors");
// sdfa_instance.showArrays(dbg_neib,tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,"neighbors");
dp.smoothDisparity(
clt_parameters.tiDispPull, // final double dispPull, // clt_parameters.tiDispPull or 0.0
......@@ -3214,14 +3755,14 @@ public class TileProcessor {
these_tiles, // grown, // these_tiles, // final boolean [] selected,
border, // final boolean [] border,
clt_parameters,
// dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
// dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
double [] measured_disparity = dp.dbgRescaleToPixels(
this_disparity,
clt_parameters.transform_size); // int tile_size)
// break once
//break once
double [][] stresses = new double [clt_parameters.tiNumCycles + 1][];
double [][] neibs_broken = new double [clt_parameters.tiNumCycles][];
double [][] smooth_disparities = new double [clt_parameters.tiNumCycles + 1][];
......@@ -3232,13 +3773,9 @@ public class TileProcessor {
boolean [] too_near = new boolean [this_strength.length];
double [] true_strength = this_strength.clone(); // this strength will be modified to remove too near tiles (too far - TBD)
for (int numCycle = 0; numCycle < clt_parameters.tiNumCycles; numCycle++) { // = 5; // Number of cycles break-smooth (after the first smooth)
/*
public double tiDispPull = .1; // 10.0 tiDispPull: multiply strength*disparity difference to pull force
public double tiDispPullPreFinal= .1; // 5.0 Scale tiDispPull for pre-final pass
public double tiDispPullFinal = .01; // 2.0 Scale tiDispPull for final pass
*/
/** */
// for (int numCycle = 0; numCycle < clt_parameters.tiNumCycles; numCycle++) { // = 5; // Number of cycles break-smooth (after the first smooth)
for (int numCycle = 0; numCycle < 1; numCycle++) { // = 5; // Number of cycles break-smooth (after the first smooth)
// more smoothing
double disp_pull = clt_parameters.tiDispPull;
......@@ -3249,8 +3786,9 @@ public class TileProcessor {
}
}
double breakScale = disp_pull / clt_parameters.tiDispPull; // 1.0;
/** */
if ((clt_parameters.tiBreakMode & 1) != 0) {
dp.breakDisparity( // break using derivatives
clt_parameters.tiBreak3 * breakScale, // clt_parameters.tiBreak, // final double break4, // clt_parameters.tiBreak/0 allow disconnecting from neighbors (fg/bg)
......@@ -3331,7 +3869,7 @@ public class TileProcessor {
}
}
}
/* */
if ((dbgDeriv != null) && (dbgDeriv[0] != null)) {
stresses[numCycle] = dp.dbgShowStress(
dbgDeriv, // double [][] stress,
......@@ -3401,11 +3939,9 @@ public class TileProcessor {
smooth_disparities[numCycle+1] = dp.dbgRescaleToPixels(
new_disparity,
clt_parameters.transform_size);
}
/** */
// Just calculate stress, do not actually break (after last smoothing)
......@@ -3426,7 +3962,7 @@ public class TileProcessor {
dbgDeriv, // double [][] stress,
clt_parameters.transform_size); // int tile_size)
// String [] titles0 = {"neib", "neib_broken", "stress", "stress1", "disp-measured", "disp-result","disp-result1"};
// String [] titles0 = {"neib", "neib_broken", "stress", "stress1", "disp-measured", "disp-result","disp-result1"};
double [] dbg_far_near=new double[too_far.length];
for (int i = 0; i < dbg_far_near.length; i++){
if (!these_tiles[i]) dbg_far_near[i]= Double.NaN;
......@@ -3496,8 +4032,8 @@ public class TileProcessor {
sdfa_instance.showArrays(dbg_img, tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,
true, "neighbors", titles_all);
}
//disp_diff
//************************************************
//disp_diff
//************************************************
int [][] flaps = dp.createOverlapGeometry(
neighbors, // +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
grown, // these_tiles, // final boolean [] selected, // only inner?
......@@ -3613,11 +4149,14 @@ public class TileProcessor {
}
sdfa_instance.showArrays(disparities, tilesX, tilesY, true, "disparities_scans",titles);
}
// return scan_next;
// return scan_next;
}
//==================
public void secondPassSetupOld( // prepare tile tasks for the second pass based on the previous one(s)
// final double [][][] image_data, // first index - number of image in a quad
......
......@@ -160,10 +160,11 @@ public class X3dOutput {
Element el_appearance = x3dDoc.createElement("Appearance");
el_shape.appendChild(el_appearance);
/*
Element el_material = x3dDoc.createElement("Material");
el_appearance.appendChild(el_material);
el_material.setAttribute("diffuseColor", "0.376471 0.5 0.376471");
*/
Element el_imageTexture = x3dDoc.createElement("ImageTexture");
el_imageTexture.setAttribute("url",url);
......@@ -182,8 +183,6 @@ public class X3dOutput {
el_texCoordinate.setAttribute("point", stcoord);
el_IFC.appendChild(el_texCoordinate);
}
......
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