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

Implemented augmentPairwiseAffines() to add more pairwise matches

after all scenes are matched and have defined affines
parent ef8c6ac2
......@@ -161,12 +161,13 @@ public class ComboMatch {
int gpu_width= clt_parameters.imp.rln_gpu_width; // 3008;
int gpu_height= clt_parameters.imp.rln_gpu_height; // 3008;
int zoom_lev = -3; // 0; // +1 - zoom in twice, -1 - zoom out twice
boolean show_combo = false; // true;
boolean create_pairwise_matches = false;
boolean create_pairwise_affines = false;
boolean equalize_overlaps = false;
boolean create_map = false;
boolean create_equalize = false;
boolean show_combo = false; // true;
boolean create_pairwise_matches = false;
boolean create_pairwise_affines = false;
boolean augment_pairwise_affines = false; // needs to repeat create_pairwise_matches to update overlaps
boolean equalize_overlaps = false;
boolean create_map = false;
boolean create_equalize = false;
boolean use_saved_collection = true; // false;
boolean save_collection = true;
......@@ -240,6 +241,7 @@ public class ComboMatch {
gd.addCheckbox ("Show combo maps/stats", show_combo, "Generate/save combo maps and stats.");
gd.addCheckbox ("Create overlap pairs", create_pairwise_matches, "Create scene pairs overlaps.");
gd.addCheckbox ("Create pairwise affines", create_pairwise_affines, "Create affines for scene pairs.");
gd.addCheckbox ("Augment pairwise affines", augment_pairwise_affines, "Augment pairwise affines after building initial map and re-running create_pairwise_matches.");
gd.addCheckbox ("Equalize overlap pairs", equalize_overlaps, "Equalize intensities in overlaps.");
gd.addCheckbox ("Create map", create_map, "Create combined map from pairwise matches.");
gd.addCheckbox ("Equalize intensities", create_equalize, "Create map intensities equalization from pairwise matches.");
......@@ -305,6 +307,7 @@ public class ComboMatch {
show_combo = gd.getNextBoolean();
create_pairwise_matches = gd.getNextBoolean();
create_pairwise_affines = gd.getNextBoolean();
augment_pairwise_affines = gd.getNextBoolean();
equalize_overlaps = gd.getNextBoolean();
create_map = gd.getNextBoolean();
create_equalize = gd.getNextBoolean();
......@@ -823,17 +826,22 @@ public class ComboMatch {
return ok; // Just exit, do not try other commands. if (!ok) return false;
}
if (augment_pairwise_affines) {
boolean ok =maps_collection.augmentPairwiseAffines(
clt_parameters, // CLTParameters clt_parameters,
orthoMapsCollection_savepath); // String orthoMapsCollection_path);
return ok; // Just exit, do not try other commands. if (!ok) return false;
}
if (create_pairwise_affines) {
// boolean ok =maps_collection.getIntersectedPairs(
// clt_parameters, // CLTParameters clt_parameters,
// orthoMapsCollection_savepath); // String orthoMapsCollection_path);
boolean ok =maps_collection.generatePairwiseAffines(
clt_parameters, // CLTParameters clt_parameters,
orthoMapsCollection_savepath); // String orthoMapsCollection_path);
return ok; // Just exit, do not try other commands. if (!ok) return false;
}
if (equalize_overlaps) {
boolean ok =maps_collection.equalizeIntersectedPairs(
clt_parameters, // CLTParameters clt_parameters,
......@@ -876,9 +884,14 @@ public class ComboMatch {
double flt_min_rms = clt_parameters.imp.flt_min_rms; // 0.0;
double flt_max_rms = clt_parameters.imp.flt_max_rms; // 2.0;
boolean flt_nan_rms = clt_parameters.imp.flt_nan_rms; // false;
boolean flt_filt_zoom = clt_parameters.imp.flt_filt_zoom; // true;
int flt_min_zoom = clt_parameters.imp.flt_min_zoom; // -2;
int flt_max_zoom = clt_parameters.imp.flt_max_zoom; // 10;
boolean flt_show_names = clt_parameters.imp.flt_show_names; // true;
boolean flt_show_overlaps = clt_parameters.imp.flt_show_overlaps; // true;
boolean flt_show_rms = clt_parameters.imp.flt_show_rms; // true;
boolean flt_show_zoom = clt_parameters.imp.flt_show_zoom; // true;
boolean flt_update_config = false;
String flt_extra_line = "--- select a single image ---";
GenericJTabbedDialog gdf = new GenericJTabbedDialog("Select pairs filter/display",800,500);
......@@ -889,9 +902,15 @@ public class ComboMatch {
gdf.addNumericField("Minimal RMSE", flt_min_rms, 3,7,"", "Minimal LMA RMSE of the scene pair.");
gdf.addNumericField("Maximal RMSE", flt_max_rms, 3,7,"", "Maximal LMA RMSE of the scene pair.");
gdf.addCheckbox ("NaN RMS (failed match)", flt_nan_rms, "Keep only failed matches with RMSE=NaN.");
gdf.addCheckbox ("Filter by zoom level" , flt_filt_zoom, "Filter by the zoom level used for matching.");
gdf.addNumericField("Minimal zoom", flt_min_zoom, 0,3,"","Minimal zoom level used for matching.");
gdf.addNumericField("Maximal zoom", flt_max_zoom, 0,3,"","Maximal zoom level used for matching.");
gdf.addCheckbox ("Show scene names", flt_show_names, "Show scene full names (timestamps) in selection drop-down list.");
gdf.addCheckbox ("Show scene overlaps", flt_show_overlaps, "Show scene overlaps (in percents) in selection drop-down list.");
gdf.addCheckbox ("Show pairs RMSE", flt_show_rms, "Show scene match RMSE in selection drop-down list.");
gdf.addCheckbox ("Show zoom level", flt_show_zoom, "Show zoom level.");
gdf.addCheckbox ("Update configuration", flt_update_config, "Update matching configuration parameters to be saved as defaults.");
gdf.showDialog();
if (gdf.wasCanceled()) return false;
......@@ -902,6 +921,10 @@ public class ComboMatch {
flt_min_rms = gdf.getNextNumber();
flt_max_rms = gdf.getNextNumber();
flt_nan_rms = gdf.getNextBoolean();
flt_filt_zoom = gdf.getNextBoolean();
flt_min_zoom =(int) gdf.getNextNumber();
flt_max_zoom =(int) gdf.getNextNumber();
flt_show_names = gdf.getNextBoolean();
flt_show_overlaps = gdf.getNextBoolean();
flt_show_rms = gdf.getNextBoolean();
......@@ -914,9 +937,13 @@ public class ComboMatch {
clt_parameters.imp.flt_min_rms = flt_min_rms;
clt_parameters.imp.flt_max_rms = flt_max_rms;
clt_parameters.imp.flt_nan_rms = flt_nan_rms;
clt_parameters.imp.flt_filt_zoom = flt_filt_zoom;
clt_parameters.imp.flt_min_zoom = flt_min_zoom;
clt_parameters.imp.flt_max_zoom = flt_max_zoom;
clt_parameters.imp.flt_show_names = flt_show_names;
clt_parameters.imp.flt_show_overlaps = flt_show_overlaps;
clt_parameters.imp.flt_show_rms = flt_show_rms;
clt_parameters.imp.flt_show_zoom = flt_show_zoom;
}
if (flt_list) {
......@@ -927,7 +954,10 @@ public class ComboMatch {
flt_max_overlap, // double max_overlap,
flt_min_rms, // double min_rms,
flt_max_rms, // double max_rms,
flt_nan_rms); // boolean nan_rms)
flt_nan_rms, // boolean nan_rms)
flt_filt_zoom, // boolean filt_zoom,
flt_min_zoom, // int min_zoom,
flt_max_zoom); // int max_zoom)
}
String [] choices_all = maps_collection.textPairs (
......@@ -935,18 +965,8 @@ public class ComboMatch {
flt_show_names, // boolean show_names,
flt_show_overlaps, // boolean show_overlap,
flt_show_rms, // boolean show_rms,
flt_show_zoom, // boolean show_zoom,
flt_extra_line); // String extra_line)
/*
String [] choices = getPairChoices(
available_pairs, // int [][] pairs,
names); // String [] names)
String [] choices_all = new String[choices.length+1];
System.arraycopy(choices, 0, choices_all, 0, choices.length);
choices_all[choices_all.length-1] = "--- select a single image ---";
*/
GenericJTabbedDialog gdc = new GenericJTabbedDialog("Select image pair",1200,100);
int num_choice_lines = 50;
......@@ -1220,6 +1240,9 @@ public class ComboMatch {
}
return true;
}
public static PairwiseOrthoMatch initialPairAdjust(
CLTParameters clt_parameters,
OrthoMapsCollection maps_collection,
......
......@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
......@@ -5131,6 +5132,277 @@ public class OrthoMapsCollection implements Serializable{
return true;
}
/**
* Add new scene pairs from the already adjusted scenes
* @param clt_parameters
* @param orthoMapsCollection_path
* @return
*/
public boolean augmentPairwiseAffines(
CLTParameters clt_parameters,
String orthoMapsCollection_path) {
// Create list of all pairs (after recreating all overlaps with updated affines)
ArrayList<Point> pairs_list = new ArrayList<Point>();
for (OrthoMap map : ortho_maps) {
for (String other_name: map.pairwise_matches.keySet()) {
pairs_list.add(new Point(
getIndex(map.getName()),
getIndex(other_name)));
}
}
// sort pairs_list by x then y
Collections.sort(pairs_list, new Comparator<Point>() {
@Override
public int compare(Point lhs, Point rhs) {
return (rhs.x > lhs.x) ? -1 : (rhs.x < lhs.x) ? 1 :
((rhs.y > lhs.y) ? -1 : (rhs.y < lhs.y) ? 1 : 0); // increasing
}
});
// convert ArrayList<Point> to array int[][]
int [][] available_pairs = new int [pairs_list.size()][2];
for (int i = 0; i < available_pairs.length; i++) {
available_pairs[i][0] = pairs_list.get(i).x;
available_pairs[i][1] = pairs_list.get(i).y;
}
boolean flt_undef_only = false; // clt_parameters.imp.flt_undef_only; // false;
double flt_min_overlap = clt_parameters.imp.flt_min_overlap; // 0.0;
double flt_max_overlap = clt_parameters.imp.flt_max_overlap; // 1.0;
double flt_min_rms = 0; // clt_parameters.imp.flt_min_rms; // 0.0;
double flt_max_rms = 2.0; // clt_parameters.imp.flt_max_rms; // 2.0;
boolean flt_filt_zoom = clt_parameters.imp.flt_filt_zoom; // true;
int flt_min_zoom = clt_parameters.imp.flt_min_zoom; // -2;
int flt_max_zoom = clt_parameters.imp.flt_max_zoom; // 10;
boolean flt_nan_rms = true; // clt_parameters.imp.flt_nan_rms; // false;
boolean flt_show_names = true; // clt_parameters.imp.flt_show_names; // true;
boolean flt_show_overlaps = true; // clt_parameters.imp.flt_show_overlaps; // true;
boolean flt_show_rms = true; // clt_parameters.imp.flt_show_rms; // true;
boolean flt_show_zoom = true; // clt_parameters.imp.flt_show_zoom; // true;
//Initial spiral search for image matching
boolean ospir_augment = clt_parameters.imp.ospir_augment; // true
double max_rms = clt_parameters.imp.ospir_max_rms; // 0.35; //
double max_rms_refine = clt_parameters.imp.pwise_max_rms; // 0.35; //
int min_overlap_tiles = clt_parameters.imp.ospir_overlap; // 3000; // do not try to match if there is too small overlap (scaled pixels)
double double_threshold = clt_parameters.imp.ospir_double; // increase resolution if too small overlap in tiles
int num_iter_lma = clt_parameters.imp.ospir_num_iter; // 5;
double [] max_rms_iter = clt_parameters.imp.ospir_rms_iter; // {1.0, 0.6};//
boolean lores_ignore_rms = clt_parameters.imp.ospir_ignore_rms; // false
//Final pairwise scenes matching
double frac_remove = clt_parameters.imp.pmtch_frac_remove;// 0.15;
double metric_err = clt_parameters.imp.pmtch_metric_err;// 0.05; // 0.02;// 2 cm
// boolean pmtch_use_affine = clt_parameters.imp.pmtch_use_affine;
double max_std = clt_parameters.imp.pmtch_max_std;// 1.5; // maximal standard deviation to limit center area
double min_std_rad = clt_parameters.imp.pmtch_min_std_rad;// 2.0; // minimal radius of the central area (if less - fail)
boolean ignore_prev_rms = clt_parameters.imp.pmtch_ignore_rms;// true;
int num_tries = clt_parameters.imp.pmtch_num_iter;// 10;
double rad_fraction = clt_parameters.imp.pmtch_cent_rad; // center circle radius fraction of 0.5* min(width, height) in tiles
double max_tile_rad = clt_parameters.imp.pmtch_max_cent_rad;// maximal center radius in tiles (limit pmtch_cent_rad)
double fill_fraction = clt_parameters.imp.pmtch_cent_fill; // should be populated not less than this
double fill_fraction_final = clt_parameters.imp.pmtch_cent_final; // should be populated not less than this during final pass
double ease_nosfm = clt_parameters.imp.pmtch_ease_nosfm; // ease metric_error when no SfM gain == 0;
int min_scene = 0;
double pull_skew = clt_parameters.imp.pmtch_pull_skew; // ~rotation, = 0 fraction of the total weight == 1
double pull_tilt = clt_parameters.imp.pmtch_pull_tilt; // > 0
double pull_scale = clt_parameters.imp.pmtch_pull_scale; // = 0
// log/save parameters
boolean save_each = clt_parameters.imp.pwise_save_each; // save state file after each match
boolean log_append = clt_parameters.imp.pwise_log_append; //
String log_path = clt_parameters.imp.pwise_log_path; //
int debugLevel = clt_parameters.imp.pwise_debug; //
boolean flt_update_config = false;
GenericJTabbedDialog gdf = new GenericJTabbedDialog("Select pairs filter/display",800,1100);
gdf.addMessage("Filter pairs parameters");
gdf.addNumericField("Minimal scene overlap (0..1)",flt_min_overlap, 3,7,"", "Minimal overlap of the scenes to keep (0-no overlap, 1.0 - smaller scene is inside the parger one.");
gdf.addNumericField("Maximal scene overlap (0..1)",flt_max_overlap, 3,7,"", "Maximal overlap of the scenes to keep (0-no overlap, 1.0 - smaller scene is inside the parger one.");
gdf.addCheckbox ("Filter by zoom level" , flt_filt_zoom, "Filter by the zoom level used for matching.");
gdf.addNumericField("Minimal zoom", flt_min_zoom, 0,3,"","Minimal zoom level used for matching.");
gdf.addNumericField("Maximal zoom", flt_max_zoom, 0,3,"","Maximal zoom level used for matching.");
gdf.addMessage("Low-resolution match parameters");
gdf.addCheckbox ("Use low-res in augmentation", ospir_augment, "Use low-res matching during augmenting (false - skip, go to high-res).");
gdf.addNumericField("Good RMSE, low-res", max_rms, 3,7,"scaled pix", "Maximal RMSE to consider match, in scaled pixels, during spiral.");
gdf.addNumericField("Good RMSE, final", max_rms_refine,3,7,"scaled pix", "Maximal RMSE to consider match, in scaled pixels, during refine.");
gdf.addNumericField("Minimal overlap", min_overlap_tiles, 0,4,"scaled pix ^ 2","Minimal overlap area in square scaled pixels.");
gdf.addNumericField("Mitigate small overlap", double_threshold, 3,7,"","For small overlaps increase zoom by 1 and range - twice.");
gdf.addNumericField("LMA iterations", num_iter_lma, 0,2,"", "Number of LMA iterations during spiral search.");
gdf.addNumericField("RMSE at first iteration", max_rms_iter[0], 3,7,"scaled pix","Maximal RMSE at first iteration.");
gdf.addNumericField("RMSE at second iteration", max_rms_iter[1], 3,7,"scaled pix","Maximal RMSE at second iteration.");
gdf.addCheckbox ("Ignore worsening low-res RMSE",lores_ignore_rms, "Ignore worsening/not improving RMSE low-res matching.");
gdf.addMessage ("Final (high-res) pairwise scenes matching");
gdf.addNumericField("Remove fraction of worst matches", frac_remove, 3,7,"", "When fitting scenes remove this fraction of worst match tiles.");
gdf.addNumericField("Maximal metric error", metric_err, 3,7,"m", "Maximal tolerable fitting error caused by elevation variations.");
// gdf.addCheckbox ("Use scenes' affine", pmtch_use_affine, "Use known scenes' affine matrices, false - start from scratch (unity) ones.");
gdf.addNumericField("Central area standard deviation", max_std, 3,7,"", "Central area limit by the standard deviation.");
gdf.addNumericField("Central area minimal radius", min_std_rad, 3,7,"tile", "Minimal radius of the central area after all LMA passes.");
gdf.addCheckbox ("Ignore previous RMSE", ignore_prev_rms, "Do not exit full fitting cycles if the RMSE worsened/not improved.");
gdf.addNumericField("Number of fitting iterations", num_tries, 0,3,"","number of full fittng iterations.");
gdf.addNumericField("Central area radius as fraction", rad_fraction, 3,7,"", "Central area radius as fraction of half minimal WOI dimension.");
gdf.addNumericField("Maximal central area radius", max_tile_rad, 3,7,"tiles", "Absolute limit to the center area radius (eases bad peripheral matching).");
gdf.addNumericField("Central area minimal fill", fill_fraction, 3,7,"", "Central area minimal fill for all but the last iteration.");
gdf.addNumericField("Central area minimal fill final", fill_fraction_final, 3,7,"", "Central area minimal fill for the last iteration.");
gdf.addNumericField("Relax metric error for no-SfM", ease_nosfm, 3,7,"", "Relax metric error for no-SfM scenes (sfm_gain==0).");
gdf.addNumericField("Pull skew (rotation)", pull_skew, 3,7,"", "Prevent pairwise match from rotation.");
gdf.addNumericField("Pull tilt", pull_tilt, 3,7,"", "Prevent pairwise match from tilt.");
gdf.addNumericField("Pull scale", pull_scale, 3,7,"", "Prevent pairwise match from scaling.");
gdf.addMessage("Log and Save, and Debug parameters");
gdf.addCheckbox ("Save state after each match", save_each, "Update state file after each match generation to mitigate possible crashes.");
gdf.addCheckbox ("Write log file", log_append, "Enable writing log file with matching results.");
gdf.addStringField ("Log file full path", log_path, 150, "Path of the log file to be appended.");
gdf.addNumericField("Debug level", debugLevel, 0,3,"","Debug level during Spiral search.");
gdf.addNumericField("Start scene (skip all earlier)", min_scene, 0,3,"","To be able to continue skipping some.");
gdf.addCheckbox ("Update configuration", flt_update_config, "Update matching configuration parameters to be saved as defaults.");
gdf.showDialog();
if (gdf.wasCanceled()) return false;
flt_min_overlap = gdf.getNextNumber();
flt_max_overlap = gdf.getNextNumber();
flt_filt_zoom = gdf.getNextBoolean();
flt_min_zoom = (int) gdf.getNextNumber();
flt_max_zoom = (int) gdf.getNextNumber();
ospir_augment = gdf.getNextBoolean();
max_rms = gdf.getNextNumber();
max_rms_refine = gdf.getNextNumber();
min_overlap_tiles = (int) gdf.getNextNumber();
double_threshold = gdf.getNextNumber();
num_iter_lma = (int) gdf.getNextNumber();
max_rms_iter[0] = gdf.getNextNumber();
max_rms_iter[1] = gdf.getNextNumber();
lores_ignore_rms = gdf.getNextBoolean();
frac_remove = gdf.getNextNumber();
metric_err = gdf.getNextNumber();
// pmtch_use_affine= gdf.getNextBoolean();
max_std = gdf.getNextNumber();
min_std_rad = gdf.getNextNumber();
ignore_prev_rms = gdf.getNextBoolean();
num_tries = (int) gdf.getNextNumber();
rad_fraction = gdf.getNextNumber();
max_tile_rad = gdf.getNextNumber();
fill_fraction = gdf.getNextNumber();
fill_fraction_final= gdf.getNextNumber();
ease_nosfm = gdf.getNextNumber();
pull_skew = gdf.getNextNumber();
pull_tilt = gdf.getNextNumber();
pull_scale = gdf.getNextNumber();
save_each = gdf.getNextBoolean();
log_append = gdf.getNextBoolean();
log_path = gdf.getNextString();
debugLevel = (int) gdf.getNextNumber();
min_scene = (int) gdf.getNextNumber();
flt_update_config = gdf.getNextBoolean();
if (flt_update_config) {
clt_parameters.imp.flt_min_overlap = flt_min_overlap;
clt_parameters.imp.flt_max_overlap = flt_max_overlap;
clt_parameters.imp.flt_filt_zoom = flt_filt_zoom;
clt_parameters.imp.flt_min_zoom = flt_min_zoom;
clt_parameters.imp.flt_max_zoom = flt_max_zoom;
clt_parameters.imp.ospir_augment = ospir_augment;
clt_parameters.imp.ospir_max_rms = max_rms;
clt_parameters.imp.pwise_max_rms = max_rms_refine;
clt_parameters.imp.ospir_overlap = min_overlap_tiles;
clt_parameters.imp.ospir_double = double_threshold;
clt_parameters.imp.ospir_num_iter = num_iter_lma;
clt_parameters.imp.ospir_rms_iter = max_rms_iter;
clt_parameters.imp.ospir_ignore_rms = lores_ignore_rms;
clt_parameters.imp.pmtch_frac_remove = frac_remove;
clt_parameters.imp.pmtch_metric_err = metric_err;
// clt_parameters.imp.pmtch_use_affine = pmtch_use_affine;
clt_parameters.imp.pmtch_max_std = max_std;
clt_parameters.imp.pmtch_min_std_rad = min_std_rad;
clt_parameters.imp.pmtch_ignore_rms = ignore_prev_rms;
clt_parameters.imp.pmtch_num_iter = num_tries;
clt_parameters.imp.pmtch_cent_rad = rad_fraction;
clt_parameters.imp.pmtch_max_cent_rad = max_tile_rad;
clt_parameters.imp.pmtch_cent_fill = fill_fraction;
clt_parameters.imp.pmtch_cent_final = fill_fraction_final;
clt_parameters.imp.pmtch_ease_nosfm = ease_nosfm;
clt_parameters.imp.pmtch_pull_skew = pull_skew;
clt_parameters.imp.pmtch_pull_tilt = pull_tilt;
clt_parameters.imp.pmtch_pull_scale = pull_scale;
clt_parameters.imp.pwise_save_each = save_each;
clt_parameters.imp.pwise_log_append = log_append;
clt_parameters.imp.pwise_log_path = log_path;
clt_parameters.imp.pwise_debug = debugLevel;
}
available_pairs = filterPairs(
available_pairs, // int [][] plist_in,
flt_undef_only, // boolean undef_only,
flt_min_overlap, // double min_overlap,
flt_max_overlap, // double max_overlap,
flt_min_rms, // double min_rms,
flt_max_rms, // double max_rms,
flt_nan_rms, // boolean nan_rms)
flt_filt_zoom, // boolean filt_zoom,
flt_min_zoom, // int min_zoom,
flt_max_zoom); // int max_zoom)
String [] choices_all = textPairs (
available_pairs, // int [][] plist,
flt_show_names, // boolean show_names,
flt_show_overlaps, // boolean show_overlap,
flt_show_rms, // boolean show_rms,
flt_show_zoom, // boolean show_zoom,
null); // String extra_line)
if (debugLevel > 0) {
System.out.println("Selected "+available_pairs.length+" scene pairs for matching");
for (int i = 0; i < available_pairs.length; i++) {
System.out.println(String.format("%4d:%s",i,choices_all[i]));
}
}
if (available_pairs.length == 0) {
return false;
}
return augmentPairwiseAffines(
clt_parameters, // CLTParameters clt_parameters,
available_pairs, // int [][] available_pairs,
//Initial spiral search for image matching
ospir_augment, // boolean ospir_augment,
max_rms, // double max_rms,
max_rms_refine, // double max_rms_refine,
min_overlap_tiles, // int min_overlap_tiles,
double_threshold, // double double_threshold,
num_iter_lma, // int num_iter_lma,
max_rms_iter, // double [] max_rms_iter,
lores_ignore_rms, // boolean lores_ignore_rms
//Final pairwise scenes matching
frac_remove, // double frac_remove,
metric_err, // double metric_error,
// pmtch_use_affine, // boolean pmtch_use_affine,
max_std, // double max_std,
min_std_rad, // double min_std_rad,
ignore_prev_rms, // boolean ignore_prev_rms,
num_tries, // int num_tries,
rad_fraction, // double rad_fraction,
max_tile_rad, // double max_tile_rad,
fill_fraction, // double fill_fraction,
fill_fraction_final, // double fill_fraction_final,
ease_nosfm, // double ease_nosfm,
min_scene, // int min_scene,
pull_skew, // double pull_skew,
pull_tilt, // double pull_tilt,
pull_scale, // double pull_scale,
// log/save parameters
save_each, // boolean save_each,
log_append, // boolean log_append,
log_path, // String log_path,
orthoMapsCollection_path, // String orthoMapsCollection_path
debugLevel); // int debugLevel)
}
public boolean generatePairwiseAffines(
CLTParameters clt_parameters,
String orthoMapsCollection_path) {
......@@ -5168,10 +5440,6 @@ public class OrthoMapsCollection implements Serializable{
}
boolean dry_run = false;
/// boolean skip_exist = clt_parameters.imp.pwise_skip_exist; //
/// boolean refine_exist = clt_parameters.imp.pwise_refine_exist; // if false, start from scratch, true - start from previous
/// boolean delete_failed = clt_parameters.imp.pwise_delete_fail; // delete existing match if now failed
/// boolean gen_inverse = clt_parameters.imp.pwise_gen_inverse; // generate inverse matches
boolean save_each = clt_parameters.imp.pwise_save_each; // save state file after each match
boolean log_append = clt_parameters.imp.pwise_log_append; //
String log_path = clt_parameters.imp.pwise_log_path; //
......@@ -5211,7 +5479,6 @@ public class OrthoMapsCollection implements Serializable{
double pull_tilt = clt_parameters.imp.pmtch_pull_tilt; // > 0
double pull_scale = clt_parameters.imp.pmtch_pull_scale; // = 0
// double max_rmse_reuse = 0.35;
boolean use_multi = true;
int heur = 15;
int min_scene = 0;
......@@ -5268,7 +5535,7 @@ public class OrthoMapsCollection implements Serializable{
gd.addNumericField("Start scene (skip all earlier)", min_scene, 0,3,"","To be able to continue skipping some.");
gd.addNumericField("Heuristics bitmap", heur, 0,3,"","Bitmap of modes to suggest the next pair.");
gd.addCheckbox ("Use multiple threads", use_multi, "Use multipl tghreads (may be disabled in debug mode).");
gd.addCheckbox ("Use multiple threads", use_multi, "Use multiple threads (may be disabled in debug mode).");
//
gd.showDialog();
......@@ -5416,6 +5683,287 @@ public class OrthoMapsCollection implements Serializable{
}
}
public boolean augmentPairwiseAffines(
CLTParameters clt_parameters,
int [][] available_pairs,
//Initial spiral search for image matching
boolean ospir_augment,
double max_rms,
double max_rms_refine,
int min_overlap_tiles,
double double_threshold,
int num_iter_lma,
double [] max_rms_iter,
boolean lores_ignore_rms,
//Final pairwise scenes matching
double frac_remove,
double metric_error,
double max_std,
double min_std_rad,
boolean ignore_prev_rms,
int num_tries,
double rad_fraction,
double max_tile_rad,
double fill_fraction,
double fill_fraction_final,
double ease_nosfm,
int min_scene,
double pull_skew,
double pull_tilt,
double pull_scale,
// log/save parameters
boolean save_each,
boolean log_append,
String log_path,
String orthoMapsCollection_path,
int debugLevel) {
boolean batch_mode = true;
boolean show_vf = false;
double [][] ground_planes = null; // null or double[2] - will return ground planes:
if (log_append && (log_path != null)) { // assuming directory exists
StringBuffer sb = new StringBuffer();
sb.append(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+"\n");
sb.append("number of scenes pairs\t"+ available_pairs.length+"\n");
sb.append(String.format("%4s\t%4s\t%17s\t%17s\t%6s\t%3s\t%6s\t%6s\t%7s\n",
"scn1","scn2","timestamp1","timestamp2","ovrlp","zl","RMS-sp","RMSfin","fzl","removed"));
CalibrationFileManagement.saveStringToFile (
log_path, //String path,
sb.toString(), // data,
true); // boolean append)
if (debugLevel>-3) {
System.out.print(sb.toString());
}
}
int num_pairs = 0; // available_pairs.length
ArrayList<Point> failed_pairs = new ArrayList<Point>();
for (int npair = 0; npair < available_pairs.length; npair++) {
int [] ipair = available_pairs[npair];
PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[ipair[0]].getMatch(ortho_maps[ipair[1]].getName(), true);
double [][] daffine = null;
if (pairwiseOrthoMatch != null) {
double [][] aff0 = ortho_maps[ipair[0]].getAffine();
double [][] aff1 = ortho_maps[ipair[1]].getAffine();
double [] enuOffset = ortho_maps[ipair[1]].enuOffsetTo(ortho_maps[ipair[0]]);
double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image
PairwiseOrthoMatch aff_match = new PairwiseOrthoMatch (
aff0, // double [][] affine0,
aff1, // double [][] affine1,
rd); // double [] rd);
daffine = aff_match.getAffine();
pairwiseOrthoMatch.setAffine(daffine);
} else {
System.out.println("BUG: Missing pair for ["+ipair[0]+", "+ipair[1]+"] ");
continue;
}
if (ipair[0] < min_scene) {
System.out.println ("Skipping "+ipair[0]+":"+ipair[1]+" until "+min_scene);
continue;
}
// only do low-res if ospir_augment
// boolean direct = ipair[0] < ipair[1]; // always?
int min_zoom_lev = ortho_maps[ipair[0]].getOriginalZoomLevel();
int max_zoom_lev = ortho_maps[ipair[0]].getOriginalZoomLevel();
double max_agl = ortho_maps[ipair[0]].getAGL();
for (int i = 0; i < ipair.length; i++) {
max_agl = Math.max(max_agl, ortho_maps[ipair[i]].getAGL());
min_zoom_lev = Math.min(min_zoom_lev, ortho_maps[ipair[i]].getOriginalZoomLevel());
max_zoom_lev = Math.max(max_zoom_lev, ortho_maps[ipair[i]].getOriginalZoomLevel());
}
double agl_ratio = max_agl/50.0;
double metric_error_adj = metric_error * agl_ratio * agl_ratio; // metric_error settings is good for 50m. Increase for higher Maybe squared?
int initial_zoom = max_zoom_lev - 4; // another algorithm?
// overlaps
double overlap_frac = pairwiseOrthoMatch.getOverlap(); // .pairsGraph.getOverlap(next_pair);
double overlap_frac_mod = overlap_frac;
while (overlap_frac_mod < double_threshold) {
overlap_frac_mod *= 2;
initial_zoom += 1;
}
// unityAffine()
// use unityAffine() for 0; getaffine for second?
double [][] affine0 = unityAffine(); // ortho_maps[ipair[0]].getAffine();
double [][] affine1 = daffine; // ortho_maps[ipair[1]].getAffine();
double [][][] affines = new double[][][] {affine0,affine1};
boolean success = true;
Point pair = new Point(ipair[0],ipair[1]);
if (ospir_augment) {
correlateOrthoPair(
clt_parameters, // CLTParameters clt_parameters,
pairwiseOrthoMatch, // PairwiseOrthoMatch pairwiseOrthoMatch, // will return statistics
min_overlap_tiles, // int min_overlap,
max_std, // double max_std, // maximal standard deviation to limit center area
min_std_rad, // double min_std_rad, // minimal radius of the central area (if less - fail)
frac_remove, // double frac_remove, // = 0.25
metric_error_adj, // metric_error, // double metric_error,
lores_ignore_rms, // boolean ignore_prev_rms,
num_tries, // = 5int num_tries, // = 5
false, // boolean calc_warp, (will return null if false)
batch_mode, // boolean batch_mode,
ipair, // int [] gpu_pair,
affines, // double [][][] affines, // on top of GPS offsets
null, // woi, // Rectangle woi,
initial_zoom, // int zoom_lev,
show_vf, // boolean show_vf,
ground_planes, // double [][] ground_planes, // null or double[2] - will return ground planes
rad_fraction, // double rad_fraction,
max_tile_rad, // double max_tile_rad, // = 30;
fill_fraction, // double fill_fraction,
fill_fraction_final,// double fill_fraction_final,
ease_nosfm, // double ease_nosfm,
max_rms_iter, // double [] max_rms_iter, // = {1.0, 0.6};//
pull_skew, // double pull_skew, // ~rotation, = 0 fraction of the total weight == 1
pull_tilt, // double pull_tilt, // > 0
pull_scale, // double pull_scale, // = 0
debugLevel-4); // final int debugLevel)
pairwiseOrthoMatch.setAffine(affines[1]); // modified by correlateOrthoPair ALREADY SET
if (debugLevel > -4) {
System.out.println(String.format("Low-res Match(): %3d-%3d RMSE=%8.6f",
ipair[0], ipair[1], pairwiseOrthoMatch.rms)); // if NaN - provide reason
}
if (pairwiseOrthoMatch.rms < max_rms) {
pairwiseOrthoMatch.ok = true;
}
success &= pairwiseOrthoMatch.ok; // && !Double.isNaN(pairwiseOrthoMatch.rms)
if (!success) {
String str_failed = "%4d\t%4d\t%s\t%s\t%6.4f\t%3d\t%6.4f\tFAILED\n";
if (log_append && (log_path != null)) { // assuming directory exists
StringBuffer sb = new StringBuffer();
sb.append(String.format(str_failed,
ipair[0], ipair[1], ortho_maps[ipair[0]].getName(), ortho_maps[ipair[1]].getName(),
overlap_frac, initial_zoom,
// pairwiseOrthoMatch.nxy[0],pairwiseOrthoMatch.nxy[1],
pairwiseOrthoMatch.rms));
CalibrationFileManagement.saveStringToFile (
log_path, //String path,
sb.toString(), // data,
true); // boolean append)
}
failed_pairs.add(pair);
continue;
}
} // if (ospir_augment) {
// PairwiseOrthoMatch pairwiseOrthoMatch_lores = pairwiseOrthoMatch.clone();
double lores_rms = pairwiseOrthoMatch.getRMS();
// high-res
affines[1][0] = affines[1][0].clone();
affines[1][1] = affines[1][1].clone();
Rectangle woi = new Rectangle(); // used to return actual woi from correlateOrthoPair()
correlateOrthoPair(
clt_parameters, // CLTParameters clt_parameters,
pairwiseOrthoMatch, //PairwiseOrthoMatch pairwiseOrthoMatch, // will return statistics
0, // int min_overlap,
max_std, // double max_std, // maximal standard deviation to limit center area
min_std_rad, // double min_std_rad, // minimal radius of the central area (if less - fail)
frac_remove, // double frac_remove, // = 0.25
metric_error_adj,// double metric_error,
ignore_prev_rms, // boolean ignore_prev_rms,
num_tries, // = 5int num_tries, // = 5
false, // , // boolean calc_warp, (will return null if false)
batch_mode, // boolean batch_mode,
ipair, // String [] gpu_spair,
affines, // double [][][] affines, // on top of GPS offsets
woi, // Rectangle woi,
min_zoom_lev, // int zoom_lev,
false, // show_vf, // boolean show_vf,
null, // ground_planes, // double [][] ground_planes, // null or double[2] - will return ground planes
rad_fraction, // double rad_fraction,
max_tile_rad, // double max_tile_rad, // = 30;
fill_fraction, // double fill_fraction,
fill_fraction_final, // double fill_fraction_final,
ease_nosfm, // double ease_nosfm,