Commit 7ad0875e authored by Andrey Filippov's avatar Andrey Filippov

Matching altitudes

parent 1cc6d251
...@@ -114,6 +114,7 @@ public class DoubleGaussianBlur { ...@@ -114,6 +114,7 @@ public class DoubleGaussianBlur {
* @param extraLines Number of lines (parallel to the blurring direction) * @param extraLines Number of lines (parallel to the blurring direction)
* below and above the roi bounds that should be processed. * below and above the roi bounds that should be processed.
*/ */
// TODO: Make threaded!
public void blur1Direction(double [] pixels, public void blur1Direction(double [] pixels,
int width, int width,
int height, int height,
......
...@@ -11,6 +11,8 @@ import java.util.Arrays; ...@@ -11,6 +11,8 @@ import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
import java.util.Random; import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
...@@ -27,6 +29,7 @@ import com.elphel.imagej.gpu.TpTask; ...@@ -27,6 +29,7 @@ import com.elphel.imagej.gpu.TpTask;
import com.elphel.imagej.ims.Imx5; import com.elphel.imagej.ims.Imx5;
import com.elphel.imagej.readers.ElphelTiffReader; import com.elphel.imagej.readers.ElphelTiffReader;
import com.elphel.imagej.tileprocessor.ImageDtt; import com.elphel.imagej.tileprocessor.ImageDtt;
import com.elphel.imagej.tileprocessor.IntersceneMatchParameters;
import com.elphel.imagej.tileprocessor.OpticalFlow; import com.elphel.imagej.tileprocessor.OpticalFlow;
import com.elphel.imagej.tileprocessor.QuadCLT; import com.elphel.imagej.tileprocessor.QuadCLT;
import com.elphel.imagej.tileprocessor.TDCorrTile; import com.elphel.imagej.tileprocessor.TDCorrTile;
...@@ -166,10 +169,13 @@ public class ComboMatch { ...@@ -166,10 +169,13 @@ public class ComboMatch {
boolean create_pairwise_affines = false; boolean create_pairwise_affines = false;
boolean augment_pairwise_affines = false; // needs to repeat create_pairwise_matches to update overlaps boolean augment_pairwise_affines = false; // needs to repeat create_pairwise_matches to update overlaps
boolean equalize_overlaps = false; boolean equalize_overlaps = false;
boolean altitude_match_pairs = false;
boolean display_pairs = false;
boolean create_map = false; boolean create_map = false;
boolean create_equalize = false; boolean create_equalize = false;
boolean use_saved_collection = true; // false; boolean use_saved_collection = true; // false;
boolean save_collection = true; boolean save_collection = true;
boolean process_correlation = true; // use false to save new version of data boolean process_correlation = true; // use false to save new version of data
...@@ -187,6 +193,7 @@ public class ComboMatch { ...@@ -187,6 +193,7 @@ public class ComboMatch {
boolean update_lla = false; // re-read file metadata boolean update_lla = false; // re-read file metadata
boolean update_kernel_patterns = false; boolean update_kernel_patterns = false;
boolean update_bl_bc = false; boolean update_bl_bc = false;
boolean fix_duplicates = false;
String [] suffixes_bl_bc= {"","-BL","-BC"}; String [] suffixes_bl_bc= {"","-BL","-BC"};
boolean log_append = clt_parameters.imp.pwise_log_append; boolean log_append = clt_parameters.imp.pwise_log_append;
String log_path = clt_parameters.imp.pwise_log_path; String log_path = clt_parameters.imp.pwise_log_path;
...@@ -232,6 +239,8 @@ public class ComboMatch { ...@@ -232,6 +239,8 @@ public class ComboMatch {
gd.addCheckbox ("Create pairwise affines", create_pairwise_affines, "Create affines for scene pairs."); 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 ("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 ("Equalize overlap pairs", equalize_overlaps, "Equalize intensities in overlaps.");
gd.addCheckbox ("Altitude match pairs", altitude_match_pairs, "Pairwise match scenes altitude.");
gd.addCheckbox ("Display pairs", display_pairs, "Display pairwise match data.");
gd.addCheckbox ("Create map", create_map, "Create combined map from pairwise matches."); 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."); gd.addCheckbox ("Equalize intensities", create_equalize, "Create map intensities equalization from pairwise matches.");
gd.addNumericField("Remove fraction of worst matches", frac_remove, 3,7,"", "When fitting scenes remove this fraction of worst match."); gd.addNumericField("Remove fraction of worst matches", frac_remove, 3,7,"", "When fitting scenes remove this fraction of worst match.");
...@@ -241,6 +250,8 @@ public class ComboMatch { ...@@ -241,6 +250,8 @@ public class ComboMatch {
} }
gd.addCheckbox ("Update files metadata", update_lla, "Re-read files metadata (if it was modified)"); gd.addCheckbox ("Update files metadata", update_lla, "Re-read files metadata (if it was modified)");
gd.addCheckbox ("Update kernels/patterns", update_kernel_patterns, "Re-read kernels and patterns from *.list file"); gd.addCheckbox ("Update kernels/patterns", update_kernel_patterns, "Re-read kernels and patterns from *.list file");
gd.addCheckbox ("Remove duplicate scenes", fix_duplicates, "Remove scenes with the same timestamp");
gd.addCheckbox ("Update BC/BL suffix", update_bl_bc, gd.addCheckbox ("Update BC/BL suffix", update_bl_bc,
"Change source filenames to use -BC for bicubic, -BL - for bilinear, or empty - for old bilinear files"); "Change source filenames to use -BC for bicubic, -BL - for bilinear, or empty - for old bilinear files");
gd.addChoice("BL/BC suffix:", gd.addChoice("BL/BC suffix:",
...@@ -284,6 +295,8 @@ public class ComboMatch { ...@@ -284,6 +295,8 @@ public class ComboMatch {
create_pairwise_affines = gd.getNextBoolean(); create_pairwise_affines = gd.getNextBoolean();
augment_pairwise_affines = gd.getNextBoolean(); augment_pairwise_affines = gd.getNextBoolean();
equalize_overlaps = gd.getNextBoolean(); equalize_overlaps = gd.getNextBoolean();
altitude_match_pairs = gd.getNextBoolean();
display_pairs = gd.getNextBoolean();
create_map = gd.getNextBoolean(); create_map = gd.getNextBoolean();
create_equalize = gd.getNextBoolean(); create_equalize = gd.getNextBoolean();
frac_remove = gd.getNextNumber(); frac_remove = gd.getNextNumber();
...@@ -293,6 +306,7 @@ public class ComboMatch { ...@@ -293,6 +306,7 @@ public class ComboMatch {
} }
update_lla= gd.getNextBoolean(); update_lla= gd.getNextBoolean();
update_kernel_patterns= gd.getNextBoolean(); update_kernel_patterns= gd.getNextBoolean();
fix_duplicates= gd.getNextBoolean();
update_bl_bc= gd.getNextBoolean(); update_bl_bc= gd.getNextBoolean();
suffix_bc_bl_indx = gd.getNextChoiceIndex(); suffix_bc_bl_indx = gd.getNextChoiceIndex();
log_append = gd.getNextBoolean(); log_append = gd.getNextBoolean();
...@@ -325,6 +339,9 @@ public class ComboMatch { ...@@ -325,6 +339,9 @@ public class ComboMatch {
maps_collection.updateNumberScenes(); maps_collection.updateNumberScenes();
maps_collection.updateSfmGain(); maps_collection.updateSfmGain();
} }
if (fix_duplicates) {
removeDuplicateScenes (maps_collection);
}
if (update_bl_bc) { if (update_bl_bc) {
boolean OK = updateBlBcFileNames( boolean OK = updateBlBcFileNames(
...@@ -826,6 +843,19 @@ public class ComboMatch { ...@@ -826,6 +843,19 @@ public class ComboMatch {
return ok; // Just exit, do not try other commands. if (!ok) return false; return ok; // Just exit, do not try other commands. if (!ok) return false;
} }
if (altitude_match_pairs) {
boolean ok =maps_collection.altutudeMatchPairs(
clt_parameters, // CLTParameters clt_parameters,
orthoMapsCollection_savepath); // String orthoMapsCollection_path);
return ok; // Just exit, do not try other commands. if (!ok) return false;
}
if (display_pairs) {
boolean ok =maps_collection.displayScenePairs(
clt_parameters, // CLTParameters clt_parameters,
orthoMapsCollection_savepath); // String orthoMapsCollection_path);
return ok; // Just exit, do not try other commands. if (!ok) return false;
}
if (process_correlation || render_match || pattern_match || test_multi_lma) { if (process_correlation || render_match || pattern_match || test_multi_lma) {
// int [] gpu_pair; // int [] gpu_pair;
if (gpu_spair == null) { if (gpu_spair == null) {
...@@ -864,11 +894,15 @@ public class ComboMatch { ...@@ -864,11 +894,15 @@ public class ComboMatch {
boolean flt_filt_zoom = clt_parameters.imp.flt_filt_zoom; // true; boolean flt_filt_zoom = clt_parameters.imp.flt_filt_zoom; // true;
int flt_min_zoom = clt_parameters.imp.flt_min_zoom; // -2; int flt_min_zoom = clt_parameters.imp.flt_min_zoom; // -2;
int flt_max_zoom = clt_parameters.imp.flt_max_zoom; // 10; int flt_max_zoom = clt_parameters.imp.flt_max_zoom; // 10;
double flt_min_sfm = clt_parameters.imp.flt_min_sfm; // 0.0;
double flt_max_sfm = clt_parameters.imp.flt_max_sfm; //1000.0;
int flt_alt = clt_parameters.imp.flt_alt; // 0;
boolean flt_show_names = clt_parameters.imp.flt_show_names; // true; 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_overlaps = clt_parameters.imp.flt_show_overlaps; // true;
boolean flt_show_rms = clt_parameters.imp.flt_show_rms; // 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_show_zoom = clt_parameters.imp.flt_show_zoom; // true;
boolean flt_show_alt = clt_parameters.imp.flt_show_alt; // true;
boolean flt_update_config = false; boolean flt_update_config = false;
String flt_extra_line = "--- select a single image ---"; String flt_extra_line = "--- select a single image ---";
GenericJTabbedDialog gdf = new GenericJTabbedDialog("Select pairs filter/display",800,500); GenericJTabbedDialog gdf = new GenericJTabbedDialog("Select pairs filter/display",800,500);
...@@ -882,11 +916,16 @@ public class ComboMatch { ...@@ -882,11 +916,16 @@ public class ComboMatch {
gdf.addCheckbox ("Filter by zoom level" , flt_filt_zoom, "Filter by the zoom level used for matching."); 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("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.addNumericField("Maximal zoom", flt_max_zoom, 0,3,"","Maximal zoom level used for matching.");
gdf.addNumericField("Minimal SfM gain", flt_min_sfm, 3,7,"","Minimal SfM gain of the minimum in the scene pair.");
gdf.addNumericField("Maximal SfM gain", flt_max_sfm, 3,7,"","Maximal SfM gain of the minimum in the scene pair.");
gdf. addChoice("Filter by pairwise ALT availability",IntersceneMatchParameters.FLT_ALT_MODES, IntersceneMatchParameters.FLT_ALT_MODES[flt_alt],
"Filter by pairwise ALT availability.");
gdf.addCheckbox ("Show scene names", flt_show_names, "Show scene full names (timestamps) in selection drop-down list."); 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 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 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 ("Show zoom level", flt_show_zoom, "Show zoom level.");
gdf.addCheckbox ("Show ALT", flt_show_alt, "Show altitude data availability.");
gdf.addCheckbox ("Update configuration", flt_update_config, "Update matching configuration parameters to be saved as defaults."); gdf.addCheckbox ("Update configuration", flt_update_config, "Update matching configuration parameters to be saved as defaults.");
gdf.showDialog(); gdf.showDialog();
...@@ -901,11 +940,15 @@ public class ComboMatch { ...@@ -901,11 +940,15 @@ public class ComboMatch {
flt_filt_zoom = gdf.getNextBoolean(); flt_filt_zoom = gdf.getNextBoolean();
flt_min_zoom =(int) gdf.getNextNumber(); flt_min_zoom =(int) gdf.getNextNumber();
flt_max_zoom =(int) gdf.getNextNumber(); flt_max_zoom =(int) gdf.getNextNumber();
flt_min_sfm = gdf.getNextNumber();
flt_max_sfm = gdf.getNextNumber();
flt_alt = gdf.getNextChoiceIndex();
flt_show_names = gdf.getNextBoolean(); flt_show_names = gdf.getNextBoolean();
flt_show_overlaps = gdf.getNextBoolean(); flt_show_overlaps = gdf.getNextBoolean();
flt_show_rms = gdf.getNextBoolean(); flt_show_rms = gdf.getNextBoolean();
flt_show_zoom = gdf.getNextBoolean(); flt_show_zoom = gdf.getNextBoolean();
flt_show_alt = gdf.getNextBoolean();
flt_update_config = gdf.getNextBoolean(); flt_update_config = gdf.getNextBoolean();
if (flt_update_config) { if (flt_update_config) {
clt_parameters.imp.flt_list = flt_list; clt_parameters.imp.flt_list = flt_list;
...@@ -918,10 +961,14 @@ public class ComboMatch { ...@@ -918,10 +961,14 @@ public class ComboMatch {
clt_parameters.imp.flt_filt_zoom = flt_filt_zoom; clt_parameters.imp.flt_filt_zoom = flt_filt_zoom;
clt_parameters.imp.flt_min_zoom = flt_min_zoom; clt_parameters.imp.flt_min_zoom = flt_min_zoom;
clt_parameters.imp.flt_max_zoom = flt_max_zoom; clt_parameters.imp.flt_max_zoom = flt_max_zoom;
clt_parameters.imp.flt_min_sfm = flt_min_sfm;
clt_parameters.imp.flt_max_sfm = flt_max_sfm;
clt_parameters.imp.flt_alt = flt_alt;
clt_parameters.imp.flt_show_names = flt_show_names; clt_parameters.imp.flt_show_names = flt_show_names;
clt_parameters.imp.flt_show_overlaps = flt_show_overlaps; clt_parameters.imp.flt_show_overlaps = flt_show_overlaps;
clt_parameters.imp.flt_show_rms = flt_show_rms; clt_parameters.imp.flt_show_rms = flt_show_rms;
clt_parameters.imp.flt_show_zoom = flt_show_zoom; clt_parameters.imp.flt_show_zoom = flt_show_zoom;
clt_parameters.imp.flt_show_alt = flt_show_alt;
} }
if (flt_list) { if (flt_list) {
...@@ -935,7 +982,11 @@ public class ComboMatch { ...@@ -935,7 +982,11 @@ public class ComboMatch {
flt_nan_rms, // boolean nan_rms) flt_nan_rms, // boolean nan_rms)
flt_filt_zoom, // boolean filt_zoom, flt_filt_zoom, // boolean filt_zoom,
flt_min_zoom, // int min_zoom, flt_min_zoom, // int min_zoom,
flt_max_zoom); // int max_zoom) flt_max_zoom, // int max_zoom)
flt_min_sfm, // double min_sfm,
flt_max_sfm, // double max_sfm,
flt_alt); // int flt_alt)
} }
String [] choices_all = maps_collection.textPairs ( String [] choices_all = maps_collection.textPairs (
...@@ -944,6 +995,8 @@ public class ComboMatch { ...@@ -944,6 +995,8 @@ public class ComboMatch {
flt_show_overlaps, // boolean show_overlap, flt_show_overlaps, // boolean show_overlap,
flt_show_rms, // boolean show_rms, flt_show_rms, // boolean show_rms,
flt_show_zoom, // boolean show_zoom, flt_show_zoom, // boolean show_zoom,
flt_show_alt, // boolean show_alt,
false, // boolean use_tab,
flt_extra_line); // String extra_line) flt_extra_line); // String extra_line)
GenericJTabbedDialog gdc = new GenericJTabbedDialog("Select image pair",1200,100); GenericJTabbedDialog gdc = new GenericJTabbedDialog("Select image pair",1200,100);
...@@ -1399,6 +1452,77 @@ public class ComboMatch { ...@@ -1399,6 +1452,77 @@ public class ComboMatch {
return pairwiseOrthoMatch; return pairwiseOrthoMatch;
} }
public static boolean removeDuplicateScenes(
OrthoMapsCollection maps_collection) {
String duplicate_name=null;
do {
HashSet<String> scene_names = new HashSet<String>();
duplicate_name=null;
for (int i = 0; i < maps_collection.ortho_maps.length; i++) {
String name = maps_collection.ortho_maps[i].getName();
if (scene_names.contains(name)) {
duplicate_name=name;
break;
}
scene_names.add(name);
}
if (duplicate_name != null) {
long latest_modified = -1;
int latest_index = -1;
ArrayList<Integer> duplicates = new ArrayList<Integer>();
for (int i = 0; i < maps_collection.ortho_maps.length; i++) {
if (maps_collection.ortho_maps[i].getName().equals(duplicate_name)) {
duplicates.add(i);
long mod_ts = (new File(maps_collection.ortho_maps[i].getPath())).lastModified();
if (mod_ts > latest_modified) {
latest_index = i;
}
}
}
if (duplicates.size()> 1) {
System.out.println("removeDuplicateScenes(): found " +duplicates.size()+ " duplicates for scene "+duplicate_name+":");
for (int i :duplicates) {
System.out.println(((i==latest_index)?" KEEP ":"REMOVE ")+maps_collection.ortho_maps[i].getPath());
}
// combine pairwise matches, remove self-paired
HashMap <String, PairwiseOrthoMatch> combo_pairwise_matches = new HashMap <String, PairwiseOrthoMatch>();
OrthoMap [] new_maps = new OrthoMap[maps_collection.ortho_maps.length-duplicates.size()+1];
int indx = 0;
int new_indx = -1;
for (int i = 0; i < maps_collection.ortho_maps.length; i++) {
if (duplicates.contains(i)) {
for (String key:maps_collection.ortho_maps[i].pairwise_matches.keySet()) {
if (!key.equals(duplicate_name) && !combo_pairwise_matches.containsKey(key)) {
combo_pairwise_matches.put(key, maps_collection.ortho_maps[i].pairwise_matches.get(key));
}
}
}
if (!duplicates.contains(i) || (i == latest_index)) {
if (i == latest_index) {
new_indx = indx;
}
new_maps[indx++] = maps_collection.ortho_maps[i];
}
}
maps_collection.ortho_maps = new_maps;
maps_collection.ortho_maps[new_indx].pairwise_matches = combo_pairwise_matches;
// remove pairs with (now) itself
} else {
System.out.println("removeDuplicateScenes(): BUG - number of duplicates = "+duplicates.size()+", aborting.");
return false;
}
// find latest file
}
} while (duplicate_name != null);
maps_collection.reindex();
return true;
}
public static boolean updateBlBcFileNames( public static boolean updateBlBcFileNames(
String suffix, String suffix,
String before, String before,
......
/**
** OrthoAltitudeMatch - Represent elevation maps matching for pair of scenes
**
** Copyright (C) 2024 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** PairwiseOrthoMatch.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
package com.elphel.imagej.orthomosaic;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import com.elphel.imagej.calibration.CalibrationFileManagement;
import com.elphel.imagej.cameras.CLTParameters;
import ij.IJ;
public class OrthoAltitudeMatch {
public static boolean altutudeMatchPairs(
CLTParameters clt_parameters,
OrthoMapsCollection orthoMapsCollection,
int [][] available_pairs,
boolean alt_overwrite, // overwrite existing altitude match pairs
boolean alt_pairwise, // use pairwise affines if available
double alt_sigma, // 5.0; Reduce weight of the border tiles, Gaussian sigma in tiles to apply to weights.
double alt_abs_outliers, // = 3.0; // remove absolute outliers when fitting planes
double alt_outliers, // 0.05; Remove outliers when fitting planes, removed fraction.
int alt_refine, // 1; Refine altitude difference plane after removing outliers (0 - no outlier removal, 1 - remove outliers and refine once, ...)
double metric_error,
// log/save parameters
boolean save_each,
boolean log_append,
String log_path,
String orthoMapsCollection_path,
int debugLevel) {
int [] indices = orthoMapsCollection.getScenesFromPairs( // may be shorter, each element - absolute scene number used in pairs
available_pairs, // pairs_defined_abs,// int [][] pairs,
null); // int [] indices_in) // preselected indices or null
boolean updateStatus = true;
int [][] condensed_pairs = orthoMapsCollection.condensePairs (available_pairs, indices);
int alt_zoom_offs = -3; // altitude resolution is 3 steps lower than the images
if (indices.length < 2) {
System.out.println("too few scenes remain: "+indices.length);
return false;
}
OrthoMap[] ortho_maps = orthoMapsCollection.getMaps();
int min_zoom_all = ortho_maps[indices[0]].getOriginalZoomLevel();
int max_zoom_all = ortho_maps[indices[0]].getOriginalZoomLevel();
for (int i = 1; i < indices.length; i++) {
min_zoom_all = Math.min(min_zoom_all, ortho_maps[indices[i]].getOriginalZoomLevel());
max_zoom_all = Math.max(max_zoom_all, ortho_maps[indices[i]].getOriginalZoomLevel());
}
int alt_zoom_lev = Math.min(max_zoom_all+alt_zoom_offs, min_zoom_all);
double pix_size_meters = OrthoMap.getPixelSizeMeters(alt_zoom_lev);
if (debugLevel > 0 ) {
System.out.println("max_zoom="+max_zoom_all+ " min_zoom="+min_zoom_all+" alt_zoom_lev="+alt_zoom_lev);
}
int min_scene = 0; // use if needs to continue (during development)
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("number of scenes\t"+ indices.length+"\n");
sb.append("minimal zoom level\t"+ min_zoom_all+"\n");
sb.append("maximal zoom level\t"+ max_zoom_all+"\n");
sb.append("altitude zoom level\t"+ alt_zoom_lev+"\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"));
sb.append(String.format("%4s\t%4s\t%17s\t%17s\t%6s\t%3s\t%6s\t%7s\t%7s\t%7s\n",
"scn1","scn2","timestamp1","timestamp2","ovrlp","zl","RMS","tiltX","tiltY","offs"));
CalibrationFileManagement.saveStringToFile (
log_path, //String path,
sb.toString(), // data,
true); // boolean append)
if (debugLevel>-3) {
System.out.print(sb.toString());
}
}
// create altitude map
int [] wh = new int[2];
int [] origin = new int[2];
boolean show_centers = true;
boolean bounds_to_indices = true;
double [][] centers = show_centers? (new double [indices.length][]): null;
double [][] alt_multi = orthoMapsCollection.renderMultiDouble (
new double [indices.length][] , // double [][] ground_planes, // null - images, non-null altitudes. use new double[2][3] for old way alt
indices, // int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
bounds_to_indices, // boolean bounds_to_indices,
null, // affines, // double [][][] affines, // null or [indices.length][2][3]
null, // double [][] equalize,
true, // boolean ignore_equalize,
null, // warp, // FineXYCorr warp,,
alt_zoom_lev, // int zoom_level,
wh, // int [] wh,
origin, // int [] origin){ // maps[0] as a reference
centers); // double [][] centers)
final int width = wh[0];
// final int height = wh[1];
// int num_pairs = 0; // available_pairs.length
// ArrayList<Point> failed_pairs = new ArrayList<Point>();
for (int npair = 0; npair < condensed_pairs.length; npair++) {
int [] cpair = condensed_pairs[npair]; // index alt_multi
int [] ipair = {indices[cpair[0]], indices[cpair[1]]};
if (updateStatus) {
IJ.showStatus("Processing pair "+npair+" of "+condensed_pairs.length+" "+ipair[0]+"->"+ipair[1]);
}
/*
PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[ipair[0]].getMatch(ortho_maps[ipair[1]].getName(), true).clone(); // ?
double [][] daffine = null;
if (pairwiseOrthoMatch != null) {
double [] enuOffset = ortho_maps[ipair[1]].enuOffsetTo(ortho_maps[ipair[0]]);
double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image
daffine = pairwiseOrthoMatch.getAffine();
if ((daffine != null) && alt_pairwise) {
} else { // combine differential affine from individual
double [][] aff0 = ortho_maps[ipair[0]].getAffine();
double [][] aff1 = ortho_maps[ipair[1]].getAffine();
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;
}
*/
PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[ipair[0]].getMatch(ortho_maps[ipair[1]].getName(), true); // ?
if (pairwiseOrthoMatch == null) {
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;
}
if ((pairwiseOrthoMatch.getAltData() != null) && !alt_overwrite) {
System.out.println ("Skipping "+ipair[0]+":"+ipair[1]+" as it has alt_data defined and alt_overwrite == false .");
continue;
}
// pairwiseOrthoMatch is clone() - not anymore
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 [][] alt_slices = {alt_multi[cpair[0]], alt_multi[cpair[1]]};
Rectangle woi_overlap = OrthoMap.getDefinedBounds(
alt_slices, // final double [][] data_slices,
width); // final int width);
double [] diff_data = OrthoMap. subtractWoi(
alt_multi[cpair[0]], // final double [] data0,
alt_multi[cpair[1]], // final double [] data1,
width, // final int width,
woi_overlap); // Rectangle woi_in);
double [] xy0 = {0.5*woi_overlap.width, 0.5*woi_overlap.height};
double [] weight = null; // make it fading?
if (alt_sigma > 0) {
weight = OrthoMap.getBorderWeights(
diff_data, //final double [] data,
alt_sigma, // final double sigma,
woi_overlap.width); // int width)
}
boolean [] mask = null;
double [] alt_data5 = null;
int num_bins = 1000;
for (int ntry = 0; ntry <= alt_refine; ntry++) {
alt_data5 = OrthoMap.getPlane(
diff_data, // final double [] data,
mask, // final boolean [] mask,
weight, // final double [] weight,
woi_overlap.width, // final int width,
xy0); // final double [] xy0) {
if ((alt_outliers > 0) && (ntry < alt_refine)){ // not the last pass
mask = OrthoMap.removeRelativeLowHigh (
diff_data, // final double [] data,
null, // mask, // final boolean [] mask_in, // new mask for all data and latest plane
alt_abs_outliers, // final double abs_diff,
alt_outliers, // final double rel_frac,
alt_data5, // final double [] ground_plane, // tiltx,tilty, offs, x0(pix), y0(pix) or null
woi_overlap.width, // final int width, // only used with ground_plane != null;
num_bins); // final int num_bins)
} else {
break;
}
}
// double [] alt_data = new double[3];
// System.arraycopy(alt_data5, 0, alt_data, 0, alt_data.length);
double [] alt_data = {alt_data5[0]/pix_size_meters, alt_data5[1]/pix_size_meters,alt_data5[2]};
pairwiseOrthoMatch.setAltData(alt_data);
if (log_append && (log_path != null)) { // assuming directory exists
StringBuffer sb = new StringBuffer();
sb.append(String.format("%4d\t%4d\t%s\t%s\t%6.4f\t%3d\t%6.4f\t%7.4f\t%7.4f\t%7.3f\n",
ipair[0], ipair[1], ortho_maps[ipair[0]].getName(), ortho_maps[ipair[1]].getName(),
pairwiseOrthoMatch.overlap, pairwiseOrthoMatch.zoom_lev, pairwiseOrthoMatch.rms,
pairwiseOrthoMatch.alt_data[0],pairwiseOrthoMatch.alt_data[1],pairwiseOrthoMatch.alt_data[2]));
CalibrationFileManagement.saveStringToFile (
log_path, //String path,
sb.toString(), // data,
true); // boolean append)
}
//pix_size_meters
/*
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);
// unityAffine()
// use unityAffine() for 0; getaffine for second?
double [][] affine0 = OrthoMapsCollection.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]);
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,
null, // 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)
*/
}
if (orthoMapsCollection_path != null) {
try {
orthoMapsCollection.writeOrthoMapsCollection(orthoMapsCollection_path);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (debugLevel > -4) {
System.out.println("Saved data to "+ orthoMapsCollection_path);
}
}
return true;
}
}
...@@ -27,6 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -27,6 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.cameras.CLTParameters; import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.common.DoubleFHT; import com.elphel.imagej.common.DoubleFHT;
import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.GenericJTabbedDialog; import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.common.PolynomialApproximation; import com.elphel.imagej.common.PolynomialApproximation;
import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.common.ShowDoubleFloatArrays;
...@@ -3468,6 +3469,141 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -3468,6 +3469,141 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
return mask; return mask;
} }
/**
* Remove specified fractions (0 <= (rlow+rhigh) <= 1.0) of too low and too high values
* @param data double [] input data
* @param mask_in optional (may be null) mask for the data array. Will be modified if provided.
* @param abs_dif high limit of the histogram (reasonably higher than useful range of the data[])
* @param rel_frac fraction of the highest data[] elements to remove
* @param ground_plane null or {tilt_x, tilt_y, offs, x0,y0}, where tilt_x and tilt_y are per pixel.
* x0, y0 are also in pixels (not meters)
* @param width - width of the data[] array. Only used if ground_plane != null
* @param num_bins number of the histogram bins
* @return boolean array of the remaining data elements. Input mask_in array (if not null) is modified too.
*/
public static boolean [] removeRelativeLowHigh (
final double [] data,
final boolean [] mask_in,
final double abs_diff,
final double rel_frac,
final double [] ground_plane, // tiltx,tilty, offs, x0(pix), y0(pix) or null
final int width, // only used with ground_plane != null;
final int num_bins) {
final boolean [] mask = (mask_in == null) ? new boolean [data.length] : mask_in;
if (mask_in == null) {
Arrays.fill(mask, true);
}
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger ati = new AtomicInteger(0);
final double [][] hist2 = new double [threads.length][num_bins];
final double scale = num_bins/abs_diff;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int thread_num = ati.getAndIncrement();
for (int nPix = ai.getAndIncrement(); nPix < data.length; nPix = ai.getAndIncrement()) if (mask[nPix]){
double d = data[nPix];
if (!Double.isNaN(d)) {
if (ground_plane != null) {
double x = nPix % width - ground_plane[3];
double y = nPix/width - ground_plane[4];
double tilt_x = ground_plane[0];
double tilt_y = ground_plane[1];
double offs = ground_plane[2];
d -= x * tilt_x + y * tilt_y + offs;
}
int bin = Math.min(Math.max(((int) Math.round(Math.abs(d)*scale)), 0), num_bins-1);
hist2[thread_num][bin] += 1.0;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
final double [] hist = new double [num_bins];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int bin = ai.getAndIncrement(); bin < num_bins; bin = ai.getAndIncrement()) {
for (int i = 0; i < hist2.length; i++) {
hist[bin]+= hist2[i][bin];
}
}
}
};
}
ImageDtt.startAndJoin(threads);
double sw = 0;
for (int bin = 0; bin < num_bins; bin++) {
sw += hist[bin];
}
// double trlow = sw * rlow;
double trhigh = sw * rel_frac; // rhigh;
double sh = 0, shp = 0;
double threshold_high = abs_diff; // abs_high;
for (int bin = num_bins-1; bin>=0; bin--) {
shp = sh;
sh += hist[bin];
if (sh > trhigh) {
double r = (sh-trhigh)/(sh-shp);
threshold_high = (bin + r)/scale; // abs_low + (bin + r)/scale;
break;
}
}
sh = 0;
shp = 0;
/*
double threshold_low = abs_low;
for (int bin = 0; bin < num_bins; bin++) {
shp = sh;
sh += hist[bin];
if (sh > trlow) {
double r = (trlow-shp)/(sh-shp);
threshold_low = abs_low + (bin + r)/scale;
break;
}
}
final double fthreshold_low = threshold_low;
*/
final double fthreshold_high = threshold_high;
if (ground_plane == null) {
return removeAbsoluteLowHigh (
data, // final double [] data,
mask, // final boolean [] mask,
fthreshold_high, // final double threshold_high,
-fthreshold_high); // fthreshold_low); // final double threshold_low)
}
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// int thread_num = ati.getAndIncrement();
for (int nPix = ai.getAndIncrement(); nPix < data.length; nPix = ai.getAndIncrement()) if (mask[nPix]){
double d = data[nPix];
if (!Double.isNaN(d)) {
double x = nPix % width - ground_plane[3];
double y = nPix/width - ground_plane[4];
double tilt_x = ground_plane[0];
double tilt_y = ground_plane[1];
double offs = ground_plane[2];
d -= x * tilt_x + y * tilt_y + offs;
// if (!((d >= fthreshold_low) && (d <= fthreshold_high))) {
if (!((d >= -fthreshold_high) && (d <= fthreshold_high))) {
mask[nPix] = false;
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return mask;
}
/** /**
* Remove (mask out) tiles that have high product of distance (in pixels) from the vertical point * Remove (mask out) tiles that have high product of distance (in pixels) from the vertical point
* by the metric difference between the elevation and an approximation plane * by the metric difference between the elevation and an approximation plane
...@@ -3523,6 +3659,50 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -3523,6 +3659,50 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
return mask; return mask;
} }
public static double [] getBorderWeights(
final double [] data,
final double sigma,
int width) {
double [] weights = new double [data.length];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nPix = ai.getAndIncrement(); nPix < data.length; nPix = ai.getAndIncrement()){
weights[nPix] = Double.isNaN(data[nPix])? -1:1;
}
}
};
}
ImageDtt.startAndJoin(threads);
// TODO: Make threaded !
(new DoubleGaussianBlur()).blurDouble(
weights, // double[] pixels,
width, // int width,
weights.length/width, // int height,
sigma, // double sigmaX,
sigma, // double sigmaY,
0.01); // double accuracy);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nPix = ai.getAndIncrement(); nPix < data.length; nPix = ai.getAndIncrement()){
if (weights[nPix] < 0) {
weights[nPix] = 0;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return weights;
}
/** /**
...@@ -3534,12 +3714,13 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -3534,12 +3714,13 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
* @param xy0 a pair of x0, y0 - origin where the plane is referenced too * @param xy0 a pair of x0, y0 - origin where the plane is referenced too
* @return double array of {tiltx, tilty, offset, xy0[0] and xy0[1]). * @return double array of {tiltx, tilty, offset, xy0[0] and xy0[1]).
*/ */
private static double [] getPlane( public static double [] getPlane(
final double [] data, final double [] data,
final boolean [] mask, final boolean [] mask,
final double [] weight, final double [] weight,
final int width, final int width,
final double [] xy0) { final double [] xy0) {
int debug = -1;
final double [][][] mdatai = new double [data.length][][]; final double [][][] mdatai = new double [data.length][][];
AtomicInteger anum_good = new AtomicInteger(0); AtomicInteger anum_good = new AtomicInteger(0);
final Thread[] threads = ImageDtt.newThreadArray(); final Thread[] threads = ImageDtt.newThreadArray();
...@@ -3547,7 +3728,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -3547,7 +3728,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
public void run() { public void run() {
for (int nPix = ai.getAndIncrement(); nPix < data.length; nPix = ai.getAndIncrement()) if (mask[nPix]){ for (int nPix = ai.getAndIncrement(); nPix < data.length; nPix = ai.getAndIncrement()) if ((mask == null) || mask[nPix]){
double d = data[nPix]; double d = data[nPix];
if (!Double.isNaN(d)) { if (!Double.isNaN(d)) {
int x = nPix % width; int x = nPix % width;
...@@ -3577,11 +3758,40 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -3577,11 +3758,40 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
null, // damping, // double [] damping, null OK null, // damping, // double [] damping, null OK
-1); // debug level -1); // debug level
if (approx2d != null) { if (approx2d != null) {
if (debug > 0) {
double [] plane=new double[data.length];
double [] diff=new double[data.length];
double [] dweight = (weight != null) ? weight: new double[data.length];
double [] dmask = new double[data.length];
double [] masked = new double[data.length];
Arrays.fill(masked, Double.NaN);
for (int nPix = 0; nPix < plane.length; nPix++) {
int x = nPix % width;
int y = nPix / width;
double dx = x-xy0[0];
double dy = y-xy0[1];
plane[nPix] = approx2d[0][2]+approx2d[0][0]*dx+approx2d[0][1]*dy;
diff[nPix] = data[nPix]-plane[nPix];
dmask[nPix] = ((mask == null) || Double.isNaN(data[nPix]))? Double.NaN : (mask[nPix]?2:1);
if ((mask == null) || mask[nPix]) {
masked[nPix] = diff[nPix];
}
}
ShowDoubleFloatArrays.showArrays(
new double[][] {data,plane,diff,masked,dweight,dmask},
width,
data.length/width,
true,
"plane_approximation",
new String[] {"data","approx","diff","masked","weight","mask"});
}
return new double[] {approx2d[0][0], approx2d[0][1], approx2d[0][2], xy0[0], xy0[1]}; // tiltX, tiltY, offset return new double[] {approx2d[0][0], approx2d[0][1], approx2d[0][2], xy0[0], xy0[1]}; // tiltX, tiltY, offset
} }
return null; return null;
} }
/** /**
* Trying to estimate image OTF to modify correlation results. Some images are better, some - worse * Trying to estimate image OTF to modify correlation results. Some images are better, some - worse
* (blurred because of elevation errors)? For all image or parts of it? So on some images all * (blurred because of elevation errors)? For all image or parts of it? So on some images all
...@@ -5359,6 +5569,86 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ ...@@ -5359,6 +5569,86 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
return new double [] {beta, s,t, g_p_b}; return new double [] {beta, s,t, g_p_b};
} }
public static Rectangle getDefinedBounds(
final double [][] data_slices,
final int width) { // null or same length as data_slices[i]
final int height = data_slices[0].length/width;
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger ati = new AtomicInteger(0);
final int [][][] bounds = new int [threads.length][2][2]; // [thread][x/y][min/max]
for (int i = 0; i < bounds.length; i++) {
bounds[i][0][0] = width; // min x
bounds[i][1][0] = height;// min y
bounds[i][0][1] = -1; // max x
bounds[i][1][1] = -1; // max y
}
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int thread_num = ati.getAndIncrement();
for (int ipix = ai.getAndIncrement(); ipix < data_slices[0].length; ipix = ai.getAndIncrement()) {
pix_loop: {
for (int i = 0; i < data_slices.length; i++) {
if (Double.isNaN(data_slices[i][ipix])) {
break pix_loop;
}
}
int px = ipix % width;
int py = ipix / width;
if (px < bounds[thread_num][0][0]) bounds[thread_num][0][0] = px;
if (px > bounds[thread_num][0][1]) bounds[thread_num][0][1] = px;
if (py < bounds[thread_num][1][0]) bounds[thread_num][1][0] = py;
if (py > bounds[thread_num][1][1]) bounds[thread_num][1][1] = py;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
for (int i = 1; i < bounds.length; i++) {
for (int j = 0; j < 2; j++) {
bounds [0][j][0] = Math.min(bounds [0][j][0], bounds [i][j][0]);
bounds [0][j][1] = Math.max(bounds [0][j][1], bounds [i][j][1]);
}
}
Rectangle rbounds = new Rectangle(
bounds[0][0][0],
bounds [0][1][0],
bounds[0][0][1]-bounds[0][0][0]+1,
bounds[0][1][1]-bounds[0][1][0]+1);
return rbounds;
}
public static double [] subtractWoi(
final double [] data0,
final double [] data1,
final int width,
Rectangle woi_in) {
final int height = data0.length/width;
if (woi_in == null) {
woi_in =new Rectangle(0,0,width,height);
}
final Rectangle woi = new Rectangle(woi_in);
final int woi_len = woi.width*woi.height;
final double [] data_out =new double [woi_len];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int iPix = ai.getAndIncrement(); iPix < woi_len; iPix = ai.getAndIncrement()) {
int x = woi.x + (iPix % woi.width);
int y = woi.y + (iPix / woi.width);
int nPix = y * width + x;
data_out[iPix] = data1[nPix] - data0[nPix];
}
}
};
}
ImageDtt.startAndJoin(threads);
return data_out;
}
} }
...@@ -39,6 +39,7 @@ import com.elphel.imagej.common.ShowDoubleFloatArrays; ...@@ -39,6 +39,7 @@ import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.gpu.GPUTileProcessor; import com.elphel.imagej.gpu.GPUTileProcessor;
import com.elphel.imagej.gpu.TpTask; import com.elphel.imagej.gpu.TpTask;
import com.elphel.imagej.tileprocessor.ImageDtt; import com.elphel.imagej.tileprocessor.ImageDtt;
import com.elphel.imagej.tileprocessor.IntersceneMatchParameters;
import com.elphel.imagej.tileprocessor.OpticalFlow; import com.elphel.imagej.tileprocessor.OpticalFlow;
import com.elphel.imagej.tileprocessor.TDCorrTile; import com.elphel.imagej.tileprocessor.TDCorrTile;
import com.elphel.imagej.tileprocessor.TileNeibs; import com.elphel.imagej.tileprocessor.TileNeibs;
...@@ -1245,61 +1246,6 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -1245,61 +1246,6 @@ public class OrthoMapsCollection implements Serializable{
} }
/*
public FineXYCorr correlateOrthoPair( // not used
CLTParameters clt_parameters,
PairwiseOrthoMatch pairwiseOrthoMatch, // will return statistics
double frac_remove, // = 0.25
double metric_error,
boolean ignore_prev_rms,
int num_tries, // = 5
boolean calc_warp,
boolean batch_mode,
String [] gpu_spair,
double [][][] affines, // here in meters, relative to vertical points
Rectangle woi,
int zoom_lev,
boolean show_vf,
double [][] ground_planes, // null or double[2] - will return ground planes
double rad_fraction,
double fill_fraction,
double fill_fraction_final,
double ease_nosfm,
double [] max_rms_iter, // = {1.0, 0.6};//
final int debugLevel){
int [] gpu_pair = new int[gpu_spair.length];
for (int i = 0; i < gpu_pair.length; i++) {
gpu_pair[i] = getIndex(gpu_spair[i]);
}
double max_std = 1.5; // maximal standard deviation to limit center area
double min_std_rad = 2.0; // minimal radius of the central area (if less - fail)
return 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, // double metric_error,
ignore_prev_rms, // boolean ignore_prev_rms,
num_tries, // = 5int num_tries, // = 5
calc_warp, // boolean calc_warp,
batch_mode, // boolean batch_mode,
gpu_pair, // int [] gpu_pair,
affines, // double [][][] affines, // here in meters, relative to vertical points
woi, // Rectangle woi,
zoom_lev, // 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,
30, // 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, // = {1.0, 0.6};// double [] max_rms_iter, // = {1.0, 0.6};//
debugLevel); // final int debugLevel)
}
*/
public FineXYCorr correlateOrthoPair( public FineXYCorr correlateOrthoPair(
CLTParameters clt_parameters, CLTParameters clt_parameters,
PairwiseOrthoMatch pairwiseOrthoMatch, // will return statistics, may be null if not needed PairwiseOrthoMatch pairwiseOrthoMatch, // will return statistics, may be null if not needed
...@@ -1921,6 +1867,7 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -1921,6 +1867,7 @@ public class OrthoMapsCollection implements Serializable{
tlo_rect_metric[1][0] * affines[1][i][0] - tlo_rect_metric[1][0] * affines[1][i][0] -
tlo_rect_metric[1][1] * affines[1][i][1]; tlo_rect_metric[1][1] * affines[1][i][1];
} }
if (debugLevel>-3) { if (debugLevel>-3) {
System.out.println("correlateOrthoPair(): adjusted affines[1]"); System.out.println("correlateOrthoPair(): adjusted affines[1]");
System.out.println("[["+affines[1][0][0]+","+affines[1][0][1]+","+affines[1][0][2]+"],"); System.out.println("[["+affines[1][0][0]+","+affines[1][0][1]+","+affines[1][0][2]+"],");
...@@ -5213,12 +5160,15 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5213,12 +5160,15 @@ public class OrthoMapsCollection implements Serializable{
boolean flt_filt_zoom = clt_parameters.imp.flt_filt_zoom; // true; boolean flt_filt_zoom = clt_parameters.imp.flt_filt_zoom; // true;
int flt_min_zoom = clt_parameters.imp.flt_min_zoom; // -2; int flt_min_zoom = clt_parameters.imp.flt_min_zoom; // -2;
int flt_max_zoom = clt_parameters.imp.flt_max_zoom; // 10; int flt_max_zoom = clt_parameters.imp.flt_max_zoom; // 10;
double flt_min_sfm = clt_parameters.imp.flt_min_sfm; // 0.0;
double flt_max_sfm = clt_parameters.imp.flt_max_sfm; //1000.0;
int flt_alt = clt_parameters.imp.flt_alt; // 0;
boolean flt_nan_rms = true; // clt_parameters.imp.flt_nan_rms; // false; 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_names = true; // clt_parameters.imp.flt_show_names; // true;
boolean flt_show_overlaps = true; // clt_parameters.imp.flt_show_overlaps; // 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_rms = true; // clt_parameters.imp.flt_show_rms; // true;
boolean flt_show_zoom = true; // clt_parameters.imp.flt_show_zoom; // true; boolean flt_show_zoom = true; // clt_parameters.imp.flt_show_zoom; // true;
boolean flt_show_alt = true; // clt_parameters.imp.flt_show_alt; // true;
//Initial spiral search for image matching //Initial spiral search for image matching
boolean ospir_augment = clt_parameters.imp.ospir_augment; // true boolean ospir_augment = clt_parameters.imp.ospir_augment; // true
double max_rms = clt_parameters.imp.ospir_max_rms; // 0.35; // double max_rms = clt_parameters.imp.ospir_max_rms; // 0.35; //
...@@ -5261,6 +5211,9 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5261,6 +5211,9 @@ public class OrthoMapsCollection implements Serializable{
gdf.addCheckbox ("Filter by zoom level" , flt_filt_zoom, "Filter by the zoom level used for matching."); 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("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.addNumericField("Maximal zoom", flt_max_zoom, 0,3,"","Maximal zoom level used for matching.");
gdf.addNumericField("Minimal SfM gain", flt_min_sfm, 3,7,"","Minimal SfM gain of the minimum in the scene pair.");
gdf.addNumericField("Maximal SfM gain", flt_max_sfm, 3,7,"","Maximal SfM gain of the minimum in the scene pair.");
gdf. addChoice("Filter by pairwise ALT availability",IntersceneMatchParameters.FLT_ALT_MODES, IntersceneMatchParameters.FLT_ALT_MODES[flt_alt],"Filter by pairwise ALT availability.");
gdf.addMessage("Low-resolution match parameters"); 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.addCheckbox ("Use low-res in augmentation", ospir_augment, "Use low-res matching during augmenting (false - skip, go to high-res).");
...@@ -5304,7 +5257,9 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5304,7 +5257,9 @@ public class OrthoMapsCollection implements Serializable{
flt_filt_zoom = gdf.getNextBoolean(); flt_filt_zoom = gdf.getNextBoolean();
flt_min_zoom = (int) gdf.getNextNumber(); flt_min_zoom = (int) gdf.getNextNumber();
flt_max_zoom = (int) gdf.getNextNumber(); flt_max_zoom = (int) gdf.getNextNumber();
flt_min_sfm = gdf.getNextNumber();
flt_max_sfm = gdf.getNextNumber();
flt_alt = gdf.getNextChoiceIndex();
ospir_augment = gdf.getNextBoolean(); ospir_augment = gdf.getNextBoolean();
max_rms = gdf.getNextNumber(); max_rms = gdf.getNextNumber();
max_rms_refine = gdf.getNextNumber(); max_rms_refine = gdf.getNextNumber();
...@@ -5343,6 +5298,9 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5343,6 +5298,9 @@ public class OrthoMapsCollection implements Serializable{
clt_parameters.imp.flt_filt_zoom = flt_filt_zoom; clt_parameters.imp.flt_filt_zoom = flt_filt_zoom;
clt_parameters.imp.flt_min_zoom = flt_min_zoom; clt_parameters.imp.flt_min_zoom = flt_min_zoom;
clt_parameters.imp.flt_max_zoom = flt_max_zoom; clt_parameters.imp.flt_max_zoom = flt_max_zoom;
clt_parameters.imp.flt_min_sfm = flt_min_sfm;
clt_parameters.imp.flt_max_sfm = flt_max_sfm;
clt_parameters.imp.flt_alt = flt_alt;
clt_parameters.imp.ospir_augment = ospir_augment; clt_parameters.imp.ospir_augment = ospir_augment;
clt_parameters.imp.ospir_max_rms = max_rms; clt_parameters.imp.ospir_max_rms = max_rms;
clt_parameters.imp.pwise_max_rms = max_rms_refine; clt_parameters.imp.pwise_max_rms = max_rms_refine;
...@@ -5383,13 +5341,18 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -5383,13 +5341,18 @@ public class OrthoMapsCollection implements Serializable{
flt_nan_rms, // boolean nan_rms) flt_nan_rms, // boolean nan_rms)
flt_filt_zoom, // boolean filt_zoom, flt_filt_zoom, // boolean filt_zoom,
flt_min_zoom, // int min_zoom, flt_min_zoom, // int min_zoom,
flt_max_zoom); // int max_zoom) flt_max_zoom, // int max_zoom)
flt_min_sfm, // double min_sfm,
flt_max_sfm, // double max_sfm,
flt_alt); // int flt_alt)
String [] choices_all = textPairs ( String [] choices_all = textPairs (
available_pairs, // int [][] plist, available_pairs, // int [][] plist,
flt_show_names, // boolean show_names, flt_show_names, // boolean show_names,
flt_show_overlaps, // boolean show_overlap, flt_show_overlaps, // boolean show_overlap,
flt_show_rms, // boolean show_rms, flt_show_rms, // boolean show_rms,
flt_show_zoom, // boolean show_zoom, flt_show_zoom, // boolean show_zoom,
flt_show_alt, // boolean show_alt,
true, // boolean use_tab,
null); // String extra_line) null); // String extra_line)
if (debugLevel > 0) { if (debugLevel > 0) {
System.out.println("Selected "+available_pairs.length+" scene pairs for matching"); System.out.println("Selected "+available_pairs.length+" scene pairs for matching");
...@@ -6302,6 +6265,438 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -6302,6 +6265,438 @@ public class OrthoMapsCollection implements Serializable{
return true; return true;
} }
public boolean altutudeMatchPairs(
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>();
boolean dbg00 = false;
for (OrthoMap map : ortho_maps) {
// if (getIndex(map.getName()) == 87) {
// System.out.println("index="+getIndex(map.getName()));
// }
for (String other_name: map.pairwise_matches.keySet()) {
pairs_list.add(new Point(
getIndex(map.getName()),
getIndex(other_name)));
if (dbg00) {
System.out.println(getIndex(map.getName())+"-"+getIndex(other_name)+" "+map.getName()+"-"+other_name);
if(getIndex(map.getName()) == getIndex(other_name)) {
System.out.println();
}
}
}
}
// 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 = 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;
double flt_min_sfm = clt_parameters.imp.flt_min_sfm; // 0.0;
double flt_max_sfm = clt_parameters.imp.flt_max_sfm; //1000.0;
int flt_alt = clt_parameters.imp.flt_alt; // 0;
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;
boolean flt_show_alt = true; // clt_parameters.imp.flt_show_alt; // true;
boolean alt_overwrite = clt_parameters.imp.alt_overwrite; // false; // overwrite existing altitude match pairs
boolean alt_pairwise = clt_parameters.imp.alt_pairwise; // false; // overwrite existing altitude match pairs
double alt_sigma = clt_parameters.imp.alt_sigma; // 5.0; Reduce weight of the border tiles, Gaussian sigma in tiles to apply to weights.
double alt_abs_outliers = clt_parameters.imp.alt_abs_outliers; // 3.0; // remove absolute outliers when fitting planes
double alt_outliers = clt_parameters.imp.alt_outliers; // 0.05; Remove outliers when fitting planes, removed fraction.
int alt_refine = clt_parameters.imp.alt_refine; // 1; Refine altitude difference plane after removing outliers (0 - no outlier removal, 1 - remove outliers and refine once, ...)
double metric_err = clt_parameters.imp.pmtch_metric_err;// 0.05; // 0.02;// 2 cm
// 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;
boolean select_pairs = 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.addNumericField("Minimal SfM gain", flt_min_sfm, 3,7,"","Minimal SfM gain of the minimum in the scene pair.");
gdf.addNumericField("Maximal SfM gain", flt_max_sfm, 3,7,"","Maximal SfM gain of the minimum in the scene pair.");
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.addChoice("Filter by pairwise ALT availability",IntersceneMatchParameters.FLT_ALT_MODES, IntersceneMatchParameters.FLT_ALT_MODES[flt_alt],"Filter by pairwise ALT availability.");
gdf.addMessage("Alt match parameters");
gdf.addCheckbox ("Overwrite existing alt_data", alt_overwrite, "Overwrite already defined altitude match pairs.");
gdf.addCheckbox ("Use pairwise affines", alt_pairwise, "Use pairwise affines if available (false - always recalculate from individual).");
gdf.addNumericField("Border sigma", alt_sigma, 3,7,"tiles", "Reduce weight of the border tiles, Gaussian sigma in tiles to apply to weights.");
gdf.addNumericField("Absolute outliers offset", alt_abs_outliers, 3,7,"m","Remove absolute outliers when fitting planes.");
gdf.addNumericField("Fraction of ouliers", alt_outliers, 3,7,"", "Remove outliers when fitting planes, removed fraction.");
gdf.addNumericField("Number of alt plane refines", alt_refine, 0,3,"", "Refine altitude difference plane after removing outliers (0 - no outlier removal, 1 - remove outliers and refine once, ...)");
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.addCheckbox ("Update configuration", flt_update_config, "Update matching configuration parameters to be saved as defaults.");
gdf.addCheckbox ("Select filtered pairs", select_pairs, "Manually select from the filtered pairs.");
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();
flt_min_sfm = gdf.getNextNumber();
flt_max_sfm = gdf.getNextNumber();
flt_min_rms = gdf.getNextNumber();
flt_max_rms = gdf.getNextNumber();
flt_nan_rms = gdf.getNextBoolean();
flt_alt = gdf.getNextChoiceIndex();
alt_overwrite = gdf.getNextBoolean();
alt_pairwise = gdf.getNextBoolean();
alt_sigma = gdf.getNextNumber();
alt_abs_outliers = gdf.getNextNumber();
alt_outliers = gdf.getNextNumber();
alt_refine = (int) gdf.getNextNumber();
save_each = gdf.getNextBoolean();
log_append = gdf.getNextBoolean();
log_path = gdf.getNextString();
debugLevel = (int) gdf.getNextNumber();
flt_update_config = gdf.getNextBoolean();
select_pairs = 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.flt_min_sfm = flt_min_sfm;
clt_parameters.imp.flt_max_sfm = flt_max_sfm;
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_alt = flt_alt;
clt_parameters.imp.alt_overwrite = alt_overwrite;
clt_parameters.imp.alt_pairwise = alt_pairwise;
clt_parameters.imp.alt_sigma = alt_sigma;
clt_parameters.imp.alt_abs_outliers = alt_abs_outliers;
clt_parameters.imp.alt_outliers = alt_outliers;
clt_parameters.imp.alt_refine = alt_refine;
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)
flt_min_sfm, // double min_sfm,
flt_max_sfm, // double max_sfm,
flt_alt); // int flt_alt)\
if (select_pairs) {
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,
flt_show_alt, // boolean show_alt,
false, // boolean use_tab,
null); // flt_extra_line); // String extra_line)
GenericJTabbedDialog gdc = new GenericJTabbedDialog("Select image pairs",1200,1000);
boolean [] bselected_pairs = new boolean [choices_all.length];
for (int i = 0; i < choices_all.length; i++) {
gdc.addCheckbox (i+": "+choices_all[i], bselected_pairs[i], "Select this scene pair for processing.");
}
gdc.showDialog();
if (gdc.wasCanceled()) return false;
int num_pairs = 0;
for (int i = 0; i < choices_all.length; i++) {
bselected_pairs[i] = gdc.getNextBoolean();
if (bselected_pairs[i]) num_pairs++;
}
int [][] selected_pairs = new int[num_pairs][];
int indx = 0;
for (int i = 0; i < bselected_pairs.length; i++) if (bselected_pairs[i]){
selected_pairs[indx++]= available_pairs[i];
}
available_pairs = selected_pairs;
}
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,
flt_show_alt, // boolean show_alt,
true, // boolean use_tab,
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 OrthoAltitudeMatch.altutudeMatchPairs(
clt_parameters, // CLTParameters clt_parameters,
this, // OrthoMapsCollection orthoMapsCollection,
available_pairs, // int [][] available_pairs,
select_pairs || alt_overwrite, // boolean alt_overwrite, // overwrite existing altitude match pairs
alt_pairwise, // boolean alt_pairwise, // use pairwise affines if available
alt_sigma, // double alt_sigma, // 5.0; Reduce weight of the border tiles, Gaussian sigma in tiles to apply to weights.
alt_abs_outliers, //double alt_abs_outliers, // = 3.0; // remove absolute outliers when fitting planes
alt_outliers, // double alt_outliers, // 0.05; Remove outliers when fitting planes, removed fraction.
alt_refine, // int alt_refine, // 1; Refine altitude difference plane after removing outliers (0 - no outlier removal, 1 - remove outliers and refine once, ...)
metric_err, // double metric_error,
// 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 displayScenePairs(
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>();
boolean dbg00=false;
for (OrthoMap map : ortho_maps) {
if (getIndex(map.getName()) == 87) {
System.out.println("index="+getIndex(map.getName()));
}
for (String other_name: map.pairwise_matches.keySet()) {
pairs_list.add(new Point(
getIndex(map.getName()),
getIndex(other_name)));
if (dbg00) {
System.out.println(getIndex(map.getName())+"-"+getIndex(other_name)+" "+map.getName()+"-"+other_name);
if(getIndex(map.getName()) == getIndex(other_name)) {
System.out.println();
}
}
}
}
// 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 = 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;
double flt_min_sfm = clt_parameters.imp.flt_min_sfm; // 0.0;
double flt_max_sfm = clt_parameters.imp.flt_max_sfm; //1000.0;
int flt_alt = clt_parameters.imp.flt_alt; // 0;
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;
boolean flt_show_alt = true; // clt_parameters.imp.flt_show_alt; // true;
boolean alt_overwrite = clt_parameters.imp.alt_overwrite; // false; // overwrite existing altitude match pairs
boolean alt_pairwise = clt_parameters.imp.alt_pairwise; // false; // overwrite existing altitude match pairs
double metric_err = clt_parameters.imp.pmtch_metric_err;// 0.05; // 0.02;// 2 cm
// 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.addNumericField("Minimal SfM gain", flt_min_sfm, 3,7,"","Minimal SfM gain of the minimum in the scene pair.");
gdf.addNumericField("Maximal SfM gain", flt_max_sfm, 3,7,"","Maximal SfM gain of the minimum in the scene pair.");
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.addChoice("Filter by pairwise ALT availability",IntersceneMatchParameters.FLT_ALT_MODES, IntersceneMatchParameters.FLT_ALT_MODES[flt_alt],"Filter by pairwise ALT availability.");
gdf.addMessage("Alt match parameters");
gdf.addCheckbox ("Overwrite existing alt_data", alt_overwrite, "Overwrite already defined altitude match pairs.");
gdf.addCheckbox ("Use pairwise affines", alt_pairwise, "Use pairwise affines if available (false - always recalculate from individual).");
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.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();
flt_min_sfm = gdf.getNextNumber();
flt_max_sfm = gdf.getNextNumber();
flt_min_rms = gdf.getNextNumber();
flt_max_rms = gdf.getNextNumber();
flt_nan_rms = gdf.getNextBoolean();
flt_alt = gdf.getNextChoiceIndex();
alt_overwrite = gdf.getNextBoolean();
alt_pairwise = gdf.getNextBoolean();
save_each = gdf.getNextBoolean();
log_append = gdf.getNextBoolean();
log_path = gdf.getNextString();
debugLevel = (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.flt_min_sfm = flt_min_sfm;
clt_parameters.imp.flt_max_sfm = flt_max_sfm;
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_alt = flt_alt;
clt_parameters.imp.alt_overwrite = alt_overwrite;
clt_parameters.imp.alt_pairwise = alt_pairwise;
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)
flt_min_sfm, // double min_sfm,
flt_max_sfm, // double max_sfm,
flt_alt); // int flt_alt)
boolean use_tab=true;
boolean flt_show_sfm=flt_show_alt;
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,
flt_show_alt, // boolean show_alt,
use_tab, // boolean use_tab,
null); // String extra_line)
{
System.out.println("Selected\t"+available_pairs.length+"\tscene pairs for matching");
if (use_tab) {
System.out.print(String.format("#\t%3s\t%3s","i0","i1"));
if (flt_show_names) System.out.print(String.format("\t%17s\t%17s","timestamp 0","timestamp 1"));
if (flt_show_overlaps) System.out.print(String.format("\t%5s", "olap%"));
if (flt_show_rms) System.out.print(String.format("\t%5s", "RMSE"));
if (flt_show_zoom) System.out.print(String.format("\t%4s", "Zoom"));
if (flt_show_alt) System.out.print(String.format("\t%7s\t%7s\t%7s", "tiltX","tiltY","offs"));
if (flt_show_sfm) System.out.print(String.format("\t%5s\t%5s", "SfM0","SfM1"));
System.out.println();
}
for (int i = 0; i < available_pairs.length; i++) {
// System.out.println(String.format("%4d:%s",i,choices_all[i]));
System.out.println(String.format(use_tab?"%4d\t%s":"%4d:%s",i,choices_all[i]));
}
}
if (available_pairs.length == 0) {
return false;
}
////
return true;
}
public boolean processComboMap( public boolean processComboMap(
CLTParameters clt_parameters, CLTParameters clt_parameters,
int debugLevel) { int debugLevel) {
...@@ -6335,7 +6730,7 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -6335,7 +6730,7 @@ public class OrthoMapsCollection implements Serializable{
double frame_blur = 1.0; double frame_blur = 1.0;
double frame_cut_frac = 0.01; double frame_cut_frac = 0.01;
int zoom_lev = -2; // 0; // +1 - zoom in twice, -1 - zoom out twice int zoom_lev = -2; // 0; // +1 - zoom in twice, -1 - zoom out twice
int margins = 10; int margins = 0; // 10;
boolean show_centers = true; boolean show_centers = true;
boolean bounds_to_indices = true; boolean bounds_to_indices = true;
boolean merge_layers = false; // instead of individuals boolean merge_layers = false; // instead of individuals
...@@ -7030,6 +7425,9 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -7030,6 +7425,9 @@ public class OrthoMapsCollection implements Serializable{
* @param filt_zoom filter by zoom * @param filt_zoom filter by zoom
* @param min_zoom minimal zoom (including) * @param min_zoom minimal zoom (including)
* @param max_zoom maximal zoom (including) * @param max_zoom maximal zoom (including)
* @param min_sfm minimal SfM gain of the minimum in the scene pair
* @param max_sfm maximal SfM gain of the minimum in the scene pair
* @param filt_alt filter by alt data availability (0 - no filter, 1 - with alt only, 2 - without ALT only)
* @return filtered array of pair indices * @return filtered array of pair indices
*/ */
...@@ -7043,7 +7441,10 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -7043,7 +7441,10 @@ public class OrthoMapsCollection implements Serializable{
boolean nan_rms, boolean nan_rms,
boolean filt_zoom, boolean filt_zoom,
int min_zoom, int min_zoom,
int max_zoom){ int max_zoom,
double min_sfm,
double max_sfm,
int filt_alt){
ArrayList<Point> plist = new ArrayList<Point>(); ArrayList<Point> plist = new ArrayList<Point>();
int num_all = 0; int num_all = 0;
int num_def = 0; int num_def = 0;
...@@ -7052,12 +7453,29 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -7052,12 +7453,29 @@ public class OrthoMapsCollection implements Serializable{
PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[pair.x].getMatch( PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[pair.x].getMatch(
ortho_maps[pair.y].getName(), undef_only || nan_rms); ortho_maps[pair.y].getName(), undef_only || nan_rms);
double sfm_gain = Math.min(ortho_maps[pair.x].getSfmGain(), ortho_maps[pair.y].getSfmGain());
if (pairwiseOrthoMatch != null) { if (pairwiseOrthoMatch != null) {
num_all++; num_all++;
boolean defined = pairwiseOrthoMatch.isDefined(); boolean defined = pairwiseOrthoMatch.isDefined();
if (defined) { if (defined) {
num_def++; num_def++;
} }
if (filt_alt != 0) { // has alt data
if (pairwiseOrthoMatch.alt_data != null) {
if (filt_alt == 2) {
continue; // skip if no-ALT only
}
} else { // does not have alt data
if (filt_alt == 1) {
continue; // skip if ALT only
}
}
}
if ((sfm_gain < min_sfm) || (sfm_gain > max_sfm)) {
continue;
}
if (undef_only) { if (undef_only) {
if (!defined) { if (!defined) {
plist.add(pair); plist.add(pair);
...@@ -7097,6 +7515,7 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -7097,6 +7515,7 @@ public class OrthoMapsCollection implements Serializable{
* @param show_overlap show scene overlap in percents * @param show_overlap show scene overlap in percents
* @param show_rms show pairs RMSE * @param show_rms show pairs RMSE
* @param show_zoom show pairs zoom level * @param show_zoom show pairs zoom level
* @param show_alt show altitude data
* @param extra_line null or an extra string to be added as a last element * @param extra_line null or an extra string to be added as a last element
* @return Array of strings to be shown in a drop-down list * @return Array of strings to be shown in a drop-down list
*/ */
...@@ -7106,31 +7525,37 @@ public class OrthoMapsCollection implements Serializable{ ...@@ -7106,31 +7525,37 @@ public class OrthoMapsCollection implements Serializable{
boolean show_overlap, boolean show_overlap,
boolean show_rms, boolean show_rms,
boolean show_zoom, boolean show_zoom,
boolean show_alt,
boolean use_tab,
String extra_line) { String extra_line) {
boolean show_sfm = show_alt;
// TODO: show SfM of each scene
String [] text_pairs = new String [plist.length+((extra_line !=null)? 1 : 0)]; String [] text_pairs = new String [plist.length+((extra_line !=null)? 1 : 0)];
for (int i = 0; i < plist.length; i++) { for (int i = 0; i < plist.length; i++) {
int [] pair = plist[i]; int [] pair = plist[i];
double [] sfm_gain = {ortho_maps[pair[0]].getSfmGain(), ortho_maps[pair[1]].getSfmGain()};
PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[pair[0]].getMatch( PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[pair[0]].getMatch(
ortho_maps[pair[1]].getName(), true); // include undefined ortho_maps[pair[1]].getName(), true); // include undefined
if (pairwiseOrthoMatch== null) { // if (pairwiseOrthoMatch== null) {
System.out.println("pair=["+pair[0]+","+pair[1]+"] "+ // System.out.println("pair=["+pair[0]+","+pair[1]+"] "+
ortho_maps[pair[0]].getName()+"->"+ortho_maps[pair[1]].getName()); // ortho_maps[pair[0]].getName()+"->"+ortho_maps[pair[1]].getName());
// }
} text_pairs[i] = String.format(use_tab?"%3d\t%3d":"%3d -> %3d", pair[0], pair[1]);
text_pairs[i] = String.format("%3d -> %3d", pair[0], pair[1]); if (show_names) text_pairs[i] += String.format(use_tab?"\t%17s\t%17s":" (%17s -> %17s)", ortho_maps[pair[0]].getName(),ortho_maps[pair[1]].getName());
if (show_names) {
text_pairs[i] += String.format(" (%s -> %s)", ortho_maps[pair[0]].getName(),ortho_maps[pair[1]].getName());
}
if (pairwiseOrthoMatch != null) { if (pairwiseOrthoMatch != null) {
if (show_overlap) { if (show_overlap) text_pairs[i] += String.format(use_tab?"\t%5.1f%%":" %5.1f%%", 100*pairwiseOrthoMatch.overlap);
text_pairs[i] += String.format(" %5.1f%%", 100*pairwiseOrthoMatch.overlap); if (show_rms) text_pairs[i] += String.format(use_tab?"\t%5.3f":" %5.3f", pairwiseOrthoMatch.rms);
} if (show_zoom) text_pairs[i] += String.format(use_tab?"\t%4d":" Z%3d", pairwiseOrthoMatch.zoom_lev);
if (show_rms) { if (show_alt){
text_pairs[i] += String.format(" %5.3f", pairwiseOrthoMatch.rms); if (pairwiseOrthoMatch.alt_data != null) {
} text_pairs[i] += String.format(use_tab?"\t%7.4f\t%7.4f\t%7.3f":" A %7.4f %7.4f %7.3f",
if (show_zoom) { pairwiseOrthoMatch.alt_data[0],pairwiseOrthoMatch.alt_data[1],pairwiseOrthoMatch.alt_data[2]); //" ALT";
text_pairs[i] += String.format(" Z%3d", pairwiseOrthoMatch.zoom_lev); } else if (use_tab) {
} text_pairs[i] += String.format("\t%7s\t%7s\t%7s","---","---","---");
}
}
if (show_sfm) text_pairs[i] += String.format(use_tab?"\t%5.1f\t%5.1f":" S %5.1f %5.1f", sfm_gain[0],sfm_gain[1]);
} }
} }
if (extra_line !=null) { if (extra_line !=null) {
......
...@@ -39,6 +39,7 @@ import com.elphel.imagej.cameras.CLTParameters; ...@@ -39,6 +39,7 @@ import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.common.GenericJTabbedDialog; import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.tileprocessor.ImageDtt; import com.elphel.imagej.tileprocessor.ImageDtt;
import com.elphel.imagej.tileprocessor.IntersceneMatchParameters;
import Jama.Matrix; import Jama.Matrix;
import ij.ImagePlus; import ij.ImagePlus;
...@@ -265,10 +266,14 @@ public class OrthoMultiLMA { ...@@ -265,10 +266,14 @@ public class OrthoMultiLMA {
boolean flt_filt_zoom = clt_parameters.imp.flt_filt_zoom; // true; boolean flt_filt_zoom = clt_parameters.imp.flt_filt_zoom; // true;
int flt_min_zoom = clt_parameters.imp.flt_min_zoom; // -2; int flt_min_zoom = clt_parameters.imp.flt_min_zoom; // -2;
int flt_max_zoom = clt_parameters.imp.flt_max_zoom; // 10; int flt_max_zoom = clt_parameters.imp.flt_max_zoom; // 10;
double flt_min_sfm = clt_parameters.imp.flt_min_sfm; // 0.0;
double flt_max_sfm = clt_parameters.imp.flt_max_sfm; //1000.0;
int flt_alt = clt_parameters.imp.flt_alt; // 0;
boolean flt_show_names = true; // clt_parameters.imp.flt_show_names; // true; 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_overlaps = true; // clt_parameters.imp.flt_show_overlaps; // true;
boolean flt_show_rms = true; // clt_parameters.imp.flt_show_rms; // 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; boolean flt_show_zoom = true; // clt_parameters.imp.flt_show_zoom; // true;
boolean flt_show_alt = true; // clt_parameters.imp.flt_show_alt; // true;
boolean move_only = clt_parameters.imp.pmap_move_only; // false; boolean move_only = clt_parameters.imp.pmap_move_only; // false;
boolean ignore_affines = clt_parameters.imp.pmap_ignore_affines; // false; boolean ignore_affines = clt_parameters.imp.pmap_ignore_affines; // false;
...@@ -298,7 +303,9 @@ public class OrthoMultiLMA { ...@@ -298,7 +303,9 @@ public class OrthoMultiLMA {
gd.addCheckbox ("Filter by zoom level" , flt_filt_zoom, "Filter by the zoom level used for matching."); gd.addCheckbox ("Filter by zoom level" , flt_filt_zoom, "Filter by the zoom level used for matching.");
gd.addNumericField("Minimal zoom", flt_min_zoom, 0,3,"","Minimal zoom level used for matching."); gd.addNumericField("Minimal zoom", flt_min_zoom, 0,3,"","Minimal zoom level used for matching.");
gd.addNumericField("Maximal zoom", flt_max_zoom, 0,3,"","Maximal zoom level used for matching."); gd.addNumericField("Maximal zoom", flt_max_zoom, 0,3,"","Maximal zoom level used for matching.");
gd.addNumericField("Minimal SfM gain", flt_min_sfm, 3,7,"","Minimal SfM gain of the minimum in the scene pair.");
gd.addNumericField("Maximal SfM gain", flt_max_sfm, 3,7,"","Maximal SfM gain of the minimum in the scene pair.");
gd.addChoice("Filter by pairwise ALT availability",IntersceneMatchParameters.FLT_ALT_MODES, IntersceneMatchParameters.FLT_ALT_MODES[flt_alt],"Filter by pairwise ALT availability.");
gd.addCheckbox ("Moves only", move_only, "Moves only, no affine transform."); gd.addCheckbox ("Moves only", move_only, "Moves only, no affine transform.");
gd.addCheckbox ("Ignore existing affines", ignore_affines, "Start from unity matrices, ignore saved affines."); gd.addCheckbox ("Ignore existing affines", ignore_affines, "Start from unity matrices, ignore saved affines.");
gd.addCheckbox ("Use reversed pairs", use_inv, "Use reversed (late-early timestamps) pairs."); gd.addCheckbox ("Use reversed pairs", use_inv, "Use reversed (late-early timestamps) pairs.");
...@@ -329,7 +336,9 @@ public class OrthoMultiLMA { ...@@ -329,7 +336,9 @@ public class OrthoMultiLMA {
flt_filt_zoom = gd.getNextBoolean(); flt_filt_zoom = gd.getNextBoolean();
flt_min_zoom = (int) gd.getNextNumber(); flt_min_zoom = (int) gd.getNextNumber();
flt_max_zoom = (int) gd.getNextNumber(); flt_max_zoom = (int) gd.getNextNumber();
flt_min_sfm = gd.getNextNumber();
flt_max_sfm = gd.getNextNumber();
flt_alt = gd.getNextChoiceIndex();
move_only = gd.getNextBoolean(); move_only = gd.getNextBoolean();
ignore_affines = gd.getNextBoolean(); ignore_affines = gd.getNextBoolean();
use_inv = gd.getNextBoolean(); use_inv = gd.getNextBoolean();
...@@ -354,6 +363,9 @@ public class OrthoMultiLMA { ...@@ -354,6 +363,9 @@ public class OrthoMultiLMA {
clt_parameters.imp.flt_filt_zoom = flt_filt_zoom; clt_parameters.imp.flt_filt_zoom = flt_filt_zoom;
clt_parameters.imp.flt_min_zoom = flt_min_zoom; clt_parameters.imp.flt_min_zoom = flt_min_zoom;
clt_parameters.imp.flt_max_zoom = flt_max_zoom; clt_parameters.imp.flt_max_zoom = flt_max_zoom;
clt_parameters.imp.flt_min_sfm = flt_min_sfm;
clt_parameters.imp.flt_max_sfm = flt_max_sfm;
clt_parameters.imp.flt_alt = flt_alt;
clt_parameters.imp.pmap_move_only = move_only; clt_parameters.imp.pmap_move_only = move_only;
clt_parameters.imp.pmap_ignore_affines = ignore_affines; clt_parameters.imp.pmap_ignore_affines = ignore_affines;
clt_parameters.imp.pmap_use_inv = use_inv; clt_parameters.imp.pmap_use_inv = use_inv;
...@@ -378,7 +390,10 @@ public class OrthoMultiLMA { ...@@ -378,7 +390,10 @@ public class OrthoMultiLMA {
flt_nan_rms, // boolean nan_rms) flt_nan_rms, // boolean nan_rms)
flt_filt_zoom, // boolean filt_zoom, flt_filt_zoom, // boolean filt_zoom,
flt_min_zoom, // int min_zoom, flt_min_zoom, // int min_zoom,
flt_max_zoom); // int max_zoom) flt_max_zoom, // int max_zoom)
flt_min_sfm, // double min_sfm,
flt_max_sfm, // double max_sfm,
flt_alt); // int flt_alt)
String [] choices_all = maps_collection.textPairs ( String [] choices_all = maps_collection.textPairs (
available_pairs, // int [][] plist, available_pairs, // int [][] plist,
...@@ -386,6 +401,8 @@ public class OrthoMultiLMA { ...@@ -386,6 +401,8 @@ public class OrthoMultiLMA {
flt_show_overlaps, // boolean show_overlap, flt_show_overlaps, // boolean show_overlap,
flt_show_rms, // boolean show_rms, flt_show_rms, // boolean show_rms,
flt_show_zoom, // boolean show_zoom, flt_show_zoom, // boolean show_zoom,
flt_show_alt, // boolean show_alt,
true, // boolean use_tab,
null); // String extra_line) null); // String extra_line)
if (debugLevel > 0) { if (debugLevel > 0) {
System.out.println("Selected "+available_pairs.length+" scene pairs for matching"); System.out.println("Selected "+available_pairs.length+" scene pairs for matching");
......
/**
** PairwiseOrthoMatch - Represent pairwise match between scenes
**
** Copyright (C) 2024 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** PairwiseOrthoMatch.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
package com.elphel.imagej.orthomosaic; package com.elphel.imagej.orthomosaic;
import java.io.IOException; import java.io.IOException;
...@@ -29,6 +52,14 @@ public class PairwiseOrthoMatch implements Serializable { ...@@ -29,6 +52,14 @@ public class PairwiseOrthoMatch implements Serializable {
this.overlap =overlap; this.overlap =overlap;
} }
public double [] getAltData() {
return alt_data;
}
public void setAltData(double [] data) {
alt_data = data;
}
public PairwiseOrthoMatch( public PairwiseOrthoMatch(
double [][] affine, double [][] affine,
double [][] jtj, double [][] jtj,
...@@ -80,6 +111,7 @@ public class PairwiseOrthoMatch implements Serializable { ...@@ -80,6 +111,7 @@ public class PairwiseOrthoMatch implements Serializable {
} }
pom.equalize1to0 = this.equalize1to0.clone(); pom.equalize1to0 = this.equalize1to0.clone();
pom.ok = this.ok; pom.ok = this.ok;
pom.alt_data = this.alt_data.clone();
return pom; return pom;
} }
/** /**
......
...@@ -34,6 +34,8 @@ import com.elphel.imagej.orthomosaic.ComboMatch; ...@@ -34,6 +34,8 @@ import com.elphel.imagej.orthomosaic.ComboMatch;
public class IntersceneMatchParameters { public class IntersceneMatchParameters {
public static String [] MODES3D = {"RAW", "INF", "FG", "BG"}; // RAW:-1 public static String [] MODES3D = {"RAW", "INF", "FG", "BG"}; // RAW:-1
public static String [] MODES_AVI = {"RAW", "JPEG", "PNG"}; public static String [] MODES_AVI = {"RAW", "JPEG", "PNG"};
public static String [] FLT_ALT_MODES = {"--- (no ALT filter)", "ALT only", "no ALT only"};
// Maybe add parameters to make sure there is enough data? Enough in each zone? Enough spread? // Maybe add parameters to make sure there is enough data? Enough in each zone? Enough spread?
public boolean ims_use = true; // use IMS data public boolean ims_use = true; // use IMS data
public boolean ims_rebuild = false; // recalculate INS data (after lag change) public boolean ims_rebuild = false; // recalculate INS data (after lag change)
...@@ -165,6 +167,15 @@ public class IntersceneMatchParameters { ...@@ -165,6 +167,15 @@ public class IntersceneMatchParameters {
public String pwise_log_path = "/media/elphel/NVME/lwir16-proc/ortho_videos/debug/sept12-13/overlaps/pairwise_01.log"; public String pwise_log_path = "/media/elphel/NVME/lwir16-proc/ortho_videos/debug/sept12-13/overlaps/pairwise_01.log";
public int pwise_debug = 0; public int pwise_debug = 0;
// alt_data-related parameters
public boolean alt_overwrite = false; // re-calculate alt_data even if it exists
public boolean alt_pairwise = true; // use pairwise affines if available ** not used?
public double alt_sigma = 25.0; // reduce weight of the border tiles, Gaussian sigma in pixels (after scaling) to apply to weights
public double alt_abs_outliers = 3.0; // remove absolute outliers when fitting planes
public double alt_outliers = 0.1; // remove outliers when fitting planes
public int alt_refine= 1; // refine plane after removing outliers (0 - no outlier removal, 1 - remove outliers and refine once, ...)
public boolean pmap_move_only = false; public boolean pmap_move_only = false;
public boolean pmap_ignore_affines = false; public boolean pmap_ignore_affines = false;
public boolean pmap_use_inv = false; public boolean pmap_use_inv = false;
...@@ -202,11 +213,15 @@ public class IntersceneMatchParameters { ...@@ -202,11 +213,15 @@ public class IntersceneMatchParameters {
public boolean flt_filt_zoom = true; public boolean flt_filt_zoom = true;
public int flt_min_zoom = -2; public int flt_min_zoom = -2;
public int flt_max_zoom = 10; public int flt_max_zoom = 10;
public double flt_min_sfm = 0.0; // minimal minimal SfM gain of a pair
public double flt_max_sfm = 1000.0; // maximal minimal SfM gain of a pair
public int flt_alt = 0; // 0 - do not filter, 1 - keep only with alt data, 2 - keep only without alt data
public boolean flt_show_names = true; public boolean flt_show_names = true;
public boolean flt_show_overlaps = true; public boolean flt_show_overlaps = true;
public boolean flt_show_rms = true; public boolean flt_show_rms = true;
public boolean flt_show_zoom = true; public boolean flt_show_zoom = true;
public boolean flt_show_alt = true;
public String patt_save_top = "/media/elphel/NVME/lwir16-proc/ortho_videos/debug/sept12-13/pattern_match/"; public String patt_save_top = "/media/elphel/NVME/lwir16-proc/ortho_videos/debug/sept12-13/pattern_match/";
...@@ -907,6 +922,14 @@ min_str_neib_fpn 0.35 ...@@ -907,6 +922,14 @@ min_str_neib_fpn 0.35
gd.addStringField ("Log file full path", this.pwise_log_path, 150, "Path of the log file to be appended."); gd.addStringField ("Log file full path", this.pwise_log_path, 150, "Path of the log file to be appended.");
gd.addNumericField("Pairwise match debug level", this.pwise_debug, 0,3,"","Debug level during Spiral search."); gd.addNumericField("Pairwise match debug level", this.pwise_debug, 0,3,"","Debug level during Spiral search.");
gd.addMessage ("Parameters for elevation maps matching");
gd.addCheckbox ("Overwrite existing alt_data", this.alt_overwrite, "Overwrite already defined altitude match pairs.");
gd.addCheckbox ("Use pairwise affines", this.alt_pairwise, "Use pairwise affines if available (false - always recalculate from individual).");
gd.addNumericField("Border sigma", this.alt_sigma, 3,7,"scaled pix", "Reduce weight of the border tiles, Gaussian sigma in tiles to apply to weights.");
gd.addNumericField("Absolute outliers offset", this.alt_abs_outliers, 3,7,"m","Remove absolute outliers when fitting planes.");
gd.addNumericField("Fraction of ouliers", this.alt_outliers, 3,7,"", "Remove outliers when fitting planes, removed fraction.");
gd.addNumericField("Number of alt plane refines", this.alt_refine, 0,3,"", "Refine altitude difference plane after removing outliers (0 - no outlier removal, 1 - remove outliers and refine once, ...)");
gd.addMessage ("Build map with LMA from pairwise matches"); gd.addMessage ("Build map with LMA from pairwise matches");
gd.addCheckbox ("Moves only", this.pmap_move_only, "Moves only, no affine transform."); gd.addCheckbox ("Moves only", this.pmap_move_only, "Moves only, no affine transform.");
gd.addCheckbox ("Ignore existing affines", this.pmap_ignore_affines, "Start from unity matrices, ignore saved affines."); gd.addCheckbox ("Ignore existing affines", this.pmap_ignore_affines, "Start from unity matrices, ignore saved affines.");
...@@ -945,21 +968,20 @@ min_str_neib_fpn 0.35 ...@@ -945,21 +968,20 @@ min_str_neib_fpn 0.35
gd.addCheckbox ("Filter by zoom level" , this.flt_filt_zoom, "Filter by the zoom level used for matching."); gd.addCheckbox ("Filter by zoom level" , this.flt_filt_zoom, "Filter by the zoom level used for matching.");
gd.addNumericField("Minimal zoom", this.flt_min_zoom, 0,3,"","Minimal zoom level used for matching."); gd.addNumericField("Minimal zoom", this.flt_min_zoom, 0,3,"","Minimal zoom level used for matching.");
gd.addNumericField("Maximal zoom", this.flt_max_zoom, 0,3,"","Maximal zoom level used for matching."); gd.addNumericField("Maximal zoom", this.flt_max_zoom, 0,3,"","Maximal zoom level used for matching.");
gd.addNumericField("Minimal SfM gain", this.flt_min_sfm, 3,7,"","Minimal SfM gain of the minimum in the scene pair.");
gd.addNumericField("Maximal SfM gain", this.flt_max_sfm, 3,7,"","Maximal SfM gain of the minimum in the scene pair.");
gd. addChoice("Filter by pairwise ALT availability",FLT_ALT_MODES, FLT_ALT_MODES[this.flt_alt],"Filter by pairwise ALT availability.");
gd.addCheckbox ("Show scene names", this.flt_show_names, "Show scene full names (timestamps) in selection drop-down list."); gd.addCheckbox ("Show scene names", this.flt_show_names, "Show scene full names (timestamps) in selection drop-down list.");
gd.addCheckbox ("Show scene overlaps", this.flt_show_overlaps, "Show scene overlaps (in percents) in selection drop-down list."); gd.addCheckbox ("Show scene overlaps", this.flt_show_overlaps, "Show scene overlaps (in percents) in selection drop-down list.");
gd.addCheckbox ("Show pairs RMSE", this.flt_show_rms, "Show scene match RMSE in selection drop-down list."); gd.addCheckbox ("Show pairs RMSE", this.flt_show_rms, "Show scene match RMSE in selection drop-down list.");
gd.addCheckbox ("Show zoom level", this.flt_show_zoom, "Show zoom level."); gd.addCheckbox ("Show zoom level", this.flt_show_zoom, "Show zoom level.");
gd.addCheckbox ("Show ALT", this.flt_show_alt, "Show altitude data availability.");
gd.addMessage ("Pattern match directories"); gd.addMessage ("Pattern match directories");
gd.addStringField ("Pattern match save directory",this.patt_save_top, 120, "Top directory to save combo maps"); gd.addStringField ("Pattern match save directory",this.patt_save_top, 120, "Top directory to save combo maps");
gd.addStringField ("Save subdirectory", this.patt_save_subdir, 80, "Subdirectory for versions of the same scene/pair of scenes"); gd.addStringField ("Save subdirectory", this.patt_save_subdir, 80, "Subdirectory for versions of the same scene/pair of scenes");
//
gd.addTab ("Scene Series", "Processing series of scenes and multi-series sets"); gd.addTab ("Scene Series", "Processing series of scenes and multi-series sets");
gd.addMessage ("Build series options"); gd.addMessage ("Build series options");
...@@ -1906,6 +1928,13 @@ min_str_neib_fpn 0.35 ...@@ -1906,6 +1928,13 @@ min_str_neib_fpn 0.35
this.pwise_log_path = gd.getNextString(); this.pwise_log_path = gd.getNextString();
this.pwise_debug = (int) gd.getNextNumber(); this.pwise_debug = (int) gd.getNextNumber();
this.alt_overwrite = gd.getNextBoolean();
this.alt_pairwise = gd.getNextBoolean();
this.alt_sigma = gd.getNextNumber();
this.alt_abs_outliers = gd.getNextNumber();
this.alt_outliers = gd.getNextNumber();
this.alt_refine = (int) gd.getNextNumber();
this.pmap_move_only = gd.getNextBoolean(); this.pmap_move_only = gd.getNextBoolean();
this.pmap_ignore_affines = gd.getNextBoolean(); this.pmap_ignore_affines = gd.getNextBoolean();
this.pmap_use_inv = gd.getNextBoolean(); this.pmap_use_inv = gd.getNextBoolean();
...@@ -1940,11 +1969,15 @@ min_str_neib_fpn 0.35 ...@@ -1940,11 +1969,15 @@ min_str_neib_fpn 0.35
this.flt_filt_zoom = gd.getNextBoolean(); this.flt_filt_zoom = gd.getNextBoolean();
this.flt_min_zoom = (int) gd.getNextNumber(); this.flt_min_zoom = (int) gd.getNextNumber();
this.flt_max_zoom = (int) gd.getNextNumber(); this.flt_max_zoom = (int) gd.getNextNumber();
this.flt_min_sfm = gd.getNextNumber();
this.flt_max_sfm = gd.getNextNumber();
this.flt_alt = gd.getNextChoiceIndex();
this.flt_show_names = gd.getNextBoolean(); this.flt_show_names = gd.getNextBoolean();
this.flt_show_overlaps = gd.getNextBoolean(); this.flt_show_overlaps = gd.getNextBoolean();
this.flt_show_rms = gd.getNextBoolean(); this.flt_show_rms = gd.getNextBoolean();
this.flt_show_zoom = gd.getNextBoolean(); this.flt_show_zoom = gd.getNextBoolean();
this.flt_show_alt = gd.getNextBoolean();
this.patt_save_top= gd.getNextString(); this.patt_save_top= gd.getNextString();
this.patt_save_subdir = gd.getNextString(); this.patt_save_subdir = gd.getNextString();
...@@ -2489,6 +2522,13 @@ min_str_neib_fpn 0.35 ...@@ -2489,6 +2522,13 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"pwise_log_path", this.pwise_log_path + ""); // String properties.setProperty(prefix+"pwise_log_path", this.pwise_log_path + ""); // String
properties.setProperty(prefix+"pwise_debug", this.pwise_debug + ""); // int properties.setProperty(prefix+"pwise_debug", this.pwise_debug + ""); // int
properties.setProperty(prefix+"alt_overwrite", this.alt_overwrite + ""); // boolean
properties.setProperty(prefix+"alt_pairwise", this.alt_pairwise + ""); // boolean
properties.setProperty(prefix+"alt_sigma", this.alt_sigma + ""); // double
properties.setProperty(prefix+"alt_abs_outliers", this.alt_abs_outliers + ""); // double
properties.setProperty(prefix+"alt_outliers", this.alt_outliers + ""); // double
properties.setProperty(prefix+"alt_refine", this.alt_refine + ""); // int
properties.setProperty(prefix+"pmap_move_only", this.pmap_move_only + ""); // boolean properties.setProperty(prefix+"pmap_move_only", this.pmap_move_only + ""); // boolean
properties.setProperty(prefix+"pmap_ignore_affines", this.pmap_ignore_affines + ""); // boolean properties.setProperty(prefix+"pmap_ignore_affines", this.pmap_ignore_affines + ""); // boolean
properties.setProperty(prefix+"pmap_use_inv", this.pmap_use_inv + ""); // boolean properties.setProperty(prefix+"pmap_use_inv", this.pmap_use_inv + ""); // boolean
...@@ -2523,10 +2563,14 @@ min_str_neib_fpn 0.35 ...@@ -2523,10 +2563,14 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"flt_filt_zoom", this.flt_filt_zoom + ""); // boolean properties.setProperty(prefix+"flt_filt_zoom", this.flt_filt_zoom + ""); // boolean
properties.setProperty(prefix+"flt_min_zoom", this.flt_min_zoom + ""); // int properties.setProperty(prefix+"flt_min_zoom", this.flt_min_zoom + ""); // int
properties.setProperty(prefix+"flt_max_zoom", this.flt_max_zoom + ""); // int properties.setProperty(prefix+"flt_max_zoom", this.flt_max_zoom + ""); // int
properties.setProperty(prefix+"flt_min_sfm", this.flt_min_sfm + ""); // double
properties.setProperty(prefix+"flt_max_sfm", this.flt_max_sfm + ""); // double
properties.setProperty(prefix+"flt_alt", this.flt_alt + ""); // int
properties.setProperty(prefix+"flt_show_names", this.flt_show_names + ""); // boolean properties.setProperty(prefix+"flt_show_names", this.flt_show_names + ""); // boolean
properties.setProperty(prefix+"flt_show_overlaps", this.flt_show_overlaps + ""); // boolean properties.setProperty(prefix+"flt_show_overlaps", this.flt_show_overlaps + ""); // boolean
properties.setProperty(prefix+"flt_show_rms", this.flt_show_rms + ""); // boolean properties.setProperty(prefix+"flt_show_rms", this.flt_show_rms + ""); // boolean
properties.setProperty(prefix+"flt_show_zoom", this.flt_show_zoom + ""); // boolean properties.setProperty(prefix+"flt_show_zoom", this.flt_show_zoom + ""); // boolean
properties.setProperty(prefix+"flt_show_alt", this.flt_show_alt + ""); // boolean
properties.setProperty(prefix+"patt_save_top", this.patt_save_top + ""); // String properties.setProperty(prefix+"patt_save_top", this.patt_save_top + ""); // String
properties.setProperty(prefix+"patt_save_subdir", this.patt_save_subdir + ""); // String properties.setProperty(prefix+"patt_save_subdir", this.patt_save_subdir + ""); // String
...@@ -3037,6 +3081,13 @@ min_str_neib_fpn 0.35 ...@@ -3037,6 +3081,13 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"pwise_log_path")!=null) this.pwise_log_path=(String) properties.getProperty(prefix+ "pwise_log_path"); if (properties.getProperty(prefix+"pwise_log_path")!=null) this.pwise_log_path=(String) properties.getProperty(prefix+ "pwise_log_path");
if (properties.getProperty(prefix+"pwise_debug")!=null) this.pwise_debug=Integer.parseInt(properties.getProperty(prefix+ "pwise_debug")); if (properties.getProperty(prefix+"pwise_debug")!=null) this.pwise_debug=Integer.parseInt(properties.getProperty(prefix+ "pwise_debug"));
if (properties.getProperty(prefix+"alt_overwrite")!=null) this.alt_overwrite=Boolean.parseBoolean(properties.getProperty(prefix+ "alt_overwrite"));
if (properties.getProperty(prefix+"alt_pairwise")!=null) this.alt_pairwise=Boolean.parseBoolean(properties.getProperty(prefix+ "alt_pairwise"));
if (properties.getProperty(prefix+"alt_sigma")!=null) this.alt_sigma=Double.parseDouble(properties.getProperty(prefix+ "alt_sigma"));
if (properties.getProperty(prefix+"alt_abs_outliers")!=null) this.alt_abs_outliers=Double.parseDouble(properties.getProperty(prefix+ "alt_abs_outliers"));
if (properties.getProperty(prefix+"alt_outliers")!=null) this.alt_outliers=Double.parseDouble(properties.getProperty(prefix+ "alt_outliers"));
if (properties.getProperty(prefix+"alt_refine")!=null) this.alt_refine=Integer.parseInt(properties.getProperty(prefix+ "alt_refine"));
if (properties.getProperty(prefix+"pmap_move_only")!=null) this.pmap_move_only=Boolean.parseBoolean(properties.getProperty(prefix+ "pmap_move_only")); if (properties.getProperty(prefix+"pmap_move_only")!=null) this.pmap_move_only=Boolean.parseBoolean(properties.getProperty(prefix+ "pmap_move_only"));
if (properties.getProperty(prefix+"pmap_ignore_affines")!=null)this.pmap_ignore_affines=Boolean.parseBoolean(properties.getProperty(prefix+"pmap_ignore_affines")); if (properties.getProperty(prefix+"pmap_ignore_affines")!=null)this.pmap_ignore_affines=Boolean.parseBoolean(properties.getProperty(prefix+"pmap_ignore_affines"));
if (properties.getProperty(prefix+"pmap_use_inv")!=null) this.pmap_use_inv=Boolean.parseBoolean(properties.getProperty(prefix+ "pmap_use_inv")); if (properties.getProperty(prefix+"pmap_use_inv")!=null) this.pmap_use_inv=Boolean.parseBoolean(properties.getProperty(prefix+ "pmap_use_inv"));
...@@ -3065,17 +3116,20 @@ min_str_neib_fpn 0.35 ...@@ -3065,17 +3116,20 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"flt_undef_only")!= null) this.flt_undef_only= Boolean.parseBoolean(properties.getProperty(prefix+"flt_undef_only")); if (properties.getProperty(prefix+"flt_undef_only")!= null) this.flt_undef_only= Boolean.parseBoolean(properties.getProperty(prefix+"flt_undef_only"));
if (properties.getProperty(prefix+"flt_min_overlap")!= null) this.flt_min_overlap= Double.parseDouble(properties.getProperty(prefix+ "flt_min_overlap")); if (properties.getProperty(prefix+"flt_min_overlap")!= null) this.flt_min_overlap= Double.parseDouble(properties.getProperty(prefix+ "flt_min_overlap"));
if (properties.getProperty(prefix+"flt_max_overlapc")!= null) this.flt_max_overlap= Double.parseDouble(properties.getProperty(prefix+ "flt_max_overlap")); if (properties.getProperty(prefix+"flt_max_overlapc")!= null) this.flt_max_overlap= Double.parseDouble(properties.getProperty(prefix+ "flt_max_overlap"));
if (properties.getProperty(prefix+"flt_min_rms_sec")!= null) this.flt_min_rms= Double.parseDouble(properties.getProperty(prefix+ "flt_min_rms")); if (properties.getProperty(prefix+"flt_min_rms")!= null) this.flt_min_rms= Double.parseDouble(properties.getProperty(prefix+ "flt_min_rms"));
if (properties.getProperty(prefix+"flt_max_rms_sec")!= null) this.flt_max_rms= Double.parseDouble(properties.getProperty(prefix+ "flt_max_rms")); if (properties.getProperty(prefix+"flt_max_rms")!= null) this.flt_max_rms= Double.parseDouble(properties.getProperty(prefix+ "flt_max_rms"));
if (properties.getProperty(prefix+"flt_nan_rms")!= null) this.flt_nan_rms= Boolean.parseBoolean(properties.getProperty(prefix+"flt_nan_rms")); if (properties.getProperty(prefix+"flt_nan_rms")!= null) this.flt_nan_rms= Boolean.parseBoolean(properties.getProperty(prefix+"flt_nan_rms"));
if (properties.getProperty(prefix+"flt_filt_zoom")!= null) this.flt_filt_zoom= Boolean.parseBoolean(properties.getProperty(prefix+"flt_filt_zoom")); if (properties.getProperty(prefix+"flt_filt_zoom")!= null) this.flt_filt_zoom= Boolean.parseBoolean(properties.getProperty(prefix+"flt_filt_zoom"));
if (properties.getProperty(prefix+"flt_min_zoom")!= null) this.flt_min_zoom= Integer.parseInt(properties.getProperty(prefix+ "flt_min_zoom")); if (properties.getProperty(prefix+"flt_min_zoom")!= null) this.flt_min_zoom= Integer.parseInt(properties.getProperty(prefix+ "flt_min_zoom"));
if (properties.getProperty(prefix+"flt_max_zoom")!= null) this.flt_max_zoom= Integer.parseInt(properties.getProperty(prefix+ "flt_max_zoom")); if (properties.getProperty(prefix+"flt_max_zoom")!= null) this.flt_max_zoom= Integer.parseInt(properties.getProperty(prefix+ "flt_max_zoom"));
if (properties.getProperty(prefix+"flt_min_sfm")!= null) this.flt_min_sfm= Double.parseDouble(properties.getProperty(prefix+ "flt_min_sfm"));
if (properties.getProperty(prefix+"flt_max_sfm")!= null) this.flt_max_sfm= Double.parseDouble(properties.getProperty(prefix+ "flt_max_sfm"));
if (properties.getProperty(prefix+"flt_alt")!= null) this.flt_alt= Integer.parseInt(properties.getProperty(prefix+ "flt_alt"));
if (properties.getProperty(prefix+"flt_show_names")!= null) this.flt_show_names= Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_names")); if (properties.getProperty(prefix+"flt_show_names")!= null) this.flt_show_names= Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_names"));
if (properties.getProperty(prefix+"flt_show_overlaps")!=null) this.flt_show_overlaps=Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_overlaps")); if (properties.getProperty(prefix+"flt_show_overlaps")!=null) this.flt_show_overlaps=Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_overlaps"));
if (properties.getProperty(prefix+"flt_show_rms")!= null) this.flt_show_rms= Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_rms")); if (properties.getProperty(prefix+"flt_show_rms")!= null) this.flt_show_rms= Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_rms"));
if (properties.getProperty(prefix+"flt_show_zoom")!= null) this.flt_show_zoom= Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_zoom")); if (properties.getProperty(prefix+"flt_show_zoom")!= null) this.flt_show_zoom= Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_zoom"));
if (properties.getProperty(prefix+"flt_show_alt")!= null) this.flt_show_alt= Boolean.parseBoolean(properties.getProperty(prefix+"flt_show_alt"));
if (properties.getProperty(prefix+"patt_save_top")!=null) this.patt_save_top=(String) properties.getProperty(prefix+ "patt_save_top"); if (properties.getProperty(prefix+"patt_save_top")!=null) this.patt_save_top=(String) properties.getProperty(prefix+ "patt_save_top");
if (properties.getProperty(prefix+"patt_save_subdir")!=null) this.patt_save_subdir=(String) properties.getProperty(prefix+ "patt_save_subdir"); if (properties.getProperty(prefix+"patt_save_subdir")!=null) this.patt_save_subdir=(String) properties.getProperty(prefix+ "patt_save_subdir");
...@@ -3607,6 +3661,13 @@ min_str_neib_fpn 0.35 ...@@ -3607,6 +3661,13 @@ min_str_neib_fpn 0.35
imp.pwise_log_path = this.pwise_log_path; imp.pwise_log_path = this.pwise_log_path;
imp.pwise_debug = this.pwise_debug; imp.pwise_debug = this.pwise_debug;
imp.alt_overwrite = this.alt_overwrite;
imp.alt_pairwise = this.alt_pairwise;
imp.alt_sigma = this.alt_sigma;
imp.alt_abs_outliers = this.alt_abs_outliers;
imp.alt_outliers = this.alt_outliers;
imp.alt_refine = this.alt_refine;
imp.pmap_move_only = this.pmap_move_only; imp.pmap_move_only = this.pmap_move_only;
imp.pmap_ignore_affines = this.pmap_ignore_affines; imp.pmap_ignore_affines = this.pmap_ignore_affines;
imp.pmap_use_inv = this.pmap_use_inv; imp.pmap_use_inv = this.pmap_use_inv;
...@@ -3641,10 +3702,17 @@ min_str_neib_fpn 0.35 ...@@ -3641,10 +3702,17 @@ min_str_neib_fpn 0.35
imp.flt_filt_zoom = this.flt_filt_zoom; imp.flt_filt_zoom = this.flt_filt_zoom;
imp.flt_min_zoom = this.flt_min_zoom; imp.flt_min_zoom = this.flt_min_zoom;
imp.flt_max_zoom = this.flt_max_zoom; imp.flt_max_zoom = this.flt_max_zoom;
imp.flt_min_sfm = this.flt_min_sfm;
imp.flt_max_sfm = this.flt_max_sfm;
imp.flt_alt = this.flt_alt;
imp.flt_show_names = this.flt_show_names; imp.flt_show_names = this.flt_show_names;
imp.flt_show_overlaps = this.flt_show_overlaps; imp.flt_show_overlaps = this.flt_show_overlaps;
imp.flt_show_rms = this.flt_show_rms; imp.flt_show_rms = this.flt_show_rms;
imp.flt_show_zoom = this.flt_show_zoom; imp.flt_show_zoom = this.flt_show_zoom;
imp.flt_show_alt = this.flt_show_alt;
imp.patt_save_top = this.patt_save_top; imp.patt_save_top = this.patt_save_top;
imp.patt_save_subdir = this.patt_save_subdir; imp.patt_save_subdir = this.patt_save_subdir;
......
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