Commit 6ae8367c authored by Andrey Filippov's avatar Andrey Filippov

started sorting tiles between surfaces

parent 21c0a3c4
......@@ -2212,7 +2212,8 @@ public class EyesisCorrectionParameters {
public boolean msUseSel = true; // Use planes selection masks (generated when splitting to intersecting pairs
public boolean msDivideByArea = true; // Divide plane strengths by ellipsoid area
public double msScaleProj = 1.5; // Scale projection of the plane ellkipsoid
public double msScaleProj = 1.5; // Scale projection of the plane ellipsoid
public double msFractUni = 0.3; // Spread this fraction of the ellipsoid weight among extended (double) supertile
public boolean replaceWeakOutlayers = true; // false;
......@@ -2516,6 +2517,7 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"msUseSel", this.msUseSel+"");
properties.setProperty(prefix+"msDivideByArea", this.msDivideByArea+"");
properties.setProperty(prefix+"msScaleProj", this.msScaleProj +"");
properties.setProperty(prefix+"msFractUni", this.msFractUni +"");
properties.setProperty(prefix+"dbg_migrate", this.dbg_migrate+"");
......@@ -2812,6 +2814,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"msUseSel")!=null) this.msUseSel=Boolean.parseBoolean(properties.getProperty(prefix+"msUseSel"));
if (properties.getProperty(prefix+"msDivideByArea")!=null) this.msDivideByArea=Boolean.parseBoolean(properties.getProperty(prefix+"msDivideByArea"));
if (properties.getProperty(prefix+"msScaleProj")!=null) this.msScaleProj=Double.parseDouble(properties.getProperty(prefix+"msScaleProj"));
if (properties.getProperty(prefix+"msFractUni")!=null) this.msFractUni=Double.parseDouble(properties.getProperty(prefix+"msFractUni"));
if (properties.getProperty(prefix+"dbg_migrate")!=null) this.dbg_migrate=Boolean.parseBoolean(properties.getProperty(prefix+"dbg_migrate"));
......@@ -3134,6 +3137,7 @@ public class EyesisCorrectionParameters {
gd.addCheckbox ("Use planes selection masks (generated when splitting to intersecting pairs", this.msUseSel);
gd.addCheckbox ("Divide plane strengths by ellipsoid area", this.msDivideByArea);
gd.addNumericField("Scale projection of the plane ellipsoid", this.msScaleProj, 6);
gd.addNumericField("Spread this fraction of the ellipsoid weight among extended (double) supertile",this.msFractUni, 6);
gd.addCheckbox ("Test new mode after migration", this.dbg_migrate);
......@@ -3437,6 +3441,7 @@ public class EyesisCorrectionParameters {
this.msUseSel= gd.getNextBoolean();
this.msDivideByArea= gd.getNextBoolean();
this.msScaleProj= gd.getNextNumber();
this.msFractUni= gd.getNextNumber();
this.dbg_migrate= gd.getNextBoolean();
......
......@@ -380,7 +380,7 @@ public class MeasuredLayers {
* @param sel_in optional selection for this supertile (linescan, 4 * supetile size)
* @param disp_far lowest acceptable disparity value. Double.NaN - do not check.
* @param disp_near highest acceptable disparity value. Double.NaN - do not check.
* @param null_if_none return null if there are no selected tiles in teh result selection
* @param null_if_none return null if there are no selected tiles in the result selection
* @return boolean array [4*superTileSize] of the selected tiles on the specified
* measurement layer
*/
......@@ -548,8 +548,9 @@ public class MeasuredLayers {
* @param stX supertile horizontal position in the image
* @param stY supertile vertical position in the image
* @param sel_in optional selection for this supertile (linescan, 4 * supetile size)
* @param null_if_none return null if there are no selected tiles in the result selection
* @param strength_floor subtract from the correlation strength, limit by 0
* @param strength_pow Non-linear treatment of correlation strength. Raise data to the strength_pow power
* @param null_if_none return null if there are no selected tiles in the result selection
* @return double [2][4*superTileSize] {disparity[4*superTileSize], strength [4*superTileSize]}
*/
......@@ -598,6 +599,40 @@ public class MeasuredLayers {
return ds;
}
/**
* Get disparity and correlation strength for the specific measurement layer.
* Combined with input selection
* @param num_layer number of the measurement layer to process
* @param strength_floor subtract from the correlation strength, limit by 0
* @param strength_pow Non-linear treatment of correlation strength. Raise data to the strength_pow power
* @return double {disparity[tilesX * tilesY], strength[tilesX * tilesY]}
*/
public double[][] getDisparityStrength (
int num_layer,
double strength_floor,
double strength_pow)
{
if (layers[num_layer] == null){
return null;
}
double [][] ds = {getDisparity(num_layer),getStrength(num_layer)};
for (int i = 0; i < ds[1].length; i++){
double w = ds[1][i] - strength_floor;
if (w > 0) {
if (strength_pow != 1.0) w = Math.pow(w, strength_pow);
ds[1][i] = w;
} else {
ds[1][i] = 0.0;
}
}
return ds;
}
/**
* Get double-size (for overlapping) array of disparities and strengths for the supertile
* Using best (producing lowest disparity variance) subset of neighbor tiles
......
......@@ -5981,5 +5981,29 @@ public class SuperTiles{
return snap_sort;
}
public double [][][] getDisparityStrengths(
int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
{
int numMeasLayers = measuredLayers.getNumLayers();
double [][][] ds = new double[numMeasLayers][][];
for (int ml = 0; ml < numMeasLayers; ml++) if ((stMeasSel & ( 1 << ml)) != 0) {
ds[ml] = measuredLayers.getDisparityStrength (
ml, // int num_layer,
this.strength_floor, // double strength_floor,
this.strength_pow); // double strength_pow)
}
return ds;
}
public boolean [][] getMeasurementSelections(
int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
{
int numMeasLayers = measuredLayers.getNumLayers();
boolean [][] sels = new boolean[numMeasLayers][];
for (int ml = 0; ml < numMeasLayers; ml++) if ((stMeasSel & ( 1 << ml)) != 0) {
sels[ml] = measuredLayers.getSelection (ml);
}
return sels;
}
} // end of class SuperTiles
......@@ -1475,6 +1475,7 @@ public class TilePlanes {
* @param use_sel use plane selection (this.sel_mask) to select only some part of the plane
* @param divide_by_area divide weights by ellipsoid area
* @param scale_projection use plane ellipsoid projection for weight: 0 - do not use, > 0 linearly scale ellipsoid
* @param fraction_uni add fraction of the total weight to each tile
* @return a pair of arrays {disparity, strength}, each [2 * superTileSize * 2 * superTileSize], only 1/2 or 1/4 used for offset tiles\
* TODO: add a combination of the ellipses and infinite planes?
*
......@@ -1485,6 +1486,7 @@ public class TilePlanes {
boolean use_sel,
boolean divide_by_area,
double scale_projection,
double fraction_uni,
int debugLevel)
{
double [][] disp_strength = new double[2][4*superTileSize*superTileSize];
......@@ -1555,8 +1557,6 @@ public class TilePlanes {
int indx_i = iy * ss4 + ix; // input index
disp_strength[0][indx] = zxy[0] - (normal[1] * x + normal[2] * y)/normal[0];
double w = weight;
if (window != null) w *= window[indx_i];
if (use_sel && (sel_mask != null) && !(sel_mask[indx_i])) w = 0.0;
if ((w > 0.0) && (scale_projection > 0.0)){
double [] xy = {x,y};
Matrix vxy = vect2d.times(new Matrix(xy,2)); // verify if it is correct
......@@ -1565,7 +1565,10 @@ public class TilePlanes {
double d = vxy.get(i,0);
r2 += d * d / val2d.get(i, i);
}
w *= Math.exp(-k_gauss*r2);
w *= ((1.0 - fraction_uni) * Math.exp(-k_gauss*r2) + fraction_uni);
if (window != null) w *= window[indx_i];
if (use_sel && (sel_mask != null) && !(sel_mask[indx_i])) w = 0.0;
}
disp_strength[1][indx] = w;
}
......
......@@ -25,7 +25,7 @@
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
//import java.util.concurrent.atomic.AtomicInteger;
public class TileProcessor {
public ArrayList <CLTPass3d> clt_3d_passes = null;
......@@ -3138,7 +3138,7 @@ public class TileProcessor {
st.selectNeighborPlanesMutual(
clt_parameters.plWorstWorsening, // final double worst_worsening,
clt_parameters.plWeakWorsening, // final double worst_worsening,
clt_parameters.plWeakWorsening, // final double worst_worsening,
clt_parameters.plDispNorm,
clt_parameters.plMaxEigen,
clt_parameters.plMinStrength,
......@@ -3161,6 +3161,10 @@ public class TileProcessor {
}
}
double [][][] dispStrength = st.getDisparityStrengths(
clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
boolean [][] tileSel = st.getMeasurementSelections(
clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
TileSurface tileSurface = new TileSurface(
......@@ -3176,18 +3180,22 @@ public class TileProcessor {
clt_parameters.msUseSel, // final boolean use_sel,
clt_parameters.msDivideByArea, // final boolean divide_by_area,
clt_parameters.msScaleProj, // final double scale_projection,
clt_parameters.msFractUni, // final double fraction_uni,
st.planes, // final TilePlanes.PlaneData [][] planes,
0, // -1, // debugLevel, // final int debugLevel)
clt_parameters.tileX,
clt_parameters.tileY);
/*
clt_parameters.msUseSel, // final boolean msUseSel, // final boolean use_sel,
clt_parameters.msDivideByArea, // final boolean msDivideByArea, // final boolean divide_by_area,
clt_parameters.msScaleProj, //final double msScaleProj, // final double scale_projection,
int [][] tiles_layers = tileSurface.sortTilesToSurfaces(
dispStrength, // final double [][][] dispStrength,
tileSel, // final boolean [][] tileSel,
tileData, // final TileData [][] tileData_src,
// parameters
clt_parameters, // final EyesisCorrectionParameters.CLTParameters clt_parameters,
debugLevel, // final int debugLevel,
clt_parameters.tileX,
clt_parameters.tileY);
*/
......@@ -4461,641 +4469,6 @@ public class TileProcessor {
}
//==================
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
EyesisCorrectionParameters.CLTParameters clt_parameters,
boolean use_supertiles,
int bg_scan_index,
// disparity range - differences from
double disparity_far, //
double disparity_near, //
double this_sure, // minimal strength to be considered definitely background
double this_maybe, // maximal strength to ignore as non-background
double sure_smth, // if 2-nd worst image difference (noise-normalized) exceeds this - do not propagate bgnd
int disparity_index, // index of disparity value in disparity_map == 2 (0,2 or 4)
GeometryCorrection geometryCorrection,
final int threadsMax, // maximal number of threads to launch
final boolean updateStatus,
final int debugLevel)
{
CLTPass3d scan_bg = clt_3d_passes.get(bg_scan_index); //
CLTPass3d scan_prev = clt_3d_passes.get(clt_3d_passes.size() -1); // get last one
// CLTPass3d scan_next =new CLTPass3d(this);
showDoubleFloatArrays sdfa_instance = null;
if (debugLevel > -1) sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
//TODO: for next passes - combine all selected for previous passes (all passes with smaller disparity)
boolean [] these_tiles = combineHorVertDisparity(
scan_prev, // final CLTPass3d scan,
scan_bg.selected, // clt_3d_passes.get(0).selected, // final boolean [] bg_tiles, // get from selected in clt_3d_passes.get(0);
disparity_far, //
disparity_near, //
this_sure, // minimal strength to be considered definitely background
this_maybe, // maximal strength to ignore as non-background
sure_smth, // if 2-nd worst image difference (noise-normalized) exceeds this - do not propagate bgnd
clt_parameters,
debugLevel);
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
//************************************************
// Show supertiles histograms
// if (clt_parameters.stShow){
// try renovated supertiles. Do twice to show both original and blured histograms
double [] dbg_orig_disparity = null;
double [] dbg_with_super_disp = null;
double [] dbg_outlayers = null;
boolean [] grown = these_tiles.clone();
if (use_supertiles) {
String [] dbg_st_titles = {"raw", "blurred"+clt_parameters.stSigma,"max-min-max"};
double [][] dbg_hist = new double[dbg_st_titles.length][];
scan_prev.setSuperTiles(
clt_parameters.stStepNear, // double step_disparity,
clt_parameters.stStepFar, // double step_near,
clt_parameters.stStepThreshold, // double step_threshold,
clt_parameters.stMinDisparity, // double min_disparity,
clt_parameters.stMaxDisparity, // double max_disparity,
clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow,
0.0,// NO BLUR double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[0] = scan_prev.getSuperTiles().showDisparityHistogram();
scan_prev.setSuperTiles(
clt_parameters.stStepNear, // double step_disparity,
clt_parameters.stStepFar, // double step_near,
clt_parameters.stStepThreshold, // double step_threshold,
clt_parameters.stMinDisparity, // double min_disparity,
clt_parameters.stMaxDisparity, // double max_disparity,
clt_parameters.stFloor, // double strength_floor,
clt_parameters.stPow, // double strength_pow,
clt_parameters.stSigma, // with blur double stBlurSigma)
false, //clt_parameters.stSmplMode, // Use sample mode (false - regular tile mode)
clt_parameters.stSmplSide, // Sample size (side of a square)
clt_parameters.stSmplNum, // Number after removing worst
clt_parameters.stSmplRms, // Maximal RMS of the remaining tiles in a sample
clt_parameters.stMeasSel); // bitmask of the selected measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert
dbg_hist[1] = scan_prev.getSuperTiles().showDisparityHistogram();
dbg_hist[2] = scan_prev.getSuperTiles().showMaxMinMax();
if (clt_parameters.stShow){
int hist_width0 = scan_prev.getSuperTiles().showDisparityHistogramWidth();
int hist_height0 = dbg_hist[0].length/hist_width0;
sdfa_instance.showArrays(dbg_hist, hist_width0, hist_height0, true, "disparity_supertiles_histograms",dbg_st_titles);
}
scan_prev.getBgDispStrength( // calculate (check non-null)?
clt_parameters.stMinBgDisparity, // final double minBgDisparity,
clt_parameters.stMinBgFract); // final double minBgFract);
// st_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)
dbg_orig_disparity = scan_prev.getDisparity().clone();
// combine weak with supertiles
dbg_with_super_disp = scan_prev.combineSuper(
true, //boolean updateStrength, // use ST strength if true, keep original (update disparity only) if false
clt_parameters.stStrengthScale, // Multiply st strength if used instead of regular strength (only if updateStrength)
clt_parameters.stUseDisp);
if (dbg_with_super_disp != null) dbg_with_super_disp = dbg_with_super_disp.clone(); // else no super disparity available
} else {
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)
}
// replace weak outlaye tiles with weighted averages (modifies disparity)
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++){
dbg_outlayers[i] = outlayers[i]? 1.0:0.0;
}
double [] masked_filtered = scan_prev.getDisparity().clone();
for (int i = 0; i < masked_filtered.length; i++){
if (!grown[i]) masked_filtered[i] = Double.NaN;
}
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[4] = scan_prev.getBgDisparity();
dbg_disp[5] = scan_prev.getStrength();
dbg_disp[6] = scan_prev.getBgStrength();
dbg_disp[7] = dbg_outlayers;
sdfa_instance.showArrays(dbg_disp, tilesX, tilesY, true, "disparity_supertiles",dbg_disp_tiltes);
}
// prepare new task and run
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
int op = ImageDtt.setImgMask(0, 0xf);
op = ImageDtt.setPairMask(op,0xf);
op = ImageDtt.setForcedDisparity(op,true);
double [] prev_disparity = scan_prev.getDisparity();
for (int ty = 0; ty < tilesY; ty++) for (int tx = 0; tx <tilesX; tx++){
int indx = tilesX * ty + tx;
if (grown[indx]) {
borderTiles[indx] = !these_tiles[indx];
disparityTask[ty][tx] = prev_disparity[indx];
tile_op[ty][tx] = op;
} else {
disparityTask[ty][tx] = 0.0;
tile_op[ty][tx] = 0;
borderTiles[indx] = false;
}
}
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);
// }
//clt_parameters.transform_size;
DisparityProcessor dp = new DisparityProcessor(this, clt_parameters.transform_size * geometryCorrection.getScaleDzDx());
/*
boolean [] grown = these_tiles.clone();
growTiles(
// 1, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
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];
scan_prev.fixNaNDisparity(
grown, // border, // boolean [] select, // which tiles to correct (null - all)
scan_prev.getDisparity(), // double [] disparity,
scan_prev.getStrength()); // double [] strength)
int [] neighbors = dp.getNeighbors( // creates neighbors mask from bitmask
these_tiles, // grown, // these_tiles, // boolean [] selected,
tilesX);
// int [] neighbors_orig = neighbors.clone();
double [] dbg_neib = dp.dbgShowNeighbors(
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);
double [] measured_disparity = dp.dbgRescaleToPixels(
this_disparity,
clt_parameters.transform_size); // int tile_size)
// 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][];
smooth_disparities[0] = dp.dbgRescaleToPixels(
new_disparity,
clt_parameters.transform_size);
boolean [] too_far = new boolean [this_strength.length];
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)
double breakScale = 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)
0, // mode, // 0: 3-rd derivative, 1: - third * first (compare positive threshold only), 2: second by abs(first) (compare positive threshold only)
neighbors, // final int [] neighbors, // UPDATED +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
these_tiles, // final boolean [] selected,
true, // final boolean extend_flat, // if the tile is on the hor/vert edge, assume same disparity on the other side
clt_parameters.tiBreakSame, // final double k_same,
clt_parameters.tiBreakTurn, // final double k_turn,
clt_parameters,
dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
}
if ((clt_parameters.tiBreakMode & 2) != 0) {
dp.breakDisparity( // break using derivatives
clt_parameters.tiBreak31 * breakScale, // clt_parameters.tiBreak, // final double break4, // clt_parameters.tiBreak/0 allow disconnecting from neighbors (fg/bg)
1, // mode, // 0: 3-rd derivative, 1: - third * first (compare positive threshold only), 2: second by abs(first) (compare positive threshold only)
neighbors, // final int [] neighbors, // UPDATED +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
these_tiles, // final boolean [] selected,
true, // final boolean extend_flat, // if the tile is on the hor/vert edge, assume same disparity on the other side
clt_parameters.tiBreakSame, // final double k_same,
clt_parameters.tiBreakTurn, // final double k_turn,
clt_parameters,
dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
}
if ((clt_parameters.tiBreakMode & 4) != 0) {
dp.breakDisparity( // break using derivatives
clt_parameters.tiBreak21 * breakScale, // clt_parameters.tiBreak, // final double break4, // clt_parameters.tiBreak/0 allow disconnecting from neighbors (fg/bg)
2, // mode, // 0: 3-rd derivative, 1: - third * first (compare positive threshold only), 2: second by abs(first) (compare positive threshold only)
neighbors, // final int [] neighbors, // UPDATED +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
these_tiles, // final boolean [] selected,
true, // final boolean extend_flat, // if the tile is on the hor/vert edge, assume same disparity on the other side
clt_parameters.tiBreakSame, // final double k_same,
clt_parameters.tiBreakTurn, // final double k_turn,
clt_parameters,
dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
}
if ((clt_parameters.tiBreakMode & 8) != 0) { // remove too far
boolean [] found = dp.findNearFar(
true, // boolean findFar,
clt_parameters.tiBreakFar, // double threshold, // select tiles with non-zero strength that are far/near
new_disparity, // current (approximated) disparity value
this_disparity, // measured disparity
this_strength, // final double [] strength, // masked by previously removed tiles as far/near
these_tiles); // final boolean [] selected);
if (found != null){
for (int i=0;i < too_far.length; i++){
too_far[i] |=found[i];
if (too_far[i]) this_strength[i] =0.0;
}
}
}
if ((clt_parameters.tiBreakMode & 16) != 0) { // remove too near
boolean [] found = dp.findNearFar(
false, // boolean findFar,
clt_parameters.tiBreakNear, // double threshold, // select tiles with non-zero strength that are far/near
new_disparity, // current (approximated) disparity value
this_disparity, // measured disparity
this_strength, // final double [] strength, // masked by previously removed tiles as far/near
these_tiles); // final boolean [] selected);
if (found != null){
for (int i=0;i < too_near.length; i++){
too_near[i] |=found[i];
if (too_near[i]) this_strength[i] =0.0;
}
}
}
if ((dbgDeriv != null) && (dbgDeriv[0] != null)) {
stresses[numCycle] = dp.dbgShowStress(
dbgDeriv, // double [][] stress,
clt_parameters.transform_size); // int tile_size)
} else {
stresses[numCycle] = null;
}
// Now heal some broken gaps back
double healOrtho = 0.0;
if (numCycle >= (clt_parameters.tiNumCycles -2)) {
healOrtho = clt_parameters.tiHealPreLast;
if (numCycle >= (clt_parameters.tiNumCycles -1)) {
healOrtho =clt_parameters.tiHealLast;
}
}
if (healOrtho > 0.0){
dp.reconnectDisparity( // connect disconnected tiles if they have close approximated disparity
healOrtho, // final double maxDiffOrto,
0, // healOrtho*1.5, // final double maxDiffDiagonal,
neighbors, // final int [] neighbors, // +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
these_tiles, // final boolean [] selected,
threadsMax, // maximal number of threads to launch
debugLevel);
}
if (numCycle >= (clt_parameters.tiNumCycles -2)) { // only heal during last 2 passes?
if (clt_parameters.tiHealSame > 0){
int numHealed = dp. healSame( // returns number of new ortho connections
neighbors,
clt_parameters.tiHealSame , // int maxlen,
// just to fill in diagonals
these_tiles, // final boolean [] selected,
threadsMax,
debugLevel);
if (debugLevel > -1){
System.out.println("Healed "+numHealed+" connections");
}
}
}
neibs_broken[numCycle] = dp.dbgShowNeighbors(
these_tiles, // grown, // these_tiles,
neighbors, // _orig, // int [] neighbors,
clt_parameters.transform_size, // int tile_size,
-1.0, // double bgnd,
1.0); // double fgnd)
// more smoothing
double disp_pull = clt_parameters.tiDispPull;
if (numCycle >= (clt_parameters.tiNumCycles -2)) {
disp_pull = 0.1 * clt_parameters.tiDispPull;
if (numCycle >= (clt_parameters.tiNumCycles -1)) {
disp_pull = 0.01 * clt_parameters.tiDispPull;
}
}
dp.smoothDisparity(
disp_pull, // 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,
threadsMax, // maximal number of threads to launch
debugLevel);
smooth_disparities[numCycle+1] = dp.dbgRescaleToPixels(
new_disparity,
clt_parameters.transform_size);
}
// Just calculate stress, do not actually break (after last smoothing)
dp.breakDisparity(
0.0, // final double break4, // clt_parameters.tiBreak/0 allow disconnecting from neighbors (fg/bg)
0, // clt_parameters.tiBreakMode, // mode, // 0: 3-rd derivative, 1: - third * first (compare positive threshold only), 2: second by abs(first) (compare positive threshold only)
neighbors, // final int [] neighbors, // UPDATED +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
new_disparity, // final double [] disparity, // current disparity value
these_tiles, // final boolean [] selected,
true, // final boolean extend_flat, // if the tile is on the hor/vert edge, assume same disparity on the other side
clt_parameters.tiBreakSame, // final double k_same,
clt_parameters.tiBreakTurn, // final double k_turn,
clt_parameters,
dbgDeriv, // final double [][] dbgDeriv, //double [2][len] or null;
threadsMax, // maximal number of threads to launch
debugLevel);
stresses[clt_parameters.tiNumCycles] = dp.dbgShowStress(
dbgDeriv, // double [][] stress,
clt_parameters.transform_size); // int tile_size)
// 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;
else if (too_far[i]) dbg_far_near[i]= -1.0;
else if (too_near[i]) dbg_far_near[i]= 1.0;
else dbg_far_near[i]= 0.0;
}
double [][] disp_diff = new double [3][this_disparity.length];
for (int i = 0; i< this_disparity.length; i++) {
if (this_strength[i] > 0.0) disp_diff[0][i] = this_disparity[i]-new_disparity[i];
else disp_diff[0][i] = Double.NaN;
if (too_far[i]) disp_diff[1][i] = this_disparity[i]-new_disparity[i];
else disp_diff[1][i] = Double.NaN;
if (too_near[i]) disp_diff[2][i] = this_disparity[i]-new_disparity[i];
else disp_diff[2][i] = Double.NaN;
}
if (clt_parameters.show_neighbors) {
int numImages = 2 + 3*clt_parameters.tiNumCycles+2+3 + 3;
String [] titles_all = new String[numImages];
double [][] dbg_img = new double[numImages][];
int indx = 0;
titles_all[indx] = "neib";
dbg_img[indx++]= dbg_neib;
for (int i = 0; i < neibs_broken.length; i++){
titles_all[indx] = "neib_"+i;
dbg_img[indx++]= neibs_broken[i];
}
for (int i = 0; i < stresses.length; i++){
titles_all[indx] = "stress_"+i;
dbg_img[indx++]= stresses[i];
}
titles_all[indx] = "disp_meas";
dbg_img[indx++]= measured_disparity;
for (int i = 0; i < smooth_disparities.length; i++){
titles_all[indx] = "disp_"+i;
dbg_img[indx++]= smooth_disparities[i];
}
titles_all[indx] = "far-/near+";
dbg_img[indx++] = dp.dbgRescaleToPixels(
dbg_far_near,
clt_parameters.transform_size);
// double [][] dbg_img = {dbg_neib, dbg_neib_broken, stress, stress1, measured_disparity, smooth_disparity,smooth_disparity1};
// sdfa_instance.showArrays(dbg_neib,tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,"neighbors");
titles_all[indx] = "strength_orig";
dbg_img[indx++] = dp.dbgRescaleToPixels(
true_strength,
clt_parameters.transform_size);
titles_all[indx] = "strength_mod";
dbg_img[indx++] = dp.dbgRescaleToPixels(
this_strength,
clt_parameters.transform_size);
titles_all[indx] = "diff_this";
dbg_img[indx++] = dp.dbgRescaleToPixels(
disp_diff[0],
clt_parameters.transform_size);
titles_all[indx] = "diff_far";
dbg_img[indx++] = dp.dbgRescaleToPixels(
disp_diff[1],
clt_parameters.transform_size);
titles_all[indx] = "diff_near";
dbg_img[indx++] = dp.dbgRescaleToPixels(
disp_diff[2],
clt_parameters.transform_size);
sdfa_instance.showArrays(dbg_img, tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,
true, "neighbors", titles_all);
}
//disp_diff
//************************************************
int [][] flaps = dp.createOverlapGeometry(
neighbors, // +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
these_tiles, // final boolean [] selected, // only inner?
border, // final boolean [] border,
threadsMax, // maximal number of threads to launch
debugLevel);
String [] titleFlaps = {"neib","N","NE","E","SE","S","SW","W","NW"};
if (clt_parameters.show_flaps_dirs){
double [][] dbg_flaps = dp.dbgShowOverlaps(
// boolean [] selected,
flaps, // int [][] flaps,
clt_parameters.transform_size, // int tile_size,
-1.0, // double bgnd,
1.0); // double fgnd)
double [] dbg_neibs = dp.dbgShowNeighbors(
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 [][] dbg_flaps_all = {dbg_neibs,dbg_flaps[0],dbg_flaps[1],dbg_flaps[2],dbg_flaps[3],dbg_flaps[4],dbg_flaps[5],dbg_flaps[6],dbg_flaps[7]};
sdfa_instance.showArrays(dbg_flaps_all, tilesX*clt_parameters.transform_size, tilesY*clt_parameters.transform_size,
true, "flaps-dirs", titleFlaps);
}
int [][][] clustersNO= dp.extractNonOlerlap(
true, // diag_en,
neighbors, // +1 - up (N), +2 - up-right - NE, ... +0x80 - NW
these_tiles, // final boolean [] selected, // only inner?
border, // border should be diagonal!
threadsMax, // maximal number of threads to launch
debugLevel);
if (clt_parameters.show_first_clusters){
int dbg_max_cluster_show = 50;
if (dbg_max_cluster_show > clustersNO.length) dbg_max_cluster_show = clustersNO.length;
double [][] dbg_clusters_show = new double [titleFlaps.length+dbg_max_cluster_show][neighbors.length];
for (int i = 0; i < neighbors.length; i++){
dbg_clusters_show[0][i] = neighbors[i];
for (int j = 0; j < 8; j++){
if (flaps[i] != null) dbg_clusters_show[1+j][i] = flaps[i][j];
}
}
// String [] titleFlaps = {"neib","N","NE","E","SE","S","SW","W","NW"};
String [] titleClusters = new String [titleFlaps.length+dbg_max_cluster_show];
// int indxClust = 0;
for (int i = 0; i < titleFlaps.length; i++){
titleClusters[i] = titleFlaps[i];
}
for (int i = 0; i < dbg_max_cluster_show; i++){
titleClusters[titleFlaps.length+i] = "C"+i;
}
for (int nClust = 0; nClust <dbg_max_cluster_show; nClust++){
for (int i = 0; i < clustersNO[nClust][0].length; i++){
dbg_clusters_show[nClust + 9][clustersNO[nClust][0][i]] += 32.0; // 1.0;
}
for (int i = 0; i < clustersNO[nClust][1].length; i++){
dbg_clusters_show[nClust + 9][clustersNO[nClust][1][i]] += 64.0; // 2.0;
}
for (int i = 0; i < clustersNO[nClust][2].length; i++){
dbg_clusters_show[nClust + 9][clustersNO[nClust][2][i]] += 128.0;// 4.0;
}
}
sdfa_instance.showArrays(dbg_clusters_show, tilesX, tilesY, true, "first "+dbg_max_cluster_show+" clusters",titleClusters);
}
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,
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("secondPassSetup(): created "+ numScans+ " FPGA passes.");
}
if (debugLevel > 0){
String [] titles = new String [clt_3d_passes.size()];
double [][] disparities = new double [titles.length][tilesX*tilesY];
for (int i = 0; i < titles.length; i++) {
titles[i] = i+"_scan";
double [][] disparityTiles = clt_3d_passes.get(i).disparity;
for (int ty = 0; ty < tilesY; ty++) for (int tx = 0; tx < tilesX; tx++){
disparities[i][ty*tilesX+tx] = disparityTiles[ty][tx];
}
}
sdfa_instance.showArrays(disparities, tilesX, tilesY, true, "disparities_scans",titles);
}
// return scan_next;
}
public int fixVerticalPoles( // return number of replaced cells
CLTPass3d scan, // scan data to use
boolean [] selection, // start with only from selections (if not null, continue regardless)
......
......@@ -31,8 +31,8 @@ public class TileSurface {
// public
// private int tileSize;
private int superTileSize;
// private int tilesX;
// private int tilesY;
private int imageTilesX;
private int imageTilesY;
private int stilesX;
private int stilesY;
private int [] st_dirs8;
......@@ -41,6 +41,25 @@ public class TileSurface {
private double [] window;
private int threadsMax = 100;
static int STAT_UNASSIGNED = 0; // index of number of unassigned tiles
static int STAT_ASSIGNED = 1; // index of number of assigned tiles
static int STAT_PROHIBITED = 2; // index of number of initially prohibited tiles
static int STAT_IMPOSSIBLE = 3; // index of number of impossible (like no surfaces at that location) tiles
static int STAT_NUM_ML = 4; // index of number of measurement layers used
static int STAT_LEN = 5; // number of stat entries
static int UNASSIGNED = 0; //tile marked as invalid
static int PROHOBITED = -1; //tile marked as invalid
static int IMPOSSIBLE = -2; // give up on this tile (as no surface for it)
static int NEW_ASSIGNED = 0; // succesfully assigned to a surface
static int NO_SURF = 1; // no surfaces for this tile cell
static int TOO_WEAK = 2; // tile strength is too low
static int TOO_STRONG = 3; // tile strength is too high ( for that disparity difference)
static int TOO_FAR = 4; // no surface candidates within the allowed disparity range
static int NOT_UNIQUE = 5; // multiple surfaces are within range
static int NUM_STATS = 6;
// private int nsTilesstSize = 0; // 8;
GeometryCorrection geometryCorrection = null;
public TileSurface(
......@@ -53,8 +72,8 @@ public class TileSurface {
// this.tileSize = tileSize;
this.superTileSize = superTileSize;
this.geometryCorrection =geometryCorrection;
// this.tilesX = tilesX;
// this.tilesY = tilesY;
this.imageTilesX = tilesX;
this.imageTilesY = tilesY;
this.window = getWindow(2*superTileSize);
this.threadsMax = threadsMax;
stilesX = (tilesX + superTileSize -1)/superTileSize;
......@@ -239,7 +258,7 @@ public class TileSurface {
int getSegment(int indx)
{
int s1 = size / 4;
int s2 = size /2;
// int s2 = size /2;
int s3 = 3 * size / 4;
int x = indx % size;
int y = indx / size;
......@@ -378,13 +397,9 @@ public class TileSurface {
int np,
TilePlanes.PlaneData [][] planes)
{
// if (planes[nsTile] == null){
// return -1; // empty supertile or supertile plane
// }
if (nsTile < 0) {
return -1;
}
// int tsn = ((nsTile < 0) || (planes[nsTile] == null)) ? 0 : planes[nsTile].length; // nsTile = -1 when mesh goes out of the image area
int tsn = (planes[nsTile] == null) ? 0 : planes[nsTile].length; // nsTile = -1 when mesh goes out of the image area
if (dir < 0) {
if (np >= tsn){
......@@ -465,7 +480,8 @@ public class TileSurface {
* TODO: replace misplaced description Calculate per-tile surface data (TileData) including disparity, strength, and 8 neighbors indices
* @param use_sel use plane selection (this.sel_mask) to select only some part of the plane
* @param divide_by_area divide weights by ellipsoid area
* @param scale_projection use plane ellipsoid projection for weight: 0 - do not use, > 0 linearly scale ellipsoid
* @param scale_projection use plane ellipsoid projection for weight: 0 - do not use, > 0 linearly scale ellipsoid
* @param fraction_uni add fraction of the total weight to each tile
* @param planes array of the per-supertile, per plane plane data (each level can be null)
* @param debugLevel debug level
* @param dbg_X debug supertile X coordinate
......@@ -476,6 +492,7 @@ public class TileSurface {
final boolean use_sel,
final boolean divide_by_area,
final double scale_projection,
final double fraction_uni,
final TilePlanes.PlaneData [][] planes,
final int debugLevel,
final int dbg_X,
......@@ -502,9 +519,10 @@ public class TileSurface {
disp_strength[np] = planes[nsTile][np].getDoublePlaneDisparityStrength(
getWindow(), // double [] window,
-1, // int dir (-1 - center, 0- N, 1 - NE, .. 7 - NW
use_sel, // boolean use_sel,
false, // use_sel, // boolean use_sel, apply selection to the result
divide_by_area, //boolean divide_by_area,
scale_projection, // double scale_projection,
fraction_uni, // double fraction_uni,
debugLevel-1); // int debugLevel)
// multiply disparities by strengths to calculate weighted averages
for (int i = 0; i < disp_strength[np][1].length; i++){
......@@ -520,9 +538,10 @@ public class TileSurface {
double [][] ds = planes[nsTile1][sNeib].getDoublePlaneDisparityStrength(
getWindow(), // double [] window,
dir, // int dir (-1 - center, 0- N, 1 - NE, .. 7 - NW
use_sel, // boolean use_sel,
false, // use_sel, // boolean use_sel, apply selection to the result
divide_by_area, //boolean divide_by_area,
scale_projection, // double scale_projection,
fraction_uni, // double fraction_uni,
debugLevel-1); // int debugLevel)
for (int i = 0; i < disp_strength[np][1].length; i++){
if (ds[1][i] > 0.0){
......@@ -539,9 +558,47 @@ public class TileSurface {
disp_strength[np][0][i] /= disp_strength[np][1][i];
}
}
if (use_sel){ // zero out selection after averaging, apply to this tile
boolean [] sel = planes[nsTile][np].getSelMask();
if (sel != null){
for (int i = 0; i < disp_strength[np][1].length; i++){
if (!sel[i]) disp_strength[np][1][i] = 0.0;
}
}
}
if ((debugLevel > -1) && (dl>0)){
String str_neib = "fuseSupertilePlanes_"+nsTile+":"+np;
for (int dir = 0; dir < 8; dir++){
str_neib += " " + planes[nsTile][np].getNeibBest(dir);
}
System.out.println(str_neib);
}
}
}
fused_data[nsTile] = disp_strength;
if ((debugLevel > -1) && (dl>0)){
String[] titles = new String [3 * disp_strength.length];
double [][] dbg_img = new double [titles.length][];
for (int i = 0; i < disp_strength.length; i++) {
titles [i + 0 * disp_strength.length] = "disp_" + i;
titles [i + 1 * disp_strength.length] = "mdisp_" + i;
titles [i + 2 * disp_strength.length] = "str_" + i;
if (disp_strength[i] != null) {
dbg_img[i + 0 * disp_strength.length] = disp_strength[i][0];
dbg_img[i + 2 * disp_strength.length] = disp_strength[i][1];
dbg_img[i + 1 * disp_strength.length] = disp_strength[i][0].clone();
for (int j = 0; j < disp_strength[i][0].length; j++){
if (disp_strength[i][1][j] == 0.0){
dbg_img[i + 1 * disp_strength.length][j] = Double.NaN;
}
}
}
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(dbg_img, 2 * superTileSize, 2 * superTileSize, true, "surf_ds_"+nsTile, titles);
}
}
}
}
......@@ -1344,13 +1401,19 @@ public class TileSurface {
{
int num = 0;
for (int i = 0; i < tileData.length; i++){
if (tileData[i].length > num ){
if ((tileData[i] != null) && (tileData[i].length > num )){
num = tileData[i].length;
}
}
return num;
}
public int [] getTilesWH()
{
int [] wh = {stilesX*superTileSize, stilesY*superTileSize};
return wh;
}
public double [][][] getTileDisparityStrengths (
final TileData [][] tileData,
final boolean useNaN)
......@@ -1387,7 +1450,6 @@ public class TileSurface {
ImageDtt.startAndJoin(threads);
return disp_strength;
}
public int [][][] getTileConnections (
final TileData [][] tileData)
{
......@@ -1419,11 +1481,109 @@ public class TileSurface {
ImageDtt.startAndJoin(threads);
return connections;
}
public int [][] getTileGenerator (
final TileData [][] tileData)
{
final int nStiles = stilesX * stilesY;
final int nTiles = nStiles * superTileSize * superTileSize;
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final int numLayers = getTileLayersNumber(tileData);
final int [][] generators = new int [numLayers][tileData.length];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
if (tileData[nTile] != null) {
for (int nl = 0; nl < tileData[nTile].length; nl++) if (tileData[nTile][nl] != null) {
for (int indx = 0 ; indx < tileData.length; indx++){
generators[nl][nTile] = tileData[nTile][nl].getDbgNsTile();
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return generators;
}
public int [] getNumSurfaces (
final TileData [][] tileData)
{
final int nStiles = stilesX * stilesY;
final int nTiles = nStiles * superTileSize * superTileSize;
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final int [] surfaces = new int [tileData.length];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
if (tileData[nTile] != null) {
for (int nl = 0; nl < tileData[nTile].length; nl++) if (tileData[nTile][nl] != null) {
surfaces[nTile] ++;
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return surfaces;
}
public void showSurfaceDS (
TileData [][] tileData,
String title)
{
int [] wh = getTilesWH();
double [][][] tds = getTileDisparityStrengths (
tileData,
false); // useNaN);
double [][][] tds_nan = getTileDisparityStrengths (
tileData,
true); // useNaN);
int [][] generators = getTileGenerator(tileData);
int [] surfaces = getNumSurfaces (tileData);
String [] titles = new String [5 * tds.length + 1];
double [][] img_data = new double [titles.length][];
for (int i = 0; i <tds.length; i++){
titles[i + 0 * tds.length] = "disp_"+i;
titles[i + 1 * tds.length] = "str_"+i;
titles[i + 2 * tds.length] = "mdisp_"+i;
titles[i + 3 * tds.length] = "mstr_"+i;
titles[i + 4 * tds.length] = "gen_"+i;
img_data[i + 0 * tds.length] = tds[i][0];
img_data[i + 1 * tds.length] = tds[i][1];
img_data[i + 2 * tds.length] = tds_nan[i][0];
img_data[i + 3 * tds.length] = tds_nan[i][1];
img_data[i + 4 * tds.length] = new double [generators[i].length];
for (int j = 0; j < generators[i].length; j++){
img_data[i + 4 * tds.length][j] = 0.01*generators[i][j];
}
}
titles[5 * tds.length] = "layers";
img_data[5 * tds.length] = new double [surfaces.length];
for (int j = 0; j < surfaces.length; j++){
img_data[5 * tds.length][j] =surfaces[j];
}
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays();
sdfa_instance.showArrays(img_data, wh[0], wh[1], true, title, titles);
}
/**
* Calculate per-tile surface data (TileData) including disparity, strength, and 8 neighbors indices
* @param use_sel use plane selection (this.sel_mask) to select only some part of the plane
* @param divide_by_area divide weights by ellipsoid area
* @param scale_projection use plane ellipsoid projection for weight: 0 - do not use, > 0 linearly scale ellipsoid
* @param scale_projection use plane ellipsoid projection for weight: 0 - do not use, > 0 linearly
* scale ellipsoid (enlarge)
* @param fraction_uni add fraction of the total weight to each tile
* @param planes array of the per-supertile, per plane plane data (each level can be null)
* @param debugLevel debug level
* @param dbg_X debug supertile X coordinate
......@@ -1434,6 +1594,7 @@ public class TileSurface {
final boolean use_sel,
final boolean divide_by_area,
final double scale_projection,
final double fraction_uni,
final TilePlanes.PlaneData [][] planes,
final int debugLevel,
final int dbg_X,
......@@ -1444,6 +1605,7 @@ public class TileSurface {
use_sel, // final boolean use_sel,
divide_by_area, // final boolean divide_by_area,
scale_projection, // final double scale_projection,
fraction_uni, // final double fraction_uni,
planes, // final TilePlanes.PlaneData [][] planes,
debugLevel, // final int debugLevel,
dbg_X, // final int dbg_X,
......@@ -1480,20 +1642,386 @@ public class TileSurface {
debugLevel, // final int debugLevel,
dbg_X, // final int dbg_X,
dbg_Y); // final int dbg_Y);
/*
System.out.println("checkShellsConnections() - 2");
checkShellsConnections (
tileData, // final TileData [][] tileData_src,
debugLevel, // final int debugLevel,
dbg_X, // final int dbg_X,
dbg_Y); // final int dbg_Y);
*/
tileData = compactSortShells (
tileData, // final TileData [][] tileData_src,
debugLevel, // final int debugLevel,
dbg_X, // final int dbg_X,
dbg_Y); // final int dbg_Y);
showSurfaceDS (tileData, "tileData");
return tileData;
}
//getNtileDir
public int [] getTilesAssignStats(
final int [][] tileLayers)
{
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final int numThreads = threads.length;
int [] stats = new int [STAT_LEN];
final int [][] stats_all = new int [numThreads][STAT_LEN];
final AtomicInteger ai_numThread = new AtomicInteger(0);
final AtomicInteger ai = new AtomicInteger(0);
for (int ml = 0; ml < tileLayers.length; ml++) if (tileLayers[ml] != null){
final int fml = ml;
ai_numThread.set(0);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int numThread = ai_numThread.getAndIncrement(); // unique number of thread to write to rslt_diffs[numThread]
for (int nTile = ai.getAndIncrement(); nTile < tileLayers[fml].length; nTile = ai.getAndIncrement()) {
if (tileLayers[fml][nTile] > 0){ // index + 1
stats_all[numThread][STAT_ASSIGNED] ++;
} else if (tileLayers[fml][nTile] == UNASSIGNED) {
stats_all[numThread][STAT_UNASSIGNED] ++;
} else if (tileLayers[fml][nTile] == PROHOBITED) {
stats_all[numThread][STAT_PROHIBITED] ++;
} else if (tileLayers[fml][nTile] == IMPOSSIBLE) {
stats_all[numThread][STAT_IMPOSSIBLE] ++;
} else {
System.out.println("Bug in getTilesAssignStats(): tileLayers["+fml+"]["+nTile+"]="+tileLayers[fml][nTile]);
stats_all[numThread][0] ++; // prohibited
}
}
}
};
}
ImageDtt.startAndJoin(threads);
stats[STAT_NUM_ML]++; // number of non-null measurement layers
}
for (int nt = 0; nt < numThreads; nt ++){
for (int i = 0 ; i < stats.length; i++ ){
stats[i] += stats_all[nt][i];
}
}
return stats;
}
public double getNormDispFromSurface(
double disp_tile,
double disp_surf,
double disp_norm)
{
double disp_avg = 0.5 * (disp_tile + disp_surf);
if (disp_avg <= disp_norm){
return disp_tile - disp_surf;
} else {
return (disp_tile - disp_surf) * disp_norm / disp_avg;
}
}
/**
* Convert from image tile index to surface tile index (surface tiles are all full superTileSize
* TODO: update/remove if surface grid will be trimmed to fit image
* Currently there are 324 tiles horizontally in the image and 328 in the surfaces
* @param nTile image tile index in scan order
* @return surface tile index in scan order
*/
public int getSurfaceTileIndex(
int nTile)
{
// calculate index in tileData (has different dimensions - TODO: trim?
return stilesX * superTileSize * (nTile / imageTilesX) + (nTile % imageTilesX);
}
/**
* Assign tiles to a certain disparity surface if there is only one surface candidate
* @param maxDiff maximal (normalized) disparity difference
* @param minDiffOther minimal disparity difference to closest 2-nd place candidate
* @param minStrength minimal processed (floor subtracted) correlation strength of the candidate
* @param maxStrength maximal processed (floor subtracted) correlation strength of the candidate
* @param moveDirs +1 - allow moving tile closer to the camera (increase disparity, +2 - allow moving away
* @param dispNorm disparity normalization - disparity difference with average above it will be scaled down
* @param tileLayers measured tiles assignment (will be modified): -1 - prohibited, 0 - unassigned,
* >0 - number of surface where this tile is assigned plus 1.
* @param tileData per-tile, per layer array of TileData objects specifying surfaces to snap to
* @param dispStrength per measurement layer, combined disparity and strength array ([num_ml [2][])
* @param debugLevel debug level
* @param dbg_X debug tile X coordinate
* @param dbg_Y debug tile Y coordinate
* @return
*/
public int [] assignSingleCandidate(
final double maxDiff,
final double minDiffOther,
final double minStrength,
final double maxStrength,
final int moveDirs, // 1 increase disparity, 2 - decrease disparity, 3 - both directions
final double dispNorm, // disparity normalize (proportionally scale down disparity difference if above
final int [][] tileLayers,
final TileData [][] tileData,
final double [][][] dispStrength,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
int [] stats_new = new int [NUM_STATS];
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final int numThreads = threads.length;
final int [][] stats_all = new int [numThreads][stats_new.length];
final AtomicInteger ai_numThread = new AtomicInteger(0);
final AtomicInteger ai = new AtomicInteger(0);
final boolean en_lower = (moveDirs & 1) != 0;
final boolean en_higher = (moveDirs & 2) != 0;
for (int ml = 0; ml < tileLayers.length; ml++) if (tileLayers[ml] != null){
final int fml = ml;
ai_numThread.set(0);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int numThread = ai_numThread.getAndIncrement(); // unique number of thread to write to rslt_diffs[numThread]
for (int nTile = ai.getAndIncrement(); nTile < tileLayers[fml].length; nTile = ai.getAndIncrement()) {
if (tileLayers[fml][nTile] == 0){ // unassigned only
if (dispStrength[fml][1][nTile] < minStrength){
stats_all[numThread][TOO_WEAK] ++;
} else if (dispStrength[fml][1][nTile] > maxStrength){
stats_all[numThread][TOO_STRONG] ++;
} else {
// calculate index in tileData (has different dimensions - TODO: trim?
int nSurfTile = getSurfaceTileIndex(nTile);
if ((tileData[nSurfTile] == null) || (tileData[nSurfTile].length == 0)){
stats_all[numThread][NO_SURF] ++;
tileLayers[fml][nTile] = IMPOSSIBLE;
} else {
// double [] surf_disp_diff = new double [tileData[nSurfTile].length];
int num_fit = 0;
int num_fit_other = 0;
int fit = -1;
for (int ns = 0; ns < tileData[nSurfTile].length; ns++){
double surf_disp_diff = getNormDispFromSurface (
dispStrength[fml][0][nTile], // double disp_tile,
tileData[nSurfTile][ns].getDisparity(), // double disp_surf,
dispNorm); //double disp_norm)
if (((surf_disp_diff >= 0) && en_higher) || ((surf_disp_diff <= 0) && en_lower)){
if (Math.abs(surf_disp_diff) <= maxDiff){
fit = ns; // no rating for fit "quality" here
num_fit ++;
}
if (Math.abs(surf_disp_diff) <= minDiffOther){
num_fit_other ++;
}
}
}
if (num_fit < 1){
stats_all[numThread][TOO_FAR] ++;
} else if ((num_fit == 1) && (num_fit_other <= 1)){ // assign
tileLayers[fml][nTile] = fit + 1;
stats_all[numThread][NEW_ASSIGNED] ++;
} else {
stats_all[numThread][NOT_UNIQUE] ++;
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
for (int nt = 0; nt < numThreads; nt ++){
for (int i = 0 ; i < stats_new.length; i++ ){
stats_new[i] += stats_all[nt][i];
}
}
return stats_new;
}
/**
* Assign tiles to a certain disparity surface if there is only one surface candidate
* @param maxDiff maximal (normalized) disparity difference
* @param minDiffOther minimal disparity difference to closest 2-nd place candidate
* @param minStrength minimal processed (floor subtracted) correlation strength of the candidate
* @param maxStrength maximal processed (floor subtracted) correlation strength of the candidate
* @param moveDirs +1 - allow moving tile closer to the camera (increase disparity, +2 - allow moving away
* @param enMulti
* @param surfStrPow
* @param sigma
* @param nSigma
* @param minAdvantage
* @param dispNorm disparity normalization - disparity difference with average above it will be scaled down
* @param tileLayers measured tiles assignment (will be modified): -1 - prohibited, 0 - unassigned,
* >0 - number of surface where this tile is assigned plus 1.
* @param tileData per-tile, per layer array of TileData objects specifying surfaces to snap to
* @param dispStrength per measurement layer, combined disparity and strength array ([num_ml [2][])
* @param debugLevel debug level
* @param dbg_X debug tile X coordinate
* @param dbg_Y debug tile Y coordinate
* @return
*/
public int [] assignSingleCandidate(
final double maxDiff,
final double minDiffOther, // should be >= maxDiff
final double minStrength,
final double maxStrength,
final int moveDirs, // 1 increase disparity, 2 - decrease disparity, 3 - both directions
final boolean enMulti,
final double surfStrPow, // surface string power
final double sigma,
final double nSigma,
final double minAdvantage,
final double dispNorm, // disparity normalize (proportionally scale down disparity difference if above
final int [][] tileLayers,
final TileData [][] tileData,
final double [][][] dispStrength,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
final int [][] tileLayers_src = tileLayers.clone();
for (int i = 0; i < tileLayers_src.length; i++){
if (tileLayers_src[i] != null){
tileLayers_src[i] = tileLayers[i].clone();
}
}
int [] stats_new = new int [NUM_STATS];
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final int numThreads = threads.length;
final int [][] stats_all = new int [numThreads][stats_new.length];
final AtomicInteger ai_numThread = new AtomicInteger(0);
final AtomicInteger ai = new AtomicInteger(0);
final boolean en_lower = (moveDirs & 1) != 0;
final boolean en_higher = (moveDirs & 2) != 0;
for (int ml = 0; ml < tileLayers.length; ml++) if (tileLayers[ml] != null){
final int fml = ml;
ai_numThread.set(0);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int numThread = ai_numThread.getAndIncrement(); // unique number of thread to write to rslt_diffs[numThread]
for (int nTile = ai.getAndIncrement(); nTile < tileLayers_src[fml].length; nTile = ai.getAndIncrement()) {
if (tileLayers_src[fml][nTile] == 0){ // unassigned only
if (dispStrength[fml][1][nTile] < minStrength){
stats_all[numThread][TOO_WEAK] ++;
} else if (dispStrength[fml][1][nTile] > maxStrength){
stats_all[numThread][TOO_STRONG] ++;
} else {
// calculate index in tileData (has different dimensions - TODO: trim?
int nSurfTile = getSurfaceTileIndex(nTile);
if ((tileData[nSurfTile] == null) || (tileData[nSurfTile].length == 0)){
stats_all[numThread][NO_SURF] ++;
tileLayers[fml][nTile] = IMPOSSIBLE;
} else {
// double [] surf_disp_diff = new double [tileData[nSurfTile].length];
int num_fit = 0;
int num_fit_other = 0;
int fit = -1;
for (int ns = 0; ns < tileData[nSurfTile].length; ns++){
double surf_disp_diff = getNormDispFromSurface (
dispStrength[fml][0][nTile], // double disp_tile,
tileData[nSurfTile][ns].getDisparity(), // double disp_surf,
dispNorm); //double disp_norm)
if (((surf_disp_diff >= 0) && en_higher) || ((surf_disp_diff <= 0) && en_lower)){
if (Math.abs(surf_disp_diff) <= maxDiff){
fit = ns; // no rating for fit "quality" here
num_fit ++;
}
if (Math.abs(surf_disp_diff) <= minDiffOther){
num_fit_other ++;
}
}
}
if (num_fit < 1){
stats_all[numThread][TOO_FAR] ++;
} else if ((num_fit == 1) && (num_fit_other <= 1)){ // assign
tileLayers[fml][nTile] = fit + 1;
stats_all[numThread][NEW_ASSIGNED] ++;
} else if (!enMulti) {
stats_all[numThread][NOT_UNIQUE] ++;
} else { // multi, enabled
int [] candidates = new int [num_fit_other];
boolean [] close_enough = new boolean [num_fit_other];
num_fit_other = 0;
for (int ns = 0; ns < tileData[nSurfTile].length; ns++){
double surf_disp_diff = getNormDispFromSurface (
dispStrength[fml][0][nTile], // double disp_tile,
tileData[nSurfTile][ns].getDisparity(), // double disp_surf,
dispNorm); //double disp_norm)
if (((surf_disp_diff >= 0) && en_higher) || ((surf_disp_diff <= 0) && en_lower)){
if (Math.abs(surf_disp_diff) <= minDiffOther){
close_enough[num_fit_other] = (Math.abs(surf_disp_diff) <= maxDiff);
candidates[num_fit_other++] = ns;
}
}
}
double [][] advantages = new double [num_fit_other][num_fit_other];
// now calculate advantage of each one surface (close_enough) to each other (as a ratio)
// and then see if it is above minAdvantage
for (int ns1 = 0; ns1 < num_fit_other; ns1++){
for (int ns2 = ns1 + 1; ns2 < num_fit_other; ns2++){
if (close_enough[ns1] || close_enough[ns2]){
}
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
for (int nt = 0; nt < numThreads; nt ++){
for (int i = 0 ; i < stats_new.length; i++ ){
stats_new[i] += stats_all[nt][i];
}
}
return stats_new;
}
public int [][] sortTilesToSurfaces(
final double [][][] dispStrength,
final boolean [][] tileSel,
final TileData [][] tileData_src,
// parameters
final EyesisCorrectionParameters.CLTParameters clt_parameters,
final int debugLevel,
final int dbg_X,
final int dbg_Y)
{
int [][] tileLayers = new int [tileSel.length][];
for (int ml = 0; ml < tileSel.length; ml++){
if (tileSel[ml] != null){
tileLayers[ml] = new int [tileSel[ml].length];
for (int i = 0; i < tileSel[ml].length; i++){
tileLayers[ml][i] = tileSel[ml][i] ? 0: -1; // 0 - unassigned, -1 - prohibited
}
}
}
if (debugLevel >= -1) {
int []stats = getTilesAssignStats(tileLayers);
System.out.println("sortTilesToSurfaces(): using "+stats[STAT_NUM_ML] +" measurement layers"+
", number of assigned tiles: "+stats[STAT_ASSIGNED]+
", number of unassigned tiles: "+stats[STAT_UNASSIGNED]+
", number of prohibited tiles: "+stats[STAT_PROHIBITED]+
", number of impossible tiles: "+stats[STAT_IMPOSSIBLE]);
}
return tileLayers;
}
//getNtileDir
/*
* clt_parameters.plDispNorm, // = 2.0; // Normalize disparities to the average if above
double [][][] dispStrength = st.getDisparityStrengths(
clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
boolean [][] tileSel = st.getMeasurementSelections(
clt_parameters.stMeasSel); // int stMeasSel) // = 1; // Select measurements for supertiles : +1 - combo, +2 - quad +4 - hor +8 - vert)
*/
}
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