Commit 8facfc7c authored by Andrey Filippov's avatar Andrey Filippov

tested FPN

parent 4a5fabd6
......@@ -713,19 +713,27 @@ public class CorrectionFPN {
order, // final int order,
debugLevel); // final int debugLevel){
final double um_sigma = 5;
final int good_margins = 12;
final double threshold= 20; // 5;
final double w_blur = 2.5; // 5;
double [][] weights = getFPNWeights(
final double um_sigma = clt_parameters.imp.cuas_w_um_sigma; // 1.5; // run UM to approximate LoG
final int good_margins = clt_parameters.imp.cuas_w_good_margins;// 12; // consider defined values near image margins always good (do not have anything better anyway). Does not apply to NaN
// // areas that will be filled from different poses
final double threshold= clt_parameters.imp.cuas_w_threshold; // 20; // threshold to cut off high variations (it will be squared to compare to squared difference values)
final double scale_thresh = clt_parameters.imp.cuas_w_scale_thresh;// 1.5; // Allow over-threshold values before GB, to block them completely after GB thresholding
final boolean expand_max = clt_parameters.imp.cuas_w_expand_max; // true; // replace diff values by max of neighbors (fill zero-square gaps)
final double outliers_w = clt_parameters.imp.cuas_w_outliers; // 0.001; // Assign weights to outliers to avoid NaNs in bad areas
final double w_blur = clt_parameters.imp.cuas_w_blur; // 1.0; // blur thresholded squared values to smooth transitions.
String weights_debug_title = cuas_debug?scene_CLT.getImageName()+"-DBG-WEIGHTS":null;
double [][] weights = getFPNWeights( // add avg?
result, // final double [][][] synth_img,
um_sigma, // final double um_sigma,
good_margins, // final int good_margins,
threshold, // final double threshold,
scale_thresh, // final double scale_thresh,
expand_max, // final boolean expand_max,
outliers_w, // final double outliers_w,
w_blur, // final double w_blur,
width); // final int width
width, // final int width
weights_debug_title); //String debug_title) {
if (debugLevel > -3) {
......@@ -1789,8 +1797,12 @@ public class CorrectionFPN {
final double um_sigma,
final int good_margins,
final double threshold,
final double scale_thresh,
final boolean expand_max,
final double outliers_w,
final double w_blur,
final int width) {
final int width,
String debug_title) {
final int num_sensors = synth_img.length;
final int num_pix = synth_img[0][0].length;
final int height = num_pix/width;
......@@ -1798,17 +1810,22 @@ public class CorrectionFPN {
final Rectangle rborder = new Rectangle(good_margins,good_margins,width - 2*good_margins, height - 2 * good_margins);
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final double bad_val = 1.0 - scale_thresh; // -0.5;
final int [] offsets = {-width,-width+1, 1, width+1, width, width-1, -1, -width-1};
// unsharp max
String [] titles_top = (debug_title!= null) ? (new String [] {"synthetic","synth_GB","UM-squared","expanded","expanded-GB","weights"}): null;
final double [][][] dbg_data = (debug_title!= null) ? new double [titles_top.length][num_sensors][] : null;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
DoubleGaussianBlur gb = new DoubleGaussianBlur();
double [] pre_max = new double [num_pix];
for (int nSens = ai.getAndIncrement(); nSens < num_sensors; nSens = ai.getAndIncrement()) {
double [] pixels = synth_img[nSens][0];
if (dbg_data != null) dbg_data[0][nSens] = pixels.clone();
double [] w = weights[nSens];
System.arraycopy(pixels,0,w,0,num_pix);
for (int npix = 0; npix < num_pix; npix++) if (Double.isNaN(pixels[npix])){
// bad_pix[npix] = true;
w[npix] = 0;
}
gb.blurDouble(
......@@ -1818,19 +1835,47 @@ public class CorrectionFPN {
um_sigma, // double sigmaX,
um_sigma, // double sigmaY,
0.01); // double accuracy)
int npix=0;
if (dbg_data != null) dbg_data[1][nSens] = w.clone();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int npix = x + width * y;
double d = (pixels[npix] - w[npix])/threshold;
w[npix] = Math.max(1.0 - d * d, 0);
w[npix] = Math.max(scale_thresh - d * d, bad_val);
if (Double.isNaN(pixels[npix])) {
w[npix] = 0.0; // bad
w[npix] = bad_val; // bad
} else if (!rborder.contains(x, y)) {
w[npix] = 1.0; // good
w[npix] = scale_thresh; // good
}
npix++;
}
}
if (dbg_data != null) dbg_data[2][nSens] = w.clone();
/*
for (int npix = 0; npix < num_pix; npix++) {
if (w[npix] > scale_thresh) {
w[npix] = scale_thresh;
} else if (w[npix] < bad_val) {
w[npix] = bad_val;
}
}
if (dbg_data != null) dbg_data[3][nSens] = w.clone();
*/
if (expand_max) {
System.arraycopy(w, 0, pre_max, 0, num_pix);
for (int py = 1; py < (height-1); py++) {
for (int px = 1; px < (width-1); px++) {
int indx = py * width + px;
double mx = w[indx];
for (int offs:offsets) {
mx = Math.min(mx, pre_max[indx + offs]);
}
w[indx] = mx;
}
}
}
if (dbg_data != null) dbg_data[3][nSens] = w.clone();
if (w_blur > 0) {
gb.blurDouble(
w, //
width, // terrain woi
......@@ -1839,10 +1884,31 @@ public class CorrectionFPN {
w_blur, // double sigmaY,
0.01); // double accuracy)
}
if (dbg_data != null) dbg_data[4][nSens] = w.clone();
for (int npix = 0; npix < num_pix; npix++) {
if (w[npix] > 1.0) {
w[npix] = 1.0;
} else if (w[npix] < outliers_w) {
w[npix] = outliers_w;
}
}
if (dbg_data != null) dbg_data[5][nSens] = w.clone();
}
}
};
}
ImageDtt.startAndJoin(threads);
if (dbg_data != null) {
String [] titles = new String [num_sensors];
for (int nsens = 0; nsens < num_sensors; nsens++) titles[nsens] = "SENSOR-"+nsens;
ShowDoubleFloatArrays.showArraysHyperstack(
dbg_data, // double[][][] pixels,
width, // int width,
debug_title, // String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
titles, // String [] titles, // all slices*frames titles or just slice titles or null
titles_top, // String [] frame_titles, // frame titles or null
true); // boolean show)
}
return weights;
}
......
......@@ -679,6 +679,18 @@ min_str_neib_fpn 0.35
public double cuas_invert_tolerance = 0.001; // Finish enhancing when last change was lower than
public int cuas_invert_gap2 = 10; // Maximal dual gap size for inversion (depends on scanning radius in tiles) <0 = use maximal possible
// Calculation of FPN weights for averaging different poses, detecting high gradients of the real image on back-propagated average where image difference
// may have large errors causes my discrete pixels
public double cuas_w_um_sigma = 1.5; // run UM to approximate LoG
public int cuas_w_good_margins = 12; // consider defined values near image margins always good (do not have anything better anyway). Does not apply to NaN
// areas that will be filled from different poses
public double cuas_w_threshold= 20; // threshold to cut off high variations (it will be squared to compare to squared difference values)
public double cuas_w_scale_thresh = 1.1; // Allow over-threshold values before GB, to block them completely after GB thresholding
public boolean cuas_w_expand_max = true; // replace diff values by max of neighbors (fill zero-square gaps)
public double cuas_w_outliers = 0.0001; // Assign weights to outliers to avoid NaNs in bad areas
public double cuas_w_blur = 1.0; // blur thresholded squared values to smooth transitions.
public boolean cuas_debug = false; // save debug images (and show them if not in batch mode)
public boolean cuas_step_debug = false; // save debug images during per-step cuas recalculation (and show them if not in batch mode)
......@@ -2040,6 +2052,22 @@ min_str_neib_fpn 0.35
gd.addNumericField("Inversion gap (dual size)", this.cuas_invert_gap2, 0,3,"tiles",
"Maximal dual gap size for inversion (depends on scanning radius in tiles) .");
gd.addMessage("=== Masking out high LoG areas for averaging for different poses ===");
gd.addNumericField("UM sigma", this.cuas_w_um_sigma, 5,7,"pix",
"Run UM to approximate LoG for detection of areas with sharp changes.");
gd.addNumericField("Good margins", this.cuas_w_good_margins, 0,3,"pix",
"Consider defined values near image margins always good (do not have anything better anyway). Does not apply to NaN areas that will be filled from different poses.");
gd.addNumericField("Blanking threshold", this.cuas_w_threshold, 5,7,"",
"Threshold to cut off high variations (it will be squared to compare to squared difference values).");
gd.addNumericField("Scale threshold", this.cuas_w_scale_thresh, 5,7,"x",
"Finish enhancing tasks inversion when last change was lower than this value.");
gd.addCheckbox ("Expand squared diffs", this.cuas_w_expand_max,
"Replace squared diff values by max of 8 neighbors.");
gd.addNumericField("Outliers weight", this.cuas_w_outliers, 5,7,"x",
"Assign weights to outliers to avoid NaNs in bad areas (remaining undefined with all poses combined).");
gd.addNumericField("Blur weights", this.cuas_w_blur, 5,7,"pix",
"Blur thresholded squared values to smooth transitions.");
gd.addMessage("=== Debug ===");
gd.addCheckbox ("Save/show debug images", this.cuas_debug,
"Save CUAS-related debug images and show them in non-batch mode.");
......@@ -2958,6 +2986,14 @@ min_str_neib_fpn 0.35
this.cuas_invert_tolerance = gd.getNextNumber();
this.cuas_invert_gap2 = (int) gd.getNextNumber();
this.cuas_w_um_sigma = gd.getNextNumber();
this.cuas_w_good_margins =(int) gd.getNextNumber();
this.cuas_w_threshold = gd.getNextNumber();
this.cuas_w_scale_thresh = gd.getNextNumber();
this.cuas_w_expand_max = gd.getNextBoolean();
this.cuas_w_outliers = gd.getNextNumber();
this.cuas_w_blur = gd.getNextNumber();
this.cuas_debug = gd.getNextBoolean();
this.cuas_step_debug = gd.getNextBoolean();
......@@ -3803,6 +3839,13 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_invert_tolerance",this.cuas_invert_tolerance+"");// double
properties.setProperty(prefix+"cuas_invert_gap2", this.cuas_invert_gap2+""); // int
properties.setProperty(prefix+"cuas_w_um_sigma", this.cuas_w_um_sigma+""); // double
properties.setProperty(prefix+"cuas_w_good_margins", this.cuas_w_good_margins+""); // int
properties.setProperty(prefix+"cuas_w_threshold", this.cuas_w_threshold+""); // double
properties.setProperty(prefix+"cuas_w_scale_thresh", this.cuas_w_scale_thresh+""); // double
properties.setProperty(prefix+"cuas_w_expand_max", this.cuas_w_expand_max+""); // boolean
properties.setProperty(prefix+"cuas_w_outliers", this.cuas_w_outliers+""); // double
properties.setProperty(prefix+"cuas_w_blur", this.cuas_w_blur+""); // double
properties.setProperty(prefix+"cuas_debug", this.cuas_debug+""); // boolean
properties.setProperty(prefix+"cuas_step_debug", this.cuas_step_debug+""); // boolean
......@@ -4623,6 +4666,14 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_invert_tolerance")!=null)this.cuas_invert_tolerance=Double.parseDouble(properties.getProperty(prefix+"cuas_invert_tolerance"));
if (properties.getProperty(prefix+"cuas_invert_gap2")!=null) this.cuas_invert_gap2=Integer.parseInt(properties.getProperty(prefix+"cuas_invert_gap2"));
if (properties.getProperty(prefix+"cuas_w_um_sigma")!=null) this.cuas_w_um_sigma=Double.parseDouble(properties.getProperty(prefix+"cuas_w_um_sigma"));
if (properties.getProperty(prefix+"cuas_w_good_margins")!=null) this.cuas_w_good_margins=Integer.parseInt(properties.getProperty(prefix+"cuas_w_good_margins"));
if (properties.getProperty(prefix+"cuas_w_threshold")!=null) this.cuas_w_threshold=Double.parseDouble(properties.getProperty(prefix+"cuas_w_threshold"));
if (properties.getProperty(prefix+"cuas_w_scale_thresh")!=null) this.cuas_w_scale_thresh=Double.parseDouble(properties.getProperty(prefix+"cuas_w_scale_thresh"));
if (properties.getProperty(prefix+"cuas_w_expand_max")!=null) this.cuas_w_expand_max=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_w_expand_max"));
if (properties.getProperty(prefix+"cuas_w_outliers")!=null) this.cuas_w_outliers=Double.parseDouble(properties.getProperty(prefix+"cuas_w_outliers"));
if (properties.getProperty(prefix+"cuas_w_blur")!=null) this.cuas_w_blur=Double.parseDouble(properties.getProperty(prefix+"cuas_w_blur"));
if (properties.getProperty(prefix+"cuas_debug")!=null) this.cuas_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_debug"));
if (properties.getProperty(prefix+"cuas_step_debug")!=null) this.cuas_step_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_step_debug"));
......@@ -5443,6 +5494,14 @@ min_str_neib_fpn 0.35
imp.cuas_invert_tolerance = this.cuas_invert_tolerance;
imp.cuas_invert_gap2 = this.cuas_invert_gap2;
imp.cuas_w_um_sigma = this.cuas_w_um_sigma;
imp.cuas_w_good_margins= this.cuas_w_good_margins;
imp.cuas_w_threshold = this.cuas_w_threshold;
imp.cuas_w_scale_thresh = this.cuas_w_scale_thresh;
imp.cuas_w_expand_max = this.cuas_w_expand_max;
imp.cuas_w_outliers = this.cuas_w_outliers;
imp.cuas_w_blur = this.cuas_w_blur;
imp.cuas_debug = this.cuas_debug;
imp.cuas_step_debug = this.cuas_step_debug;
......
......@@ -5224,7 +5224,7 @@ public class OpticalFlow {
debugLevel-2);
}
quadCLTs[scene_index].setImageCenter(center_CLT.getImageCenter());
if (early_try_back) {
if (early_try_back) { // just faster debugging, not used in production
double [][][] back_prop = CorrectionFPN.backPropagate(
clt_parameters, // CLTParameters clt_parameters,
discard_border, // final int discard_border,
......
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