Commit 9d1a83ef authored by Andrey Filippov's avatar Andrey Filippov

added limits on zoom change, multi-color preview images - working state

parent 97109dcb
...@@ -426,6 +426,9 @@ public class CLTParameters { ...@@ -426,6 +426,9 @@ public class CLTParameters {
public boolean tex_debug_disp_tri = false; // !batch_mode && (debugLevel > 0); // TODO: use clt_parameters public boolean tex_debug_disp_tri = false; // !batch_mode && (debugLevel > 0); // TODO: use clt_parameters
public int tex_add_bg_tiles = 0; // If there is gap between clusters, add extra row of background tiles public int tex_add_bg_tiles = 0; // If there is gap between clusters, add extra row of background tiles
public boolean tex_save_full_textures = true; // false; // true; public boolean tex_save_full_textures = true; // false; // true;
public boolean tex_save_interm_textures = false; // Save intermediate texture
public boolean tex_save_um_texture0 = true; // Save full-res texture (only first slice) after unsharp mask filter
public boolean tex_save_preview = true; // Save normalized texture0 as a scene sequence preview
public double tex_alpha_threshold = 0.5; public double tex_alpha_threshold = 0.5;
public boolean tex_renormalize = true; // false - use normalizations from previous scenes to keep consistent colors public boolean tex_renormalize = true; // false - use normalizations from previous scenes to keep consistent colors
public boolean tex_alpha = false; // also - use jpeg? public boolean tex_alpha = false; // also - use jpeg?
...@@ -438,9 +441,9 @@ public class CLTParameters { ...@@ -438,9 +441,9 @@ public class CLTParameters {
public boolean tex_um_fixed = false; // Use fixed range after unsharp mask instead of autorange public boolean tex_um_fixed = false; // Use fixed range after unsharp mask instead of autorange
public double tex_um_range = 500; // Full range after unsharp mask public double tex_um_range = 500; // Full range after unsharp mask
public boolean tex_hist_norm = true; // Normalize texture histogram public boolean tex_hist_norm = true; // Normalize texture histogram
public double tex_hist_amount = 0.7; // Texture histogram normalization amount (0.0 - no normalization, 1.0 - full normalization) public double tex_hist_amount = 0.5; // Texture histogram normalization amount (0.0 - no normalization, 1.0 - full normalization)
public int tex_hist_bins = 1024; // Number of histogram bins to use for texture histograms public int tex_hist_bins = 1024; // Number of histogram bins to use for texture histograms
public int tex_hist_segments = 32; // Number of evenly-spaced percentiles to use for histogram normalization public int tex_hist_segments = 128; // Number of evenly-spaced percentiles to use for histogram normalization
public boolean tex_color = true; // Use pseudo-colored textures public boolean tex_color = true; // Use pseudo-colored textures
public int tex_palette = 1; // Palette number for pseudo colors public int tex_palette = 1; // Palette number for pseudo colors
...@@ -1548,6 +1551,9 @@ public class CLTParameters { ...@@ -1548,6 +1551,9 @@ public class CLTParameters {
properties.setProperty(prefix+"tex_debug_disp_tri", this.tex_debug_disp_tri+""); // boolean properties.setProperty(prefix+"tex_debug_disp_tri", this.tex_debug_disp_tri+""); // boolean
properties.setProperty(prefix+"tex_add_bg_tiles", this.tex_add_bg_tiles+""); // int properties.setProperty(prefix+"tex_add_bg_tiles", this.tex_add_bg_tiles+""); // int
properties.setProperty(prefix+"tex_save_full_textures", this.tex_save_full_textures+""); // boolean properties.setProperty(prefix+"tex_save_full_textures", this.tex_save_full_textures+""); // boolean
properties.setProperty(prefix+"tex_save_interm_textures", this.tex_save_interm_textures+"");// boolean
properties.setProperty(prefix+"tex_save_um_texture0", this.tex_save_um_texture0+""); // boolean
properties.setProperty(prefix+"tex_save_preview", this.tex_save_preview+""); // boolean
properties.setProperty(prefix+"tex_alpha_threshold", this.tex_alpha_threshold+""); // double properties.setProperty(prefix+"tex_alpha_threshold", this.tex_alpha_threshold+""); // double
properties.setProperty(prefix+"tex_renormalize", this.tex_renormalize+""); // boolean properties.setProperty(prefix+"tex_renormalize", this.tex_renormalize+""); // boolean
properties.setProperty(prefix+"tex_alpha", this.tex_alpha+""); // boolean properties.setProperty(prefix+"tex_alpha", this.tex_alpha+""); // boolean
...@@ -2547,6 +2553,9 @@ public class CLTParameters { ...@@ -2547,6 +2553,9 @@ public class CLTParameters {
if (properties.getProperty(prefix+"tex_debug_disp_tri")!=null) this.tex_debug_disp_tri=Boolean.parseBoolean(properties.getProperty(prefix+"tex_debug_disp_tri")); if (properties.getProperty(prefix+"tex_debug_disp_tri")!=null) this.tex_debug_disp_tri=Boolean.parseBoolean(properties.getProperty(prefix+"tex_debug_disp_tri"));
if (properties.getProperty(prefix+"tex_add_bg_tiles")!=null) this.tex_add_bg_tiles=Integer.parseInt(properties.getProperty(prefix+"tex_add_bg_tiles")); if (properties.getProperty(prefix+"tex_add_bg_tiles")!=null) this.tex_add_bg_tiles=Integer.parseInt(properties.getProperty(prefix+"tex_add_bg_tiles"));
if (properties.getProperty(prefix+"tex_save_full_textures")!=null)this.tex_save_full_textures=Boolean.parseBoolean(properties.getProperty(prefix+"tex_save_full_textures")); if (properties.getProperty(prefix+"tex_save_full_textures")!=null)this.tex_save_full_textures=Boolean.parseBoolean(properties.getProperty(prefix+"tex_save_full_textures"));
if (properties.getProperty(prefix+"tex_save_interm_textures")!=null)this.tex_save_interm_textures=Boolean.parseBoolean(properties.getProperty(prefix+"tex_save_interm_textures"));
if (properties.getProperty(prefix+"tex_save_um_texture0")!=null) this.tex_save_um_texture0=Boolean.parseBoolean(properties.getProperty(prefix+"tex_save_um_texture0"));
if (properties.getProperty(prefix+"tex_save_preview")!=null) this.tex_save_preview=Boolean.parseBoolean(properties.getProperty(prefix+"tex_save_preview"));
if (properties.getProperty(prefix+"tex_alpha_threshold")!=null) this.tex_alpha_threshold=Double.parseDouble(properties.getProperty(prefix+"tex_alpha_threshold")); if (properties.getProperty(prefix+"tex_alpha_threshold")!=null) this.tex_alpha_threshold=Double.parseDouble(properties.getProperty(prefix+"tex_alpha_threshold"));
if (properties.getProperty(prefix+"tex_renormalize")!=null) this.tex_renormalize=Boolean.parseBoolean(properties.getProperty(prefix+"tex_renormalize")); if (properties.getProperty(prefix+"tex_renormalize")!=null) this.tex_renormalize=Boolean.parseBoolean(properties.getProperty(prefix+"tex_renormalize"));
if (properties.getProperty(prefix+"tex_alpha")!=null) this.tex_alpha=Boolean.parseBoolean(properties.getProperty(prefix+"tex_alpha")); if (properties.getProperty(prefix+"tex_alpha")!=null) this.tex_alpha=Boolean.parseBoolean(properties.getProperty(prefix+"tex_alpha"));
...@@ -3740,6 +3749,13 @@ public class CLTParameters { ...@@ -3740,6 +3749,13 @@ public class CLTParameters {
gd.addCheckbox ("Save full textures", this.tex_save_full_textures, gd.addCheckbox ("Save full textures", this.tex_save_full_textures,
"Will save anyway if !tex_split_textures."); "Will save anyway if !tex_split_textures.");
gd.addCheckbox ("Save intermediate textures", this.tex_save_interm_textures,
"Save intermediate textures - all slices as floating-point TIFFs.");
gd.addCheckbox ("Save texture slice0", this.tex_save_um_texture0,
"Save full-res texture (only first slice) after unsharp mask filter. Used for flat down-views from UAS.");
gd.addCheckbox ("Save texture as preview", this.tex_save_preview,
"Save full-res texture (first slice) after unsharp mask and histogram normalilzationas a scene sequence preview image.");
gd.addNumericField("Alpha threshold", this.tex_alpha_threshold, 5,7,"", gd.addNumericField("Alpha threshold", this.tex_alpha_threshold, 5,7,"",
"Alpha threshold to consider it opaque."); "Alpha threshold to consider it opaque.");
gd.addCheckbox ("Re-normalize photometric range", this.tex_renormalize, gd.addCheckbox ("Re-normalize photometric range", this.tex_renormalize,
...@@ -4969,6 +4985,9 @@ public class CLTParameters { ...@@ -4969,6 +4985,9 @@ public class CLTParameters {
this.tex_debug_disp_tri = gd.getNextBoolean(); this.tex_debug_disp_tri = gd.getNextBoolean();
this.tex_add_bg_tiles = (int) gd.getNextNumber(); this.tex_add_bg_tiles = (int) gd.getNextNumber();
this.tex_save_full_textures = gd.getNextBoolean(); this.tex_save_full_textures = gd.getNextBoolean();
this.tex_save_interm_textures = gd.getNextBoolean();
this.tex_save_um_texture0 = gd.getNextBoolean();
this.tex_save_preview = gd.getNextBoolean();
this.tex_alpha_threshold = gd.getNextNumber(); this.tex_alpha_threshold = gd.getNextNumber();
this.tex_renormalize = gd.getNextBoolean(); this.tex_renormalize = gd.getNextBoolean();
this.tex_alpha = gd.getNextBoolean(); this.tex_alpha = gd.getNextBoolean();
......
...@@ -264,7 +264,8 @@ public class IntersceneMatchParameters { ...@@ -264,7 +264,8 @@ public class IntersceneMatchParameters {
public double min_offset = 1.5; // pixels - minimal average pixel offset between images to consider interscene matching public double min_offset = 1.5; // pixels - minimal average pixel offset between images to consider interscene matching
public double max_rel_offset = 0.5; // maximal interscene offset as a fraction of image width public double max_rel_offset = 0.5; // maximal interscene offset as a fraction of image width
public double max_roll_deg = 10.0; // maximal interscene roll to consider matching public double max_roll_deg = 5.0; // maximal interscene roll to consider matching
public double max_zoom_diff = 0; // for down-views when changing altitude (0 - ignore)
public boolean fpn_skip = true; // skip too close scenes (false - abort, previous behavior) public boolean fpn_skip = true; // skip too close scenes (false - abort, previous behavior)
public boolean fpn_rematch = true; // match fpn-failed scenes to later scenes with larger difference public boolean fpn_rematch = true; // match fpn-failed scenes to later scenes with larger difference
...@@ -809,6 +810,8 @@ public class IntersceneMatchParameters { ...@@ -809,6 +810,8 @@ public class IntersceneMatchParameters {
"Maximal interscene offset as a fraction of image width to handle low overlap"); "Maximal interscene offset as a fraction of image width to handle low overlap");
gd.addNumericField("Maximal interscene roll", this.max_roll_deg, 6,7,"degrees", gd.addNumericField("Maximal interscene roll", this.max_roll_deg, 6,7,"degrees",
"Maximal interscene roll to consider matching"); "Maximal interscene roll to consider matching");
gd.addNumericField("Maximal interscene relative zoom difference", this.max_zoom_diff, 6,7,"",
"Applicable for the down views from a drone. Saet to 0 to ignore.");
gd.addCheckbox ("Skip too close to reference scenes", this.fpn_skip, gd.addCheckbox ("Skip too close to reference scenes", this.fpn_skip,
"Skip too close to reference scenes (false - abort, previous behavior)"); "Skip too close to reference scenes (false - abort, previous behavior)");
gd.addCheckbox ("Match FPN-failed with other scenes", this.fpn_rematch, gd.addCheckbox ("Match FPN-failed with other scenes", this.fpn_rematch,
...@@ -1193,6 +1196,8 @@ public class IntersceneMatchParameters { ...@@ -1193,6 +1196,8 @@ public class IntersceneMatchParameters {
this.min_offset = gd.getNextNumber(); this.min_offset = gd.getNextNumber();
this.max_rel_offset = gd.getNextNumber(); this.max_rel_offset = gd.getNextNumber();
this.max_roll_deg = gd.getNextNumber(); this.max_roll_deg = gd.getNextNumber();
this.max_zoom_diff = gd.getNextNumber();
this.fpn_skip = gd.getNextBoolean(); this.fpn_skip = gd.getNextBoolean();
this.fpn_rematch = gd.getNextBoolean(); this.fpn_rematch = gd.getNextBoolean();
...@@ -1528,6 +1533,7 @@ public class IntersceneMatchParameters { ...@@ -1528,6 +1533,7 @@ public class IntersceneMatchParameters {
properties.setProperty(prefix+"min_offset", this.min_offset+""); // double properties.setProperty(prefix+"min_offset", this.min_offset+""); // double
properties.setProperty(prefix+"max_rel_offset", this.max_rel_offset+""); // double properties.setProperty(prefix+"max_rel_offset", this.max_rel_offset+""); // double
properties.setProperty(prefix+"max_roll_deg", this.max_roll_deg+""); // double properties.setProperty(prefix+"max_roll_deg", this.max_roll_deg+""); // double
properties.setProperty(prefix+"max_zoom_diff", this.max_zoom_diff+""); // double
properties.setProperty(prefix+"fpn_skip", this.fpn_skip+""); // boolean properties.setProperty(prefix+"fpn_skip", this.fpn_skip+""); // boolean
properties.setProperty(prefix+"fpn_rematch", this.fpn_rematch+""); // boolean properties.setProperty(prefix+"fpn_rematch", this.fpn_rematch+""); // boolean
...@@ -1821,6 +1827,7 @@ public class IntersceneMatchParameters { ...@@ -1821,6 +1827,7 @@ public class IntersceneMatchParameters {
if (properties.getProperty(prefix+"min_offset")!=null) this.min_offset=Double.parseDouble(properties.getProperty(prefix+"min_offset")); if (properties.getProperty(prefix+"min_offset")!=null) this.min_offset=Double.parseDouble(properties.getProperty(prefix+"min_offset"));
if (properties.getProperty(prefix+"max_rel_offset")!=null) this.max_rel_offset=Double.parseDouble(properties.getProperty(prefix+"max_rel_offset")); if (properties.getProperty(prefix+"max_rel_offset")!=null) this.max_rel_offset=Double.parseDouble(properties.getProperty(prefix+"max_rel_offset"));
if (properties.getProperty(prefix+"max_roll_deg")!=null) this.max_roll_deg=Double.parseDouble(properties.getProperty(prefix+"max_roll_deg")); if (properties.getProperty(prefix+"max_roll_deg")!=null) this.max_roll_deg=Double.parseDouble(properties.getProperty(prefix+"max_roll_deg"));
if (properties.getProperty(prefix+"max_zoom_diff")!=null) this.max_zoom_diff=Double.parseDouble(properties.getProperty(prefix+"max_zoom_diff"));
if (properties.getProperty(prefix+"fpn_skip")!=null) this.fpn_skip=Boolean.parseBoolean(properties.getProperty(prefix+"fpn_skip")); if (properties.getProperty(prefix+"fpn_skip")!=null) this.fpn_skip=Boolean.parseBoolean(properties.getProperty(prefix+"fpn_skip"));
if (properties.getProperty(prefix+"fpn_rematch")!=null) this.fpn_rematch=Boolean.parseBoolean(properties.getProperty(prefix+"fpn_rematch")); if (properties.getProperty(prefix+"fpn_rematch")!=null) this.fpn_rematch=Boolean.parseBoolean(properties.getProperty(prefix+"fpn_rematch"));
...@@ -2125,6 +2132,7 @@ public class IntersceneMatchParameters { ...@@ -2125,6 +2132,7 @@ public class IntersceneMatchParameters {
imp.min_offset = this.min_offset; imp.min_offset = this.min_offset;
imp.max_rel_offset = this.max_rel_offset; imp.max_rel_offset = this.max_rel_offset;
imp.max_roll_deg = this.max_roll_deg; imp.max_roll_deg = this.max_roll_deg;
imp.max_zoom_diff = this.max_zoom_diff;
imp.fpn_skip = this.fpn_skip; imp.fpn_skip = this.fpn_skip;
imp.fpn_rematch = this.fpn_rematch; imp.fpn_rematch = this.fpn_rematch;
......
...@@ -86,13 +86,29 @@ public class OpticalFlow { ...@@ -86,13 +86,29 @@ public class OpticalFlow {
public static int COMBO_DSN_INDX_DISP_BG_ALL =10; // cumulative BG disparity (Use FG where no BG is available) public static int COMBO_DSN_INDX_DISP_BG_ALL =10; // cumulative BG disparity (Use FG where no BG is available)
public static int COMBO_DSN_INDX_BLUE_SKY = 11; // Detected featureless infinity (sky) public static int COMBO_DSN_INDX_BLUE_SKY = 11; // Detected featureless infinity (sky)
// interscene adjustments failure reasons. // interscene adjustments failure reasons.
public static int FAIL_REASON_LMA = 1; // LMA failed public static final int FAIL_REASON_LMA = 1; // LMA failed
public static int FAIL_REASON_INTERSCENE = 2; // clt_process_tl_interscene() returned null public static final int FAIL_REASON_INTERSCENE = 2; // clt_process_tl_interscene() returned null
public static int FAIL_REASON_MIN = 3; // average pixel offset is below specified threshold (FPN) public static final int FAIL_REASON_MIN = 3; // average pixel offset is below specified threshold (FPN)
public static int FAIL_REASON_MAX = 4; // average pixel offset is above specified threshold (overlap) public static final int FAIL_REASON_MAX = 4; // average pixel offset is above specified threshold (overlap)
public static int FAIL_REASON_NULL = 5; // null offsets array public static final int FAIL_REASON_NULL = 5; // null offsets array
public static int FAIL_REASON_EMPTY = 6; // No offset pairs in offsets array public static final int FAIL_REASON_EMPTY = 6; // No offset pairs in offsets array
public static int FAIL_REASON_ROLL = 7; // Too high roll between the images public static final int FAIL_REASON_ROLL = 7; // Too high roll between the images
public static final int FAIL_REASON_ZOOM = 8; // Too high zoom ratio between the images
public static String getFailReason(int fr) {
switch (fr) {
case FAIL_REASON_LMA: return "FAIL_REASON_LMA";
case FAIL_REASON_INTERSCENE: return "FAIL_REASON_INTERSCENE";
case FAIL_REASON_MIN: return "FAIL_REASON_MIN";
case FAIL_REASON_MAX: return "FAIL_REASON_MAXv";
case FAIL_REASON_NULL: return "FAIL_REASON_NULL";
case FAIL_REASON_EMPTY: return "FAIL_REASON_EMPTY";
case FAIL_REASON_ROLL: return "FAIL_REASON_ROLL";
case FAIL_REASON_ZOOM: return "FAIL_REASON_ZOOM";
default:
return "unknown scene-matching failure reason="+fr;
}
}
public static double [] ZERO3 = {0.0,0.0,0.0}; public static double [] ZERO3 = {0.0,0.0,0.0};
public static double LINE_ERR = 0.1; public static double LINE_ERR = 0.1;
...@@ -4531,12 +4547,11 @@ public class OpticalFlow { ...@@ -4531,12 +4547,11 @@ public class OpticalFlow {
double min_offset = 0.0; // clt_parameters.imp.min_offset; double min_offset = 0.0; // clt_parameters.imp.min_offset;
double max_offset = clt_parameters.imp.max_rel_offset * tilesX * tile_size; double max_offset = clt_parameters.imp.max_rel_offset * tilesX * tile_size;
double max_roll = clt_parameters.imp.max_roll_deg*Math.PI/180.0; double max_roll = clt_parameters.imp.max_roll_deg*Math.PI/180.0;
double max_zoom_diff = clt_parameters.imp.max_zoom_diff;
boolean fpn_skip = clt_parameters.imp.fpn_skip; // if false - fail as before boolean fpn_skip = clt_parameters.imp.fpn_skip; // if false - fail as before
boolean fpn_rematch = clt_parameters.imp.fpn_rematch; // if false - keep previous boolean fpn_rematch = clt_parameters.imp.fpn_rematch; // if false - keep previous
double [] min_max = {min_offset, max_offset, 0.0} ; // {min, max, actual rms) double [] min_max = {min_offset, max_offset, 0.0} ; // {min, max, actual rms)
int [] fail_reason = new int[1]; // null or int[1]: 0 - OK, 2 - LMA, 3 - min, 4 - max int [] fail_reason = new int[1]; // null or int[1]: 0 - OK, 2 - LMA, 3 - min, 4 - max
for (int scene_index = ref_index - 1; scene_index >= 0 ; scene_index--) { for (int scene_index = ref_index - 1; scene_index >= 0 ; scene_index--) {
// to include ref scene photometric calibration // to include ref scene photometric calibration
quadCLTs[scene_index] = quadCLTs[ref_index].spawnNoModelQuadCLT( quadCLTs[scene_index] = quadCLTs[ref_index].spawnNoModelQuadCLT(
...@@ -4573,6 +4588,17 @@ public class OpticalFlow { ...@@ -4573,6 +4588,17 @@ public class OpticalFlow {
"reliable_ref"); "reliable_ref");
} }
} }
double max_z_change = Double.NaN; // only applicable for drone images
if (max_zoom_diff > 0) { // ignore if set to
double avg_z = quadCLTs[ref_index].getAverageZ(true); // use lma
max_z_change = avg_z * max_zoom_diff;
if (debugLevel > -3) {
System.out.println("Setting maximal Z-direction movement to "+ max_z_change+" m.");
}
}
double [][][] scenes_xyzatr = new double [quadCLTs.length][][]; // previous scene relative to the next one double [][][] scenes_xyzatr = new double [quadCLTs.length][][]; // previous scene relative to the next one
scenes_xyzatr[ref_index] = new double[2][3]; // all zeros scenes_xyzatr[ref_index] = new double[2][3]; // all zeros
boolean after_spiral = false; boolean after_spiral = false;
...@@ -4684,15 +4710,24 @@ public class OpticalFlow { ...@@ -4684,15 +4710,24 @@ public class OpticalFlow {
clt_parameters.imp.debug_level); // 1); // -1); // int debug_level); clt_parameters.imp.debug_level); // 1); // -1); // int debug_level);
boolean adjust_OK = scenes_xyzatr[scene_index] != null; boolean adjust_OK = scenes_xyzatr[scene_index] != null;
if (adjust_OK && (Math.abs(scenes_xyzatr[scene_index][1][2]) > max_roll)) { if (adjust_OK) { // check only for initial orientation, do not check on readjustments
if (Math.abs(scenes_xyzatr[scene_index][1][2]) > max_roll) {
fail_reason[0] = FAIL_REASON_ROLL; fail_reason[0] = FAIL_REASON_ROLL;
adjust_OK = false; adjust_OK = false;
} }
if (max_zoom_diff > 0) { // ignore if set to
if (Math.abs(scenes_xyzatr[scene_index][0][2]) > max_z_change) {
fail_reason[0] = FAIL_REASON_ZOOM;
adjust_OK = false;
}
}
}
// FAIL_REASON_ROLL // FAIL_REASON_ROLL
handle_failure: { handle_failure: {
if (!adjust_OK) { if (!adjust_OK) {
// boolean OK = false; // boolean OK = false;
System.out.println("LMA failed at nscene = "+scene_index+". Reason = "+fail_reason[0]); System.out.println("LMA failed at nscene = "+scene_index+". Reason = "+fail_reason[0]+
" ("+getFailReason(fail_reason[0])+")");
if ((fail_reason[0]==FAIL_REASON_MIN) || ((fail_reason[0]==FAIL_REASON_LMA) && !got_spiral)) { if ((fail_reason[0]==FAIL_REASON_MIN) || ((fail_reason[0]==FAIL_REASON_LMA) && !got_spiral)) {
if (fpn_skip) { if (fpn_skip) {
System.out.println("fpn_skip is set, just using initial pose"); System.out.println("fpn_skip is set, just using initial pose");
...@@ -4708,7 +4743,8 @@ public class OpticalFlow { ...@@ -4708,7 +4743,8 @@ public class OpticalFlow {
if (debugLevel > -4) { if (debugLevel > -4) {
System.out.println("Pass multi scene "+scene_index+" (of "+ quadCLTs.length+") "+ System.out.println("Pass multi scene "+scene_index+" (of "+ quadCLTs.length+") "+
quadCLTs[ref_index].getImageName() + "/" + scene_QuadClt.getImageName()+ quadCLTs[ref_index].getImageName() + "/" + scene_QuadClt.getImageName()+
" FAILED. Setting earliest_scene to "+earliest_scene + " Failure reason: " + fail_reason[0]); " FAILED. Setting earliest_scene to "+earliest_scene + " Failure reason: " + fail_reason[0]+
" ("+getFailReason(fail_reason[0])+")");
} }
// set this and all previous to null // set this and all previous to null
for (; scene_index >= 0 ; scene_index--) { for (; scene_index >= 0 ; scene_index--) {
...@@ -12841,7 +12877,7 @@ public class OpticalFlow { ...@@ -12841,7 +12877,7 @@ public class OpticalFlow {
for (int i = 0; i < scene_disparity_strength[0].length; i++) { for (int i = 0; i < scene_disparity_strength[0].length; i++) {
// scene_disparity_strength[0][i] = (scene_disparity_strength[0][i] - average_disparity) / average_absolute_disparity; // scene_disparity_strength[0][i] = (scene_disparity_strength[0][i] - average_disparity) / average_absolute_disparity;
scene_disparity_strength[0][i] = (scene_disparity_strength[0][i] - average_disparity) /magic_scale; scene_disparity_strength[0][i] = (scene_disparity_strength[0][i] - average_disparity) /magic_scale;
scene_disparity_strength[0][i] = 1.0 / average_absolute_disparity; scene_disparity_strength[1][i] = 1.0 / average_absolute_disparity;
} }
} }
} }
...@@ -14144,6 +14180,7 @@ public class OpticalFlow { ...@@ -14144,6 +14180,7 @@ public class OpticalFlow {
int debugLevel) int debugLevel)
{ {
System.out.println("reAdjustPairsLMAInterscene(): using mb_max_gain="+mb_max_gain); System.out.println("reAdjustPairsLMAInterscene(): using mb_max_gain="+mb_max_gain);
boolean fail_on_zoom_roll=false; // it should fail on initial adjustment
int avg_len = clt_parameters.imp.avg_len; int avg_len = clt_parameters.imp.avg_len;
// boolean test_motion_blur = true;//false // boolean test_motion_blur = true;//false
// Set up velocities from known coordinates, use averaging // Set up velocities from known coordinates, use averaging
...@@ -14183,7 +14220,8 @@ public class OpticalFlow { ...@@ -14183,7 +14220,8 @@ public class OpticalFlow {
int tile_size = quadCLTs[ref_index].getTileProcessor().getTileSize(); int tile_size = quadCLTs[ref_index].getTileProcessor().getTileSize();
double min_offset = clt_parameters.imp.min_offset; double min_offset = clt_parameters.imp.min_offset;
double max_offset = second_margin*clt_parameters.imp.max_rel_offset * tilesX * tile_size; double max_offset = second_margin*clt_parameters.imp.max_rel_offset * tilesX * tile_size;
double max_roll = clt_parameters.imp.max_roll_deg*Math.PI/180.0; double max_roll = second_margin*clt_parameters.imp.max_roll_deg*Math.PI/180.0;
double max_zoom_diff = second_margin*clt_parameters.imp.max_zoom_diff;
boolean fpn_skip = clt_parameters.imp.fpn_skip; // if false - fail as before boolean fpn_skip = clt_parameters.imp.fpn_skip; // if false - fail as before
boolean fpn_rematch = clt_parameters.imp.fpn_rematch; // if false - keep previous boolean fpn_rematch = clt_parameters.imp.fpn_rematch; // if false - keep previous
double [] min_max = {min_offset, max_offset, 0.0} ; // {min, max, actual rms) double [] min_max = {min_offset, max_offset, 0.0} ; // {min, max, actual rms)
...@@ -14297,6 +14335,17 @@ public class OpticalFlow { ...@@ -14297,6 +14335,17 @@ public class OpticalFlow {
} }
System.out.println(); System.out.println();
} }
double max_z_change = Double.NaN; // only applicable for drone images
if (max_zoom_diff > 0) { // ignore if set to
double avg_z = quadCLTs[ref_index].getAverageZ(true); // use lma
max_z_change = avg_z * max_zoom_diff;
if (fail_on_zoom_roll) {
if (debugLevel > -3) {
System.out.println("Setting maximal Z-direction movement to "+ max_z_change+" m.");
}
}
}
boolean [] failed_scenes = new boolean[quadCLTs.length]; boolean [] failed_scenes = new boolean[quadCLTs.length];
int num_failed =0; int num_failed =0;
for (int nscene = ref_index; nscene >= earliest_scene; nscene--) { for (int nscene = ref_index; nscene >= earliest_scene; nscene--) {
...@@ -14517,15 +14566,29 @@ public class OpticalFlow { ...@@ -14517,15 +14566,29 @@ public class OpticalFlow {
mb_vectors, // double [][] mb_vectors, // now [2][ntiles]; mb_vectors, // double [][] mb_vectors, // now [2][ntiles];
clt_parameters.imp.debug_level); // 1); // -1); // int debug_level); clt_parameters.imp.debug_level); // 1); // -1); // int debug_level);
boolean adjust_OK = scenes_xyzatr[nscene] != null; boolean adjust_OK = scenes_xyzatr[nscene] != null;
if (adjust_OK && (Math.abs(scenes_xyzatr[nscene][1][2]) > max_roll)) { // if (adjust_OK && (Math.abs(scenes_xyzatr[nscene][1][2]) > max_roll)) {
// fail_reason[0] = FAIL_REASON_ROLL;
// adjust_OK = false;
// }
if (adjust_OK && fail_on_zoom_roll) { // check only for initial orientation, do not check on readjustments
if (Math.abs(scenes_xyzatr[nscene][1][2]) > max_roll) {
fail_reason[0] = FAIL_REASON_ROLL; fail_reason[0] = FAIL_REASON_ROLL;
adjust_OK = false; adjust_OK = false;
} }
if (max_zoom_diff > 0) { // ignore if set to
if (Math.abs(scenes_xyzatr[nscene][0][2]) > max_z_change) { // NaN OK - will not fail
fail_reason[0] = FAIL_REASON_ZOOM;
adjust_OK = false;
}
}
}
// FAIL_REASON_ROLL // FAIL_REASON_ROLL
handle_failure: { handle_failure: {
if (!adjust_OK) { if (!adjust_OK) {
boolean OK = false; boolean OK = false;
System.out.println("LMA failed at nscene = "+nscene+". Reason = "+fail_reason[0]); System.out.println("LMA failed at nscene = "+nscene+". Reason = "+fail_reason[0]+
" ("+getFailReason(fail_reason[0])+")");
if ((fail_reason[0]==FAIL_REASON_MIN) || ((fail_reason[0]==FAIL_REASON_LMA))) { if ((fail_reason[0]==FAIL_REASON_MIN) || ((fail_reason[0]==FAIL_REASON_LMA))) {
if (fpn_skip) { if (fpn_skip) {
System.out.println("fpn_skip is set, just skipping this scene"); System.out.println("fpn_skip is set, just skipping this scene");
...@@ -14547,7 +14610,8 @@ public class OpticalFlow { ...@@ -14547,7 +14610,8 @@ public class OpticalFlow {
if (debugLevel > -4) { if (debugLevel > -4) {
System.out.println("reAdjustPairsLMAInterscene "+nscene+" (of "+ quadCLTs.length+") "+ System.out.println("reAdjustPairsLMAInterscene "+nscene+" (of "+ quadCLTs.length+") "+
quadCLTs[ref_index].getImageName() + "/" + ts+ quadCLTs[ref_index].getImageName() + "/" + ts+
" FAILED. Setting earliest_scene to "+earliest_scene + " Failure reason: " + fail_reason[0]); " FAILED. Setting earliest_scene to "+earliest_scene + " Failure reason: " + fail_reason[0]+
" ("+getFailReason(fail_reason[0])+")");
} }
// set this and all previous to null // set this and all previous to null
for (; nscene >= 0 ; nscene--) { for (; nscene >= 0 ; nscene--) {
......
...@@ -203,6 +203,21 @@ public class QuadCLTCPU { ...@@ -203,6 +203,21 @@ public class QuadCLTCPU {
} }
public double getAverageZ(boolean use_lma) {
double [][] dls = getDLS();
if (dls==null) {
return Double.NaN;
}
double [][] ds = new double [][] {dls[use_lma?1:0], dls[2]};
double sw=0, swd=0;
for (int i = 0; i < ds[0].length; i++) if (!Double.isNaN(ds[0][i])){
sw += ds[1][i];
swd += ds[0][i] * ds[1][i];
}
double disp_avg = swd/sw;
double z_avg = getGeometryCorrection().getZFromDisparity(disp_avg);
return z_avg;
}
public double [][] getDLS(){ // get disparity, disparity_lma, strength public double [][] getDLS(){ // get disparity, disparity_lma, strength
if (dsi == null) { if (dsi == null) {
...@@ -2205,6 +2220,25 @@ public class QuadCLTCPU { ...@@ -2205,6 +2220,25 @@ public class QuadCLTCPU {
return imp; return imp;
} }
public ImagePlus saveDoubleArrayInModelDirectory(
String suffix,
double [] data,
int width,
int height)
{
double [][] data2= new double[][] {data};
String x3d_path = getX3dDirectory();
String file_name = image_name + suffix;
String file_path = x3d_path + Prefs.getFileSeparator() + file_name + ".tiff";
ImageStack imageStack = ShowDoubleFloatArrays.makeStack(data2, width, height, null);
ImagePlus imp = new ImagePlus( file_name, imageStack);
FileSaver fs=new FileSaver(imp);
fs.saveAsTiff(file_path);
System.out.println("saveDoubleArrayInModelDirectory(): saved "+file_path);
return imp;
}
public String saveImagePlusInModelDirectory( public String saveImagePlusInModelDirectory(
String suffix, // null - use title from the imp String suffix, // null - use title from the imp
ImagePlus imp) ImagePlus imp)
...@@ -15115,6 +15149,65 @@ public class QuadCLTCPU { ...@@ -15115,6 +15149,65 @@ public class QuadCLTCPU {
return true; return true;
} }
public boolean writeLwirPreview(
final CLTParameters clt_parameters,
double [] data,
QuadCLT scene,
int tex_palette,
String suffix,
int debugLevel) {
if (scene == null) {
scene = (QuadCLT) this;
}
double [][] rendered_texture = new double[][] {data, new double[data.length]};
for (int i = 0; i < rendered_texture[0].length; i++) {
rendered_texture[1][i] = Double.isNaN(rendered_texture[0][i])? 0.0: 1.0;
}
double [] minmax = scene.getColdHot(); // used in linearStackToColor (from this current scene)
int width = getTileProcessor().getTilesX() *getTileProcessor().getTileSize();
int height = data.length/width;
String set_name = getImageName();
if (set_name == null ) {
QuadCLTCPU.SetChannels [] set_channels = setChannels(debugLevel);
set_name = set_channels[0].set_name;
}
String model_dir= correctionsParameters.selectX3dDirectory(
set_name, // quad timestamp. Will be ignored if correctionsParameters.use_x3d_subdirs is false
null,
true, // smart,
true); //newAllowed, // save\
String title = getImageName()+suffix+"-preview";
ImagePlus imp = QuadCLTCPU.linearStackToColorLWIR(
clt_parameters, // CLTParameters clt_parameters,
tex_palette, // int lwir_palette, // <0 - do not convert
minmax, // double [] minmax,
title, // String name,
"", // String suffix, // such as disparity=...
true, // boolean toRGB,
rendered_texture, // faded_textures[nslice], // double [][] texture_data,
width, // int width, // int tilesX,
height, // int height, // int tilesY,
debugLevel); // int debugLevel )
String preview_path = model_dir + Prefs.getFileSeparator() + title+".jpeg";
if (new File(preview_path).exists() && !correctionsParameters.thumb_overwrite) {
System.out.println("file "+preview_path+" exists, skipping preview generation");
return false;
}
if (debugLevel > -2) {
System.out.println("Saving preview image to "+preview_path);
}
EyesisCorrections.saveAndShow(
imp,
model_dir,
false,
false,
correctionsParameters.JPEG_quality, // jpegQuality); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
(debugLevel > -2) ? debugLevel : 1); // int debugLevel (print what it saves)
return true;
}
public boolean writeRatingFile( // USED in lwir public boolean writeRatingFile( // USED in lwir
int debugLevel int debugLevel
) )
......
...@@ -2478,7 +2478,7 @@ public class TexturedModel { ...@@ -2478,7 +2478,7 @@ public class TexturedModel {
// If there is gap between clusters, add extra row of background tiles // If there is gap between clusters, add extra row of background tiles
// int add_bg_tiles = clt_parameters.tex_add_bg_tiles; // 0; // 1; // int add_bg_tiles = clt_parameters.tex_add_bg_tiles; // 0; // 1;
final boolean save_full_textures=clt_parameters.tex_save_full_textures || !clt_parameters.tex_split_textures; //true; // false; // true; final boolean save_full_textures= clt_parameters.tex_save_full_textures || !clt_parameters.tex_split_textures; //true; // false; // true;
final double alpha_threshold = clt_parameters.tex_alpha_threshold; // 0.5; final double alpha_threshold = clt_parameters.tex_alpha_threshold; // 0.5;
final boolean renormalize = clt_parameters.tex_renormalize; // true; // false - use normalizations from previous scenes to keep consistent colors final boolean renormalize = clt_parameters.tex_renormalize; // true; // false - use normalizations from previous scenes to keep consistent colors
final boolean no_alpha = !clt_parameters.tex_alpha; // true; // also - use jpeg? final boolean no_alpha = !clt_parameters.tex_alpha; // true; // also - use jpeg?
...@@ -7026,6 +7026,9 @@ public class TexturedModel { ...@@ -7026,6 +7026,9 @@ public class TexturedModel {
final double tex_hist_amount = clt_parameters.tex_hist_amount; // clt_parameters. 0.7; final double tex_hist_amount = clt_parameters.tex_hist_amount; // clt_parameters. 0.7;
final int tex_hist_bins = clt_parameters.tex_hist_bins; // 1024 ; final int tex_hist_bins = clt_parameters.tex_hist_bins; // 1024 ;
final int tex_hist_segments = clt_parameters.tex_hist_segments; // 32 ; final int tex_hist_segments = clt_parameters.tex_hist_segments; // 32 ;
final boolean save_interm_textures= clt_parameters.tex_save_interm_textures;
final boolean save_um_texture0= clt_parameters.tex_save_um_texture0;
final boolean save_preview= clt_parameters.tex_save_preview;
// final boolean show_sky_textures = clt_parameters.lre_show_sky_textures && !clt_parameters.multiseq_run; // final boolean show_sky_textures = clt_parameters.lre_show_sky_textures && !clt_parameters.multiseq_run;
// final int show_slice_bitmap = clt_parameters.lre_show_slice_bitmap; // final int show_slice_bitmap = clt_parameters.lre_show_slice_bitmap;
...@@ -7297,7 +7300,7 @@ public class TexturedModel { ...@@ -7297,7 +7300,7 @@ public class TexturedModel {
min_trim_disparity, // final double min_trim_disparity, // do not try to trim texture outlines with lower disparities min_trim_disparity, // final double min_trim_disparity, // do not try to trim texture outlines with lower disparities
tp_tasks_ref, // final TpTask[][][] tp_tasks_ref, // reference tasks for each slice to get offsets tp_tasks_ref, // final TpTask[][][] tp_tasks_ref, // reference tasks for each slice to get offsets
ref_scene.getImageName()); // null); // ref_scene.getImageName()); // final String dbg_prefix); ref_scene.getImageName()); // null); // ref_scene.getImageName()); // final String dbg_prefix);
if (debugLevel > -20) { if (save_interm_textures) {
double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length]; double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length];
String [] dbg_titles = new String[dbg_textures.length]; String [] dbg_titles = new String[dbg_textures.length];
String [] dbg_subtitles = new String [faded_textures[0].length]; String [] dbg_subtitles = new String [faded_textures[0].length];
...@@ -7309,19 +7312,7 @@ public class TexturedModel { ...@@ -7309,19 +7312,7 @@ public class TexturedModel {
dbg_titles[i] = dbg_subtitles[i % dbg_subtitles.length] + "-" + (i / dbg_subtitles.length); dbg_titles[i] = dbg_subtitles[i % dbg_subtitles.length] + "-" + (i / dbg_subtitles.length);
} }
ref_scene.writePreview(
dbg_textures[0], // double [] data,
debugLevel); // int debugLevel
String suffix = "-combined_textures-prenorm-pre_UM"; String suffix = "-combined_textures-prenorm-pre_UM";
if (!batch_run && (debugLevel > -1)) {
ShowDoubleFloatArrays.showArrays(
dbg_textures,
tilesX * transform_size,
tilesY * transform_size,
true,
ref_scene.getImageName()+suffix,
dbg_titles);
}
ref_scene.saveDoubleArrayInModelDirectory( ref_scene.saveDoubleArrayInModelDirectory(
suffix, // String suffix, suffix, // String suffix,
null, // String [] labels, // or null null, // String [] labels, // or null
...@@ -7353,7 +7344,7 @@ public class TexturedModel { ...@@ -7353,7 +7344,7 @@ public class TexturedModel {
THREADS_MAX); // final int threadsMax) // maximal number of threads to launch THREADS_MAX); // final int threadsMax) // maximal number of threads to launch
} }
if (debugLevel > -20) { if (save_interm_textures) {
double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length]; double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length];
String [] dbg_titles = new String[dbg_textures.length]; String [] dbg_titles = new String[dbg_textures.length];
String [] dbg_subtitles = new String [faded_textures[0].length]; String [] dbg_subtitles = new String [faded_textures[0].length];
...@@ -7396,7 +7387,7 @@ public class TexturedModel { ...@@ -7396,7 +7387,7 @@ public class TexturedModel {
tex_um_weight); // final double um_weight) tex_um_weight); // final double um_weight)
} }
if (debugLevel > -20) { if (save_interm_textures || save_um_texture0) {
double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length]; double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length];
String [] dbg_titles = new String[dbg_textures.length]; String [] dbg_titles = new String[dbg_textures.length];
String [] dbg_subtitles = new String [faded_textures[0].length]; String [] dbg_subtitles = new String [faded_textures[0].length];
...@@ -7410,6 +7401,7 @@ public class TexturedModel { ...@@ -7410,6 +7401,7 @@ public class TexturedModel {
} }
String suffix = "-combined_textures-prenorm"; String suffix = "-combined_textures-prenorm";
if (save_interm_textures) {
if (!batch_run && (debugLevel > -1)) { if (!batch_run && (debugLevel > -1)) {
ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays(
dbg_textures, dbg_textures,
...@@ -7419,6 +7411,7 @@ public class TexturedModel { ...@@ -7419,6 +7411,7 @@ public class TexturedModel {
ref_scene.getImageName()+suffix, ref_scene.getImageName()+suffix,
dbg_titles); dbg_titles);
} }
ref_scene.saveDoubleArrayInModelDirectory( ref_scene.saveDoubleArrayInModelDirectory(
suffix, // String suffix, suffix, // String suffix,
null, // String [] labels, // or null null, // String [] labels, // or null
...@@ -7444,6 +7437,19 @@ public class TexturedModel { ...@@ -7444,6 +7437,19 @@ public class TexturedModel {
tilesY * transform_size); // int height, // int tilesY, tilesY * transform_size); // int height, // int tilesY,
} }
} }
// here is the best full-range texture. For UAS just use slice 0
if (save_um_texture0) {
suffix = "-texture";
if (tex_um) {
suffix+= "-UM"+tex_um_sigma+"_"+tex_um_weight;
}
ref_scene.saveDoubleArrayInModelDirectory(
suffix, // String suffix,
dbg_textures[0], // double [][] data,
tilesX * transform_size, // int width, // int tilesX,
tilesY * transform_size); // int height, // int tilesY,
}
}
//renormalize //renormalize
...@@ -7508,9 +7514,7 @@ public class TexturedModel { ...@@ -7508,9 +7514,7 @@ public class TexturedModel {
cold_hot, // final double [] min_max, cold_hot, // final double [] min_max,
inverted_table); // final double [] inv_table) inverted_table); // final double [] inv_table)
} }
if (save_interm_textures || save_preview) {
if (debugLevel > -20) { // always
double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length]; double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length];
String [] dbg_titles = new String[dbg_textures.length]; String [] dbg_titles = new String[dbg_textures.length];
String [] dbg_subtitles = new String [faded_textures[0].length]; String [] dbg_subtitles = new String [faded_textures[0].length];
...@@ -7521,12 +7525,23 @@ public class TexturedModel { ...@@ -7521,12 +7525,23 @@ public class TexturedModel {
for (int i = 0; i < dbg_textures.length; i++) { for (int i = 0; i < dbg_textures.length; i++) {
dbg_textures[i] = faded_textures[i / faded_textures[0].length][i % faded_textures[0].length]; dbg_textures[i] = faded_textures[i / faded_textures[0].length][i % faded_textures[0].length];
dbg_titles[i] = dbg_subtitles[i % dbg_subtitles.length] + "-" + (i / dbg_subtitles.length); dbg_titles[i] = dbg_subtitles[i % dbg_subtitles.length] + "-" + (i / dbg_subtitles.length);
} }
// ref_scene.writePreview( // may movbe to different (earlier) stage of processing, (search for "-combined_textures") if (save_preview) {
// dbg_textures[0], // double [] data, ref_scene.writePreview( // may movbe to different (earlier) stage of processing, (search for "-combined_textures")
// debugLevel); // int debugLevel dbg_textures[0], // double [] data,
debugLevel); // int debugLevel
// Trying different palettes
int tex_palette = 2; // regular color
ref_scene.writeLwirPreview(
clt_parameters, // final CLTParameters clt_parameters,
dbg_textures[0], // double [] data,
null, // QuadCLT scene,
tex_palette, // int tex_palette,
"-color", // +tex_palette, // String suffix,
debugLevel); // int debugLevel)
}
if (save_interm_textures) {
String suffix = "-combined_textures"; String suffix = "-combined_textures";
if (!batch_run && (debugLevel > -1)) { if (!batch_run && (debugLevel > -1)) {
ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays(
...@@ -7543,27 +7558,7 @@ public class TexturedModel { ...@@ -7543,27 +7558,7 @@ public class TexturedModel {
dbg_textures, // double [][] data, dbg_textures, // double [][] data,
tilesX * transform_size, // int width, // int tilesX, tilesX * transform_size, // int width, // int tilesX,
tilesY * transform_size); // int height, // int tilesY, tilesY * transform_size); // int height, // int tilesY,
if (dbg_weights != null) {
suffix = "-texture_weights";
if (!batch_run && (debugLevel > -1)) {
ShowDoubleFloatArrays.showArrays(
dbg_weights,
tilesX * transform_size,
tilesY * transform_size,
true,
ref_scene.getImageName()+suffix,
dbg_titles);
} }
ref_scene.saveDoubleArrayInModelDirectory(
suffix, // String suffix,
null, // String [] labels, // or null
dbg_weights, // double [][] data,
tilesX * transform_size, // int width, // int tilesX,
tilesY * transform_size); // int height, // int tilesY,
}
} }
return faded_textures; return faded_textures;
} }
...@@ -7593,7 +7588,8 @@ public class TexturedModel { ...@@ -7593,7 +7588,8 @@ public class TexturedModel {
int transform_size, int transform_size,
int debugLevel) int debugLevel)
{ {
boolean save_tiff_texture = true; final boolean save_interm_textures= clt_parameters.tex_save_interm_textures;
boolean save_tiff_texture = save_interm_textures;
if (debugLevel > -2) { if (debugLevel > -2) {
System.out.println("getInterCombinedTextures(): no_alpha=" + no_alpha); // true System.out.println("getInterCombinedTextures(): no_alpha=" + no_alpha); // true
} }
......
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