Commit 84bd8cc0 authored by Andrey Filippov's avatar Andrey Filippov

Improved flat ground detection

parent cac11d90
...@@ -227,9 +227,21 @@ public class GroundPlane { ...@@ -227,9 +227,21 @@ public class GroundPlane {
final double gnd_percent_high= 0.2; // 0.9; // high ground percentile final double gnd_percent_high= 0.2; // 0.9; // high ground percentile
final double gnd_max_high_over = 0.1; // 0.5; // pix = make dependent on average disparity? final double gnd_max_high_over = 0.1; // 0.5; // pix = make dependent on average disparity?
final int min_good1 = 10; // 50; // minimal good tiles after pass1 final int min_good1 = 10; // 50; // minimal good tiles after pass1
final double max_abs_diff = 0.03; // maximal absolute disparity difference from the plane final double max_abs_diff = 0.03; // maximal absolute disparity difference from the plane
final double max_rel_diff = 0.03; // 0.1; // maximal relative disparity difference from the plane final double max_rel_diff = 0.03; // 0.1; // maximal relative disparity difference from the plane
final double normal_damping = 0.001; // pull to horizontal if not enough data final double normal_damping = 0.001; // pull to horizontal if not enough data
final double blur_frac = 0.01; // 0.03
final double weight_frac = 0.3; // multiply weight by w= 1/(1 + (err/k_max_diff)^2)
final int mtile_size = 16;
final double min_ev_rel = 0.3;
final double max_tilt = 0.2;
final double top_percent = 0.5; // remove above 50% center intersection
final int min_macro_tiles = 3;
final boolean [] good_tiles = new boolean[ref_scene.getTilesX()*ref_scene.getTilesY()]; final boolean [] good_tiles = new boolean[ref_scene.getTilesX()*ref_scene.getTilesY()];
String dbg_title =ref_scene.getImageName()+"-ground tilts"; String dbg_title =ref_scene.getImageName()+"-ground tilts";
double [][] to_ground_xyzatr_frac= GroundPlane.getPlaneDualPassMetric( // returns to_ground_xyzatr (rotated around the ground point nadir of teh drone) double [][] to_ground_xyzatr_frac= GroundPlane.getPlaneDualPassMetric( // returns to_ground_xyzatr (rotated around the ground point nadir of teh drone)
...@@ -240,6 +252,13 @@ public class GroundPlane { ...@@ -240,6 +252,13 @@ public class GroundPlane {
min_good1, // final int min_good1, // minimal good tiles after pass1 min_good1, // final int min_good1, // minimal good tiles after pass1
max_abs_diff, // final double max_abs_diff, // maximal absolute disparity difference from the plane max_abs_diff, // final double max_abs_diff, // maximal absolute disparity difference from the plane
max_rel_diff, // final double max_rel_diff, // maximal relative disparity difference from the plane max_rel_diff, // final double max_rel_diff, // maximal relative disparity difference from the plane
blur_frac, // final double blur_frac, // = 0.01; // 0.03
weight_frac, // final double weight_frac, // = 0.3; // multiply weight by w= 1/(1 + (err/k_max_diff)^2)
mtile_size, // final int mtile_size, // = 16;
min_ev_rel, // final double min_ev_rel, // = 0.3;
max_tilt, // final double max_tilt, // = 0.2;
top_percent, // final double top_percent, // = 0.5; // remove above 50% center intersection
min_macro_tiles, // final int min_macro_tiles, // = 3;
normal_damping, // final double normal_damping, normal_damping, // final double normal_damping,
ref_scene.getTilesX(),// final int width, ref_scene.getTilesX(),// final int width,
good_tiles, // final boolean [] good_tiles, // null or boolean[data.length] // should all be false good_tiles, // final boolean [] good_tiles, // null or boolean[data.length] // should all be false
...@@ -286,6 +305,15 @@ public class GroundPlane { ...@@ -286,6 +305,15 @@ public class GroundPlane {
final int min_good1, // minimal good tiles after pass1 final int min_good1, // minimal good tiles after pass1
final double max_abs_diff, // maximal absolute disparity difference from the plane final double max_abs_diff, // maximal absolute disparity difference from the plane
final double max_rel_diff, // maximal relative disparity difference from the plane final double max_rel_diff, // maximal relative disparity difference from the plane
final double blur_frac, // = 0.01; // 0.03
final double weight_frac, // = 0.3; // multiply weight by w= 1/(1 + (err/k_max_diff)^2)
final int mtile_size, // = 16;
final double min_ev_rel, // = 0.3;
final double max_tilt, // = 0.2;
final double top_percent, // = 0.5; // remove above 50% center intersection
final int min_macro_tiles, // = 3;
final double normal_damping, final double normal_damping,
final int width, final int width,
final boolean [] good_tiles, // null or boolean[data.length] // should all be false final boolean [] good_tiles, // null or boolean[data.length] // should all be false
...@@ -293,9 +321,7 @@ public class GroundPlane { ...@@ -293,9 +321,7 @@ public class GroundPlane {
final String dbg_title, final String dbg_title,
final int debugLevel) { final int debugLevel) {
boolean print_histogram = debugLevel > 0; boolean print_histogram = debugLevel > 0;
double blur_frac = 0.01; // 0.03 // boolean eig_weight = false;
double weight_frac = 0.3; // multiply weight by w= 1/(1 + (err/k_max_diff)^2)
boolean use_lma = true; boolean use_lma = true;
int num_bins = 1000; int num_bins = 1000;
String dbg_title1 = (dbg_title != null) ? (dbg_title + "-stage1") : null; String dbg_title1 = (dbg_title != null) ? (dbg_title + "-stage1") : null;
...@@ -484,6 +510,39 @@ public class GroundPlane { ...@@ -484,6 +510,39 @@ public class GroundPlane {
normal_damping, // final double normal_damping, normal_damping, // final double normal_damping,
dbg_title+"-metric", // final String dbg_title, dbg_title+"-metric", // final String dbg_title,
debugLevel); // final int debugLevel) { debugLevel); // final int debugLevel) {
double [][] macroplanes = getMacroPlanes( // no weights
wxyz, // final double [][] wxyz,
mask3, // final boolean [] mask,
weights, // final double [] weight,
false, // final boolean eig_weight, // use weights when calculating eiget values (false - only mask)
width, // final int tilesX,
mtile_size, // final int mtile_size,
normal_damping, // final double normal_damping,
dbg_title+"-macroplanes", // final String dbg_title,
debugLevel); // final int debugLevel) {
boolean [] macro_mask = getMaskFromMacro(
mask3, // boolean [] mask_in,
macroplanes, // double [][] macroplanes,
min_ev_rel, // double min_ev_rel,
max_tilt, // double max_tilt,
top_percent, // double top_percent, // remove above percentile
min_macro_tiles, // int min_macro_tiles,
width, // int tilesX,
mtile_size, // int mtile_size,
debugLevel); // int debugLevel)
double [][] macroplanes_weights = getMacroPlanes(
wxyz, // final double [][] wxyz,
mask3, // final boolean [] mask,
weights, // final double [] weight,
true, // final boolean eig_weight, // use weights when calculating eiget values (false - only mask)
width, // final int tilesX,
mtile_size, // final int mtile_size,
normal_damping, // final double normal_damping,
dbg_title+"-macroplanes", // final String dbg_title,
debugLevel); // final int debugLevel) {
double [][] ground_xyzatr = ErsCorrection.invertXYZATR(to_ground_xyzatr); // straight down from the camera, then rotated double [][] ground_xyzatr = ErsCorrection.invertXYZATR(to_ground_xyzatr); // straight down from the camera, then rotated
double [][] virtual_camera_from_ground_xyz = ErsCorrection.invertXYZATR(new double [][] {ground_xyzatr[0],new double[3]}); double [][] virtual_camera_from_ground_xyz = ErsCorrection.invertXYZATR(new double [][] {ground_xyzatr[0],new double[3]});
double [][] virtual_camera_from_camera = ErsCorrection.combineXYZATR(ground_xyzatr, virtual_camera_from_ground_xyz); double [][] virtual_camera_from_camera = ErsCorrection.combineXYZATR(ground_xyzatr, virtual_camera_from_ground_xyz);
...@@ -510,6 +569,10 @@ public class GroundPlane { ...@@ -510,6 +569,10 @@ public class GroundPlane {
}; };
*/ */
if ((dbg_title != null) || (gnd_disp != null)) { if ((dbg_title != null) || (gnd_disp != null)) {
// expand macrotiles results to match tiles
// rotate ref_disparity and show // rotate ref_disparity and show
double [][] pXpYD_ground = OpticalFlow.transformToScenePxPyD( double [][] pXpYD_ground = OpticalFlow.transformToScenePxPyD(
null, // final Rectangle full_woi_in, // show larger than sensor WOI (or null) IN TILES null, // final Rectangle full_woi_in, // show larger than sensor WOI (or null) IN TILES
...@@ -525,6 +588,41 @@ public class GroundPlane { ...@@ -525,6 +588,41 @@ public class GroundPlane {
} }
} }
if (dbg_title != null) { if (dbg_title != null) {
int tilesX = width;
int tilesY = wxyz.length/width;
int mtile_half = mtile_size/2;
int mtilesX = (tilesX - mtile_size)/mtile_half + 1;
// int mtilesY = (tilesY - mtile_size)/mtile_half + 1;
double [][] macro_exp = new double [tilesX * tilesY][];
double [][] macro_wexp = new double [tilesX * tilesY][];
for (int mtile = 0; mtile < macroplanes.length; mtile++){
int mtileX = mtile % mtilesX;
int mtileY = mtile / mtilesX;
int min_y = mtileY * mtile_half + mtile_half/2;
int min_x = mtileX * mtile_half + mtile_half/2;
int max_y = min_y + mtile_half;
int max_x = min_x + mtile_half;
if (min_y < mtile_half) min_y = 0;
if (min_x < mtile_half) min_x = 0;
if (max_y > (tilesY-mtile_half)) max_y = tilesY;
if (max_x > (tilesX-mtile_half)) max_x = tilesX;
if (macroplanes[mtile] != null) {
for (int tileY = min_y; tileY < max_y; tileY++) {
for (int tileX = min_x; tileX < max_x; tileX++) {
int ntile = tileY * tilesX + tileX;
macro_exp[ntile] = macroplanes[mtile];
}
}
}
if (macroplanes_weights[mtile] != null) {
for (int tileY = min_y; tileY < max_y; tileY++) {
for (int tileX = min_x; tileX < max_x; tileX++) {
int ntile = tileY * tilesX + tileX;
macro_wexp[ntile] = macroplanes_weights[mtile];
}
}
}
}
double [][] wxyz_gnd = OpticalFlow.transformToWorldXYZ( double [][] wxyz_gnd = OpticalFlow.transformToWorldXYZ(
gnd_disparity, // final double [] disparity_ref, // invalid tiles - NaN in disparity gnd_disparity, // final double [] disparity_ref, // invalid tiles - NaN in disparity
...@@ -542,21 +640,49 @@ public class GroundPlane { ...@@ -542,21 +640,49 @@ public class GroundPlane {
} }
String [] dbg_titles = {"ref_disparity", "ground_disparity", "ref_z", "gnd_z","masked_z","weights"}; String [] dbg_titles = {"ref_disparity", "ground_disparity", "ref_z", "gnd_z","masked_z","weights",
"offs_macro", "tX_macro", "ty_macro", "eigen_prod", "eigen0", "eigen1", "weigen_prod", "weigen0", "weigen1",
"z_macro", // masked ref_z after evaluating macro tiles
"z-center"};// masked intersection of camera axis with the macro plane
double [][] dbg_data = new double[dbg_titles.length][]; double [][] dbg_data = new double[dbg_titles.length][];
dbg_data[0] = ref_disparity; dbg_data[ 0] = ref_disparity;
dbg_data[1] = gnd_disparity; dbg_data[ 1] = gnd_disparity;
dbg_data[2] = ref_z; dbg_data[ 2] = ref_z;
dbg_data[3] = gnd_z; dbg_data[ 3] = gnd_z;
dbg_data[4] = gnd_z.clone(); dbg_data[ 4] = gnd_z.clone();
dbg_data[5] = weights.clone(); dbg_data[ 5] = weights.clone();
dbg_data[ 6] = new double[tilesX*tilesY];
Arrays.fill(dbg_data[6],Double.NaN);
dbg_data[ 7] = dbg_data[6].clone();
dbg_data[ 8] = dbg_data[6].clone();
dbg_data[ 9] = dbg_data[6].clone();
dbg_data[10] = dbg_data[6].clone();
dbg_data[11] = dbg_data[6].clone();
dbg_data[12] = dbg_data[6].clone();
dbg_data[13] = dbg_data[6].clone();
dbg_data[14] = dbg_data[6].clone();
dbg_data[15] = dbg_data[6].clone();
dbg_data[16] = dbg_data[6].clone();
for (int i = 0; i < mask3.length; i++) { for (int i = 0; i < mask3.length; i++) {
if (!mask3[i]) { if (!mask3[i]) {
dbg_data[4][i] = Double.NaN; dbg_data[4][i] = Double.NaN;
dbg_data[5][i] = Double.NaN; dbg_data[5][i] = Double.NaN;
} }
if (macro_exp[i] != null) {
for (int j = 0; j < macro_exp[i].length; j++) {
dbg_data[ 6+j][i] = macro_exp[i][j];
}
}
if (macro_wexp[i] != null) {
for (int j = 0; j < 3; j++) {
dbg_data[ 12+j][i] = macro_wexp[i][3+j];
}
}
if (macro_mask[i]) {
dbg_data[15][i] = ref_z[i];
dbg_data[16][i] = dbg_data[ 6][i]; // offset
}
} }
ref_Clt.saveDoubleArrayInModelDirectory( ref_Clt.saveDoubleArrayInModelDirectory(
dbg_title+"-result", // String suffix, dbg_title+"-result", // String suffix,
dbg_titles, // String [] labels, // or null dbg_titles, // String [] labels, // or null
...@@ -576,6 +702,102 @@ public class GroundPlane { ...@@ -576,6 +702,102 @@ public class GroundPlane {
// return to_ground_xyzatr_centered; // return to_ground_xyzatr_centered;
} }
public static boolean []getMaskFromMacro(
boolean [] mask_in,
double [][] macroplanes,
double min_ev_rel,
double max_tilt,
double top_percent, // remove above percentile
int min_macro_tiles,
int tilesX,
int mtile_size,
int debugLevel) {
// int min_macro_tiles = 3;
int num_bins = 100;
double max_tilt2 = max_tilt*max_tilt;
boolean [] mask = mask_in.clone();
int tilesY = mask.length/tilesX;
int mtile_half = mtile_size/2;
int mtilesX = (tilesX - mtile_size)/mtile_half + 1;
boolean [] keep_macro = new boolean [macroplanes.length];
double [] min_max_macro = null;
int num_macro = 0;
double [] macro_weights = new double [macroplanes.length];
double [] macro_offsets = new double [macroplanes.length];
for (int mtile = 0; mtile < macroplanes.length; mtile++){
keep_macro[mtile] = macroplanes[mtile] != null;
if (keep_macro[mtile]) {
keep_macro[mtile] = (macroplanes[mtile][1]* macroplanes[mtile][1] + macroplanes[mtile][2]* macroplanes[mtile][2]) < max_tilt2;
}
if (keep_macro[mtile]) {
double z = macroplanes[mtile][0];
if (min_max_macro == null) {
min_max_macro = new double [] {z, z};
} else {
if (z < min_max_macro[0]) min_max_macro[0] = z;
if (z > min_max_macro[1]) min_max_macro[1] = z;
}
num_macro++;
macro_weights[mtile] = macroplanes[mtile][3]; // eigenvalues product
macro_offsets[mtile] = macroplanes[mtile][0]; //
}
}
if ((num_macro >= min_macro_tiles) && (min_max_macro[1] > min_max_macro[0])) {
double [] hist = getHistogram1d(
macro_offsets, // double [] data, // may have NaNs
macro_weights, // double [] weights,
min_max_macro[0], // double hist_low,
min_max_macro[1], // double hist_high,
num_bins, // int num_bins,
debugLevel); // int debugLevel)
double [] fractions = {top_percent};
double [] percentiles = getPercentiles(
hist, // double [] hist,
fractions); // double [] fractions)
double high_lim = min_max_macro[0] + percentiles[0] * (min_max_macro[1] - min_max_macro[0]);
// if (high_lim > (low_lim + gnd_max_high_over)) high_lim = low_lim + gnd_max_high_over;
for (int mtile = 0; mtile < macroplanes.length; mtile++) if (keep_macro[mtile]){
if (macro_offsets[mtile] > high_lim) {
keep_macro[mtile] = false;
}
}
}
for (int mtile = 0; mtile < macroplanes.length; mtile++){
int mtileX = mtile % mtilesX;
int mtileY = mtile / mtilesX;
int min_y = mtileY * mtile_half + mtile_half/2;
int min_x = mtileX * mtile_half + mtile_half/2;
int max_y = min_y + mtile_half;
int max_x = min_x + mtile_half;
if (min_y < mtile_half) min_y = 0;
if (min_x < mtile_half) min_x = 0;
if (max_y > (tilesY-mtile_half)) max_y = tilesY;
if (max_x > (tilesX-mtile_half)) max_x = tilesX;
/*
boolean mask_out = macroplanes[mtile] == null;
if (!mask_out) {
mask_out |= macroplanes[mtile][3] < min_ev_rel;
}
if (!mask_out) {
mask_out |= (macroplanes[mtile][1]* macroplanes[mtile][1] + macroplanes[mtile][2]* macroplanes[mtile][2]) > max_tilt2;
}
if (mask_out) {
*/
if (!keep_macro[mtile]) {
for (int tileY = min_y; tileY < max_y; tileY++) {
for (int tileX = min_x; tileX < max_x; tileX++) {
int ntile = tileY * tilesX + tileX;
mask[ntile] = false;
}
}
}
}
return mask;
}
public static double [] getDisparityPlaneDualPass( // returns to_ground_xyzatr (rotated around the ground point nadir of teh drone) public static double [] getDisparityPlaneDualPass( // returns to_ground_xyzatr (rotated around the ground point nadir of teh drone)
final QuadCLT ref_Clt, final QuadCLT ref_Clt,
final double gnd_percent_low, final double gnd_percent_low,
...@@ -1197,6 +1419,136 @@ public class GroundPlane { ...@@ -1197,6 +1419,136 @@ public class GroundPlane {
return null; return null;
} }
/**
* Split frame area into 50% macro tiles, and calculate tilts, offset, and confidence
* derived from the eigenvalues
* @param wxyz array of X, Y, Z of the elevation surface relative to the camera reference scene. May have nulls
* @param mask corresponding tile mask
* @param weight array of tile weights
* @param tilesX elevation map width (in tiles). Now 80
* @param mtile_size width of the square macrotiles in tiles (also 16?)
* @param normal_damping regularization parameter to make tilts 0 if there is not enough data to calculate them
* @param dbg_title if not null, use it to generate debug images
* @param debugLevel debug level, now is tested if (debugLevel > -3)
* @return array of per-macrotile: offset at frame center, tiltX, tiltY, product of eigenvalues, both eigenvalues (starting with smaller)
*/
public static double [][] getMacroPlanes(
final double [][] wxyz,
final boolean [] mask,
final double [] weight,
final boolean eig_weight, // use weights when calculating eiget values (false - only mask)
final int tilesX,
final int mtile_size,
final double normal_damping,
final String dbg_title,
final int debugLevel) {
final int tilesY = wxyz.length/tilesX;
final int mtile_half = mtile_size/2;
final int mtilesX = (tilesX-mtile_size)/mtile_half + 1;
final int mtilesY = (tilesY-mtile_size)/mtile_half + 1;
final double [][] mtiles = new double [mtilesX*mtilesY][];
final double [] damping = Double.isNaN(normal_damping) ? null : (new double [] {normal_damping, normal_damping});
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
// Calculate eigenvalues for all square is full of weight = 1.0;
final int eig_full = ((mtile_half-1)*mtile_half*(2*mtile_half-1)/3 + mtile_half*(mtile_half-1) +mtile_half/2)*2*mtile_half;
final double scale_eig = 1.0/eig_full;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
final double [][][] mdata = new double [mtile_size * mtile_size][][];
for (int mTile = ai.getAndIncrement(); mTile < mtiles.length; mTile = ai.getAndIncrement()){
int ntile = ((mTile / mtilesX) * tilesX + (mTile % mtilesX)) * mtile_half; // top-left
int local_xc = ((mTile % mtilesX) + 1) * mtile_half;
int local_yc = ((mTile / mtilesX) + 1) * mtile_half;
int ntile_center = local_xc + tilesX*local_yc; // wxyz may be null, will not use local center
int mindx = 0;
// for centroid and eigenvalues
double x0 = mtile_half, y0 = mtile_half;
double s0 = 0, sx=0,sy = 0, sx2 = 0, sy2=0, sxy = 0;
for (int my = 0; my < mtile_size; my++) {
double y = my - y0;
for (int mx = 0; mx < mtile_size; mx++) {
if ((wxyz[ntile] != null) && ((mask == null) || mask[ntile])) {
double x = mx - x0;
double w = (weight == null)? 1.0 : weight[ntile];
mdata[mindx] = new double[3][];
mdata[mindx][0] = new double [2];
mdata[mindx][0][0] = wxyz[ntile][0]; // from global center
mdata[mindx][0][1] = wxyz[ntile][1];
mdata[mindx][1] = new double [1];
mdata[mindx][1][0] = wxyz[ntile][2];
mdata[mindx][2] = new double [1];
mdata[mindx][2][0] = w;
// for eigenvalues
if (!eig_weight) {
w = 1.0;
}
s0 += w;
sx += w * x;
sy += w * y;
sx2 += w * x * x;
sy2 += w * y * y;
sxy += w * x * y;
mindx++;
}
ntile++;
}
ntile += (tilesX-mtile_size);
}
if (mindx > 0) { // OK to have even a single tile
Arrays.fill(mdata, mindx, mdata.length, null);
double[][] approx2d = (new PolynomialApproximation()).quadraticApproximation(
mdata,
true, // boolean forceLinear, // use linear approximation
damping, // damping, // double [] damping, null OK
-1); // debug level
if (approx2d == null) {
continue;
}
// z_tilts= new double [] { approx2d[0][2], approx2d[0][0], approx2d[0][1]};
// int ntile = ((mTile / mtilesX) * tilesX + (mTile % mtilesX)) * mtile_half;
int dx = tilesX/2 - local_xc; // center relative to this
int dy = tilesY/2 - local_yc;
mtiles[mTile] = new double[6]; // center offset, tiltx, tilty, eigenvalues product, eigenvalue0, eigenvalue1
// can not shift as do not know wx, wy at local center
mtiles[mTile][0] = approx2d[0][2]; // + dx * approx2d[0][0] + dy * approx2d[0][1]; // shift to center
mtiles[mTile][1] = approx2d[0][0];
mtiles[mTile][2] = approx2d[0][1];
mtiles[mTile][3] = Double.NaN;
mtiles[mTile][4] = Double.NaN;
mtiles[mTile][5] = Double.NaN;
// calculate eigenvalues of weight*mask? Use both or a product as a measure of confidence
x0 += sx / s0; // will these be used?
y0 += sy / s0;
//https://users.cs.utah.edu/~tch/CS4640/resources/A%20geometric%20interpretation%20of%20the%20covariance%20matrix.pdf
double cxx = sx2 - sx * sx / s0, cyy= sy2 - sy * sy / s0, cxy = sxy - sx * sy / s0;
if ((sx2 != 0) && (sy2 != 0) && (cxx != 0) && (cyy != 0)){
double [][] acovar = {{cxx, cxy},{cxy,cyy}};
double [] eig = Correlation2d.getEigen2x2(acovar); // return 4-element array: first eigenvector x, y, lambda0, lambda1 (lambda0 <= lampda1)
if (eig != null) {
double eig0= Math.sqrt(scale_eig*eig[2]);
double eig1= Math.sqrt(scale_eig*eig[3]);
mtiles[mTile][3] = Math.sqrt(eig0 * eig1);
mtiles[mTile][4] = eig0; // eig[2] < eig[3];
mtiles[mTile][5] = eig1;
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return mtiles;
}
public static double [][] getPlane( // from the camera coordinates to in-plane coordinates public static double [][] getPlane( // from the camera coordinates to in-plane coordinates
final double [][] wxyz, final double [][] wxyz,
final boolean use_parallel_proj, // for parallel xyz is 0, otherwise - point on the ground under the camera final boolean use_parallel_proj, // for parallel xyz is 0, otherwise - point on the ground under the camera
......
...@@ -6506,6 +6506,18 @@ public class OpticalFlow { ...@@ -6506,6 +6506,18 @@ public class OpticalFlow {
final double max_abs_diff = 0.05; // maximal absolute disparity difference from the plane final double max_abs_diff = 0.05; // maximal absolute disparity difference from the plane
final double max_rel_diff = 0.1; // maximal relative disparity difference from the plane final double max_rel_diff = 0.1; // maximal relative disparity difference from the plane
final double normal_damping = 0.001; // pull to horizontal if not enough data final double normal_damping = 0.001; // pull to horizontal if not enough data
final double blur_frac = 0.01; // 0.03
final double weight_frac = 0.3; // multiply weight by w= 1/(1 + (err/k_max_diff)^2)
final int mtile_size = 16;
final double min_ev_rel = 0.3;
final double max_tilt = 0.2;
final double top_percent = 0.5; // remove above 50% center intersection
final int min_macro_tiles = 3;
final boolean [] good_tiles = new boolean[ds[0].length]; final boolean [] good_tiles = new boolean[ds[0].length];
// String dbg_title =master_CLT.getImageName()+"-ground tilts"; // String dbg_title =master_CLT.getImageName()+"-ground tilts";
String dbg_title = "-ground_tilts"; String dbg_title = "-ground_tilts";
...@@ -6518,6 +6530,13 @@ public class OpticalFlow { ...@@ -6518,6 +6530,13 @@ public class OpticalFlow {
min_good1, // final int min_good1, // minimal good tiles after pass1 min_good1, // final int min_good1, // minimal good tiles after pass1
max_abs_diff, // final double max_abs_diff, // maximal absolute disparity difference from the plane max_abs_diff, // final double max_abs_diff, // maximal absolute disparity difference from the plane
max_rel_diff, // final double max_rel_diff, // maximal relative disparity difference from the plane max_rel_diff, // final double max_rel_diff, // maximal relative disparity difference from the plane
blur_frac, // final double blur_frac, // = 0.01; // 0.03
weight_frac, // final double weight_frac, // = 0.3; // multiply weight by w= 1/(1 + (err/k_max_diff)^2)
mtile_size, // final int mtile_size, // = 16;
min_ev_rel, // final double min_ev_rel, // = 0.3;
max_tilt, // final double max_tilt, // = 0.2;
top_percent, // final double top_percent, // = 0.5; // remove above 50% center intersection
min_macro_tiles, // final int min_macro_tiles, // = 3;
normal_damping, // final double normal_damping, normal_damping, // final double normal_damping,
master_CLT.getTilesX(),// final int width, master_CLT.getTilesX(),// final int width,
good_tiles, // final boolean [] good_tiles, // null or boolean[data.length] // should all be false good_tiles, // final boolean [] good_tiles, // null or boolean[data.length] // should all be false
......
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