Commit b3afa1ab authored by Andrey Filippov's avatar Andrey Filippov

Working on fronto objects at long distances in the model

parent c2de0cdf
......@@ -276,7 +276,7 @@ public class BiCamDSI {
/**
* Filter selection by expending, then shrinking (fills small gaps) shrinking (combined with
* Filter selection by expanding, then shrinking (fills small gaps) shrinking (combined with
* previous step) and expanding again (removes small clusters)
* @param pre_expand number of steps for initial expand (odd last is - only hor/vert, even - last step includes diagonals)
* @param shrink number of shrink steps normally equals to pre_expand+post_expand
......
......@@ -20,6 +20,9 @@
** -----------------------------------------------------------------------------**
**
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicInteger;
public class BiScan {
......@@ -155,6 +158,59 @@ public class BiScan {
return ds;
}
class DSIndex{
double disparity;
double strength;
int scan_index;
DSIndex (
double disparity,
double strength,
int scan_index)
{
this.disparity = disparity;
this.strength = strength;
this.scan_index = scan_index;
}
}
ArrayList<DSIndex> getTileDSList(
int nTile,
final boolean only_strong,
final boolean only_trusted,
final boolean only_enabled)
{
ArrayList<DSIndex> ds_list = new ArrayList<DSIndex>();
for (int indx = list_index; indx >= 0; indx--) { // include the latest measurement
BiScan scan = biCamDSI.getBiScan(indx);
if (only_enabled && scan.disabled_measurement[nTile]) { // || (scan.src_index[nTile] != indx)){ // skip all but enabled
continue;
}
if (only_strong && !scan.strong_trusted[nTile]) {
continue;
}
if (only_trusted && !scan.trusted[nTile]) {
continue;
}
if ((scan.strength_measured[nTile] > 0.0) && !Double.isNaN(scan.disparity_measured[nTile])) {
ds_list.add(new DSIndex(scan.disparity_measured[nTile],scan.strength_measured[nTile],indx));
}
}
Collections.sort(ds_list, new Comparator<DSIndex>() {
@Override
public int compare(DSIndex lhs, DSIndex rhs) {
// -1 - less than, 1 - greater than, 0 - equal, all inverted for descending disparity
return lhs.disparity > rhs.disparity ? -1 : (lhs.disparity < rhs.disparity ) ? 1 : 0;
}
});
return ds_list;
}
// trusted should be set, copied and replaced as needed
public double [][] getFilteredDisparityStrength( // FIXME
final boolean [] area_of_interest,
......@@ -425,6 +481,127 @@ public class BiScan {
return num_changes.get();
}
/**
* Prefer thin FG (like thin poles) over textured BG (at first not directional), just prefer "good enough" FG over even stronger BG
* @param str_good_enough minimal strength for the FG tiles and neighbors
* @param min_FGtoBG minimal FG to BG disparity difference
* @param disp_atolerance absolute disparity difference for qualifying neighbors (in master camera pixels)
* @param disp_rtolerance add to tolerance for each pixel of disparity
* @param min_neib minimal number of neighbors that promoted tiles should have
* @return number of promoted FG tiles
*/
public int copyStrongFGEnabled(
final double str_good_enough, // absolute strength floor for good enough
final double min_FGtoBG, // minimal disparity difference over
final double disp_atolerance, // = 0.1; // Maximal absolute disparity difference to qualifying neighbor
final double disp_rtolerance, // = 0.02; // Maximal relative (to absolute disparity) disparity difference to qualifying neighbor
final int min_neib) // minimal number of qualifying neighbors to promote FG tile
{
final TileNeibs tnImage = biCamDSI.tnImage;
final int num_tiles = biCamDSI.tnImage.getSizeX()*biCamDSI.tnImage.getSizeY();
final double [][] ds = getDisparityStrength( // used to comapre to see if re-arrangement is needed
false, // final boolean only_strong,
false, // final boolean only_trusted,
true) ; // final boolean only_enabled);
final Thread[] threads = ImageDtt.newThreadArray(biCamDSI.threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final int [] new_src = new int[num_tiles];
final AtomicInteger num_changes = new AtomicInteger(0); // number of tiles modified to FG
int dbg_x = 193;
int dbg_y = 162;
int debugLevel = -1;
final int dbg_tile = (debugLevel>-2)?(dbg_x + tnImage.sizeX*dbg_y):-1;
ai.set(0);
// find definitely trusted and conditionally trusted tiles
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < num_tiles; nTile = ai.getAndIncrement()) {
if (nTile == dbg_tile) {
System.out.println("copyStrongFGEnabled(): nTile="+nTile);
}
if (ds[1][nTile] < 0) { // no good d/s for this tile
continue;
}
// get list in descending disparity order
ArrayList<DSIndex> ds_list = getTileDSList(
nTile, // int nTile,
false, // final boolean only_strong,
false, // final boolean only_trusted,
true); // final boolean only_enabled)
if (ds_list.size() < 1) {
continue;
}
// find strongest tile closer than default disparity
for (int indx = 0; indx < ds_list.size(); indx++) {
DSIndex dsi = ds_list.get(indx);
if (dsi.disparity < (ds[0][nTile] + min_FGtoBG)){
break; // not sufficiently closer than default;
}
if (dsi.strength > str_good_enough){
double disp_tolerance = disp_atolerance + dsi.disparity * disp_rtolerance; // disparity tolerance
// see if it has strong enough neighbors with close disparity
int num_neib = 0;
for (int dir = 0; dir < 8; dir++) {
int nTile1 = tnImage.getNeibIndex(nTile, dir);
if (nTile1 > 0) {
ArrayList<DSIndex> ds_neib = getTileDSList(
nTile1, // int nTile,
false, // final boolean only_strong,
false, // final boolean only_trusted,
true); // final boolean only_enabled)
for (DSIndex dsi_neib: ds_neib) {
if ((dsi_neib.strength > str_good_enough) &&
(Math.abs(dsi_neib.disparity - dsi.disparity ) <= disp_tolerance)) {
num_neib++;
break;
}
}
}
}
if (num_neib > 0) {
new_src[nTile] = dsi.scan_index + 1;
num_changes.getAndIncrement();
break; // for (int indx = 0; indx < ds_list.size(); indx++)
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (num_changes.get() > 0) {
ai.set(0);
// find definitely trusted and conditionally trusted tiles
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < num_tiles; nTile = ai.getAndIncrement()) {
if (nTile == dbg_tile) {
System.out.println("copyStrongFGEnabled() 2 : nTile="+nTile);
}
if (new_src[nTile] > 0){
int best_indx = new_src[nTile]-1;
src_index[nTile] = best_indx;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
// will need trusted* recalculated
return num_changes.get();
}
/**
* Copy data (if the current was not measured) from one of the previous scans - strongest that is not disabled. If last_priority is true
* the latest not disabled scan will be used, even if it is not the strongest
......@@ -970,6 +1147,11 @@ public class BiScan {
final int dbg_y,
final int debugLevel
) {
// int dbg_x = 193;
// int dbg_y = 162;
// int debugLevel = -1;
// final int dbg_tile = (debugLevel>-2)?(dbg_x + tnImage.sizeX*dbg_y):-1;
final TileNeibs tnImage = biCamDSI.tnImage;
final double [][] ds = getDisparityStrength( // FIXME
false, // final boolean only_strong,
......@@ -993,8 +1175,13 @@ public class BiScan {
@Override
public void run() {
for (int nTile = ai.getAndIncrement(); nTile < num_tiles; nTile = ai.getAndIncrement()) if (discard_strong || !trusted_sw[nTile]){
if (nTile == 52681) {
System.out.println("suggestNewScan(), nTIle="+nTile+", dxy={"+dxy[0]+","+dxy[1]+"}");
}
int nTile1 = tnImage.getNeibIndex(nTile, dxy[0], dxy[1]);
if ((nTile1 >= 0) && trusted_weak[nTile1]) { // weak trusted OK, maybe even any measured
// if ((nTile1 >= 0) && trusted_weak[nTile1]) { // weak trusted OK, maybe even any measured
if ((nTile1 >= 0) && (ds[0][nTile1] > 0)) { // weak trusted OK, maybe even any measured
double new_disp = ds[0][nTile1];
if (Math.abs(new_disp - ds[0][nTile]) < new_diff) { // suggested is too close to already measured
continue; // already measured for this tile
......@@ -1331,8 +1518,8 @@ public class BiScan {
if ((max_disp <= d_lim) && ((w < max_disp_w) || (w < min_strength))) {
disableTile(nTile);
ai_trimmed.getAndIncrement();
if (debugLevel > -4) {
System.out.println("trimWeakLoneFG: removing tile "+nTile+" ("+(nTile%tnImage.sizeX)+":"+(nTile/tnImage.sizeX));
if (debugLevel > -1) {
System.out.println("trimWeakLoneFG: removing tile "+nTile+" ("+(nTile%tnImage.sizeX)+":"+(nTile/tnImage.sizeX)+")");
}
}
}
......
......@@ -2858,7 +2858,9 @@ public class EyesisCorrectionParameters {
public boolean plPreferDisparity = false;// Always start with disparity-most axis (false - lowest eigenvalue)
public double plDispNorm = 5.0; // Normalize disparities to the average if above (now only for eigenvalue comparison)
public double plFrontoTol = 0.0; // for compatibility with old //0.1; // Fronto tolerance (pix) - treat almost fronto as fronto (constant disparity). <= 0 - disable
public double plFrontoRms = 0.05; // Target rms for the fronto planes - same as sqrt(plMaxEigen) for other planes
public double plFrontoOffs = 0.2; // increasing weight of the near tiles by using difference between the reduced average as weight. <= 0 - disable
public double plBlurBinVert = 1.2; // Blur disparity histograms for constant disparity clusters by this sigma (in bins)
public double plBlurBinHor = 0.8; // Blur disparity histograms for horizontal clusters by this sigma (in bins)
public double plMaxDiffVert = 0.4; // Maximal normalized disparity difference when initially assigning to vertical plane
......@@ -2868,7 +2870,7 @@ public class EyesisCorrectionParameters {
public int plMinPoints = 5; // Minimal number of points for plane detection
public double plTargetEigen = 0.02; // Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below
public double plFractOutliers = 0.3; // Maximal fraction of outliers to remove
public int plMaxOutliers = 20; // Maximal number of outliers to remove
public int plMaxOutliers = 200; // Maximal number of outliers to remove
public double plMinStrength = 0.01; // Minimal total strength of a plane
public double plMaxEigen = 0.06; // Maximal eigenvalue of a plane
public double plEigenFloor = 0.005;// Add to eigenvalues of each participating plane and result to validate connections
......@@ -3522,6 +3524,9 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"plPreferDisparity",this.plPreferDisparity+"");
properties.setProperty(prefix+"plDispNorm", this.plDispNorm +"");
properties.setProperty(prefix+"plFrontoTol", this.plFrontoTol +"");
properties.setProperty(prefix+"plFrontoRms", this.plFrontoRms +"");
properties.setProperty(prefix+"plFrontoOffs", this.plFrontoOffs +"");
properties.setProperty(prefix+"plBlurBinVert", this.plBlurBinVert +"");
properties.setProperty(prefix+"plBlurBinHor", this.plBlurBinHor +"");
......@@ -4165,6 +4170,9 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"plPreferDisparity")!=null) this.plPreferDisparity=Boolean.parseBoolean(properties.getProperty(prefix+"plPreferDisparity"));
if (properties.getProperty(prefix+"plDispNorm")!=null) this.plDispNorm=Double.parseDouble(properties.getProperty(prefix+"plDispNorm"));
if (properties.getProperty(prefix+"plFrontoTol")!=null) this.plFrontoTol=Double.parseDouble(properties.getProperty(prefix+"plFrontoTol"));
if (properties.getProperty(prefix+"plFrontoRms")!=null) this.plFrontoRms=Double.parseDouble(properties.getProperty(prefix+"plFrontoRms"));
if (properties.getProperty(prefix+"plFrontoOffs")!=null) this.plFrontoOffs=Double.parseDouble(properties.getProperty(prefix+"plFrontoOffs"));
if (properties.getProperty(prefix+"plBlurBinVert")!=null) this.plBlurBinVert=Double.parseDouble(properties.getProperty(prefix+"plBlurBinVert"));
if (properties.getProperty(prefix+"plBlurBinHor")!=null) this.plBlurBinHor=Double.parseDouble(properties.getProperty(prefix+"plBlurBinHor"));
......@@ -4707,7 +4715,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Set new pole segment strength to max of horizontal correlation and this value", this.poles_min_strength, 3);
gd.addCheckbox ("Set disparity to that of the bottom of existing segment (false - use hor. disparity)",this.poles_force_disp);
gd.addNumericField("Maximal number of output meshes to generate", this.max_clusters, 0);
gd.addNumericField("Maximal number of output meshes to generate", this.max_clusters, 0);
gd.addCheckbox ("Remove all unneeded scans when generating x3d output to save memory", this.remove_scans);
gd.addCheckbox ("Generate x3d output", this.output_x3d);
gd.addCheckbox ("Generate Wavefront obj output", this.output_obj);
......@@ -4818,7 +4826,7 @@ public class EyesisCorrectionParameters {
"", "Allows to find plane when there are not enough tiles to process");
gd.addNumericField("Disparity switch between filtering modes", this.mlfp.min_tilt_disp, 4,6,
"pix","Objects that are closer (larger disparity) use tilted plane model, far objects use maximal amon neighbors disparity");
"pix","Objects that are closer (larger disparity) use tilted plane model, far objects use maximal among neighbors disparity");
gd.addNumericField("Mode transition range (between tilted and maximal disparity)", this.mlfp.transition, 4,6,
"pix","Disparity range to gradually switch between maximal and tilted modes");
gd.addNumericField("Far objects filtering mode (0 - off, 1,2 - power of disparity)", this. mlfp.far_mode, 0,3,
......@@ -4900,8 +4908,13 @@ public class EyesisCorrectionParameters {
gd.addTab ("Plane Det", "Planes detection");
gd.addMessage ("--- Planes detection ---");
gd.addCheckbox ("Always start with disparity-most axis (false - lowest eigenvalue)", this.plPreferDisparity);
gd.addNumericField("Normalize disparities to the average if above", this.plDispNorm, 6);
gd.addNumericField("Normalize disparities to the average if above", this.plDispNorm, 4,6, "pix");
gd.addNumericField("Fronto tolerance", this.plFrontoTol, 4,6,"pix",
"Fronto tolerance (pix) - treat almost fronto planes as fronto (constant disparity). If <= 0 - disable this feature");
gd.addNumericField("Fronto RMS", this.plFrontoRms, 4,6,"pix",
"Target half-thikness of the fronto planes. Similar to sqrt(plMaxEigen) for other planes");
gd.addNumericField("Fronto offset", this.plFrontoOffs, 4,6,"pix",
"Increasing weights of the near tiles by using difference between tile disparity and reduced by this value average as weight. If <= 0 - disable feature");
gd.addNumericField("Blur disparity histograms for constant disparity clusters by this sigma (in bins)", this.plBlurBinVert, 6);
gd.addNumericField("Blur disparity histograms for horizontal clusters by this sigma (in bins)", this.plBlurBinHor, 6);
gd.addNumericField("Maximal normalized disparity difference when initially assigning to vertical plane", this.plMaxDiffVert, 6);
......@@ -5556,6 +5569,9 @@ public class EyesisCorrectionParameters {
this.plPreferDisparity= gd.getNextBoolean();
this.plDispNorm= gd.getNextNumber();
this.plFrontoTol = gd.getNextNumber();
this.plFrontoRms = gd.getNextNumber();
this.plFrontoOffs = gd.getNextNumber();
this.plBlurBinVert= gd.getNextNumber();
this.plBlurBinHor= gd.getNextNumber();
......
This diff is collapsed.
......@@ -7190,6 +7190,7 @@ public class QuadCLT {
if (this.image_data == null){
return false;
}
double infinity_disparity = geometryCorrection.getDisparityFromZ(clt_parameters.infinityDistance);
X3dOutput x3dOutput = null;
WavefrontExport wfOutput = null;
if (clt_parameters.remove_scans){
......@@ -7202,7 +7203,8 @@ public class QuadCLT {
int next_pass = tp.clt_3d_passes.size(); //
tp.thirdPassSetupSurf( // prepare tile tasks for the second pass based on the previous one(s) // needs last scan
clt_parameters,
clt_parameters.bgnd_range, // double disparity_far,
//FIXME: make a special parameter?
infinity_disparity, //0.25 * 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
......@@ -7253,9 +7255,9 @@ public class QuadCLT {
// int num_bgnd = 0;
// for (int i = 0; i < bgnd_sel.length; i++) if (bgnd_sel[i]) num_bgnd++;
// if (num_bgnd >= clt_parameters.min_bgnd_tiles) { // TODO: same for the backdrop too
// double infinity_disparity = geometryCorrection.getDisparityFromZ(clt_parameters.infinityDistance);
if (bgndScan.texture != null) { // TODO: same for the backdrop too
if (clt_parameters.infinityDistance > 0.0){ // generate background as a billboard
double infinity_disparity = geometryCorrection.getDisparityFromZ(clt_parameters.infinityDistance);
// grow selection, then grow once more and create border_tiles
// create/rstore, probably not needed
boolean [] bg_sel_backup = bgndScan.getSelected().clone();
......@@ -7434,7 +7436,8 @@ public class QuadCLT {
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
// FIXME: make a separate parameter:
infinity_disparity, // 0.25 * 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);
} catch (IOException e) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -224,7 +224,8 @@ public class X3dOutput {
public double [][] getBBox() // center: x,y,z, size:x,y,z
{
double depth = geometry_correction.getZFromDisparity(clt_parameters.bgnd_range);
// double depth = geometry_correction.getZFromDisparity(clt_parameters.bgnd_range);
double depth = clt_parameters.infinityDistance;
double width = depth * geometry_correction.getFOVWidth();
double height = depth * geometry_correction.getFOVHeight();
double [][] bbox = {{0, 0, -depth/2},{width,height,depth}};
......
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