Commit 2f51f8e6 authored by Andrey Filippov's avatar Andrey Filippov

Next snapshot, working onpairs selection and LMA map

parent c3505d27
......@@ -849,6 +849,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
addButton("Read Tiff", panelLWIRWorld, color_process);
addButton("Test video", panelLWIRWorld, color_process);
addButton("Ortho Pairs", panelLWIRWorld, color_process);
addButton("Manual pair", panelLWIRWorld, color_process);
addButton("Extract Objects", panelLWIRWorld, color_process);
addButton("Mismatched resolutions", panelLWIRWorld, color_process);
addButton("Generate DATI", panelLWIRWorld, color_process);
......@@ -5709,7 +5710,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
e.printStackTrace();
}
// ComboMatch.testReadTiff();
} else if (label.equals("Ortho Pairs") || label.equals("Extract Objects")) {
} else if (label.equals("Ortho Pairs") || label.equals("Extract Objects") || label.equals("Manual pair")) {
DEBUG_LEVEL = MASTER_DEBUG_LEVEL;
EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
if (GPU_TILE_PROCESSOR == null) {
......@@ -5731,6 +5732,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
CLT_PARAMETERS, // CLTParameters clt_parameters,
GPU_TILE_PROCESSOR,
label.equals("Extract Objects"), // boolean extract_mines,
label.equals("Manual pair"), // boolean manual_pair,
DEBUG_LEVEL);
} else if (label.equals("Test video")) {
ImagePlus imp_sel = WindowManager.getCurrentImage();
......
......@@ -61,6 +61,7 @@ public class ComboMatch {
CLTParameters clt_parameters,
GPUTileProcessor gpu_tile_processor, // initialized by the caller
boolean extract_objects,
boolean manual_pair,
int debugLevel) {
boolean create_kernels = debugLevel>1000;
if (create_kernels) {
......@@ -70,7 +71,7 @@ public class ComboMatch {
GPU_TILE_PROCESSOR = gpu_tile_processor;
PairwiseOrthoMatch pairwiseOrthoMatch = null;
String [] pair_names = new String[2];
ImagePlus imp_sel = WindowManager.getCurrentImage();
ImagePlus imp_sel = manual_pair? WindowManager.getCurrentImage() : null;
String [] gpu_spair = null;
boolean use_marked_image = false; // will be set if found
String [] all_scenes = null;
......
......@@ -21,9 +21,11 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
......@@ -5230,6 +5232,19 @@ public class OrthoMapsCollection implements Serializable{
heur = (int) gd.getNextNumber();
use_multi = gd.getNextBoolean();
double max_rmse_reuse= max_rms_refine;
int [][] pairs_defined = filterPairs(
indices, // int [] indices_in,
min_overlap_frac, // double min_overlap_frac,
max_rmse_reuse, // double max_rmse,
true, // boolean max_resolution,
null); // int [][] remove_pairs
int [][] pairs_undefined = filterPairs(
indices, // int [] indices_in,
min_overlap_frac, // double min_overlap_frac,
0, // max_rmse_reuse, // double max_rmse,
false, // boolean max_resolution,
pairs_defined); // int [][] remove_pairs
/*
PairsGraph pairsGraph = new PairsGraph(
this, // OrthoMapsCollection orthoMapsCollection,
indices, // int [] indices,
......@@ -5237,6 +5252,13 @@ public class OrthoMapsCollection implements Serializable{
max_rmse_reuse, // double max_rmse_reuse,
use_multi, // boolean multi,
debugLevel); // int debugLevel);
*/
PairsGraph pairsGraph = new PairsGraph(
this, // OrthoMapsCollection orthoMapsCollection,
pairs_undefined, // int [][] undefined_pairs,
pairs_defined, // int [][] defined_pairs,
use_multi, // boolean multi,
debugLevel); // int debugLevel);
if (dry_run) {
return pairsGraph.dryRun(
......@@ -6184,4 +6206,118 @@ public class OrthoMapsCollection implements Serializable{
ImageDtt.startAndJoin(threads);
return overlaps;
}
public int [][] filterPairs(
int [] indices_in,
double min_overlap_frac,
double max_rmse,
boolean max_resolution, // require defined and full resolution
int [][] remove_pairs) {
if (indices_in == null) {
indices_in = new int [ortho_maps.length];
for (int i = 0; i < indices_in.length; i++) {
indices_in[i] = i;
}
}
boolean [] used_scenes = new boolean [ortho_maps.length];
for (int i:indices_in) {
used_scenes[i] = true;
}
HashSet <Point> donotuse_set = new HashSet<Point>();
if (remove_pairs != null) {
for (int [] p: remove_pairs) {
donotuse_set.add(new Point(p[0],p[1]));
}
}
ArrayList<Point> pairs_list = new ArrayList<Point>();
for (int scene0:indices_in) {
Set<String> match_names = ortho_maps[scene0].pairwise_matches.keySet();
ArrayList<String> names_list = new ArrayList<String>();
names_list.addAll(match_names);
Collections.sort(names_list);
for (String scene1_name:names_list) {
PairwiseOrthoMatch match = ortho_maps[scene0].getMatch(scene1_name, !max_resolution); // may be not defined only
if (match != null) {
int scene1 = getIndex(scene1_name);
if ( used_scenes[scene1] && (!max_resolution || match.isDefined()) &&
(match.getOverlap() >= min_overlap_frac) &&
((max_rmse <= 0) || (match.getRMS() <= max_rmse))
){
if (max_resolution) {
int min_zoom = Math.min(ortho_maps[scene0].getOriginalZoomLevel(), ortho_maps[scene1].getOriginalZoomLevel());
if (match.getZoomLevel() < min_zoom) {
continue;
}
}
Point p = new Point(scene0, scene1);
if (remove_pairs != null) {
if (donotuse_set.contains(p)) {
continue;
}
}
System.out.println(String.format("%5d: %3d-%3d, %7.4f, %7.4f",
pairs_list.size(), scene0, scene1, match.getOverlap(), match.getRMS()));
pairs_list.add(p);
}
}
}
}
int [][] pairs = new int [pairs_list.size()][2];
for (int i = 0; i < pairs.length; i++) {
Point p = pairs_list.get(i);
pairs[i][0] = p.x;
pairs[i][1] = p.y;
}
return pairs;
}
public int [] getScenesFromPairs(
int [][] pairs,
int [] indices_in) { // preselected indices or null
boolean [] used_scenes = new boolean [ortho_maps.length];
if (indices_in != null) {
for (int i:indices_in) {
used_scenes[i] = true;
}
}
for (int [] p:pairs) {
used_scenes[p[0]] = true;
used_scenes[p[1]] = true;
}
int indx = 0;
for (int i = 0; i < used_scenes.length; i++) if (used_scenes[i]){
indx++;
}
int [] indices = new int [indx];
indx = 0;
for (int i = 0; i < used_scenes.length; i++) if (used_scenes[i]){
indices[indx++] = i;
}
return indices;
}
/**
* Re-index pairs to exclude scenes not present in indices[]
* @param pairs - array of start,end absolute scene numbers
* @param indices - ascending array of used scenes (or null - all scenes)
* @return re-indexed pairs, indices exclude scenes that are not in indices[]
*/
public int [][] condensePairs(
int [][] pairs_all,
int [] indices) {
if (indices == null) {
return pairs_all;
}
int [] reindex = new int [ortho_maps.length];
int [][] pairs = new int [pairs_all.length][2];
Arrays.fill(reindex, -1);
for (int i = 0; i < indices.length; i++) {
reindex[indices[i]] = i;
}
for (int i = 0; i < pairs.length; i++) {
pairs[i][0] = reindex[pairs_all[i][0]];
pairs[i][1] = reindex[pairs_all[i][1]];
}
return pairs;
}
}
......@@ -221,6 +221,8 @@ public class OrthoMultiLMA {
String orthoMapsCollection_path
) {
boolean all_pairs = true;
double min_overlap_frac = clt_parameters.imp.pwise_overlap; // 0.25;
double max_rms_refine = clt_parameters.imp.pwise_max_rms; // 0.35; //
boolean move_only = clt_parameters.imp.pmap_move_only; // false;
boolean ignore_affines = clt_parameters.imp.pmap_ignore_affines; // false;
boolean use_inv = clt_parameters.imp.pmap_use_inv; // false;
......@@ -236,6 +238,8 @@ public class OrthoMultiLMA {
GenericJTabbedDialog gd = new GenericJTabbedDialog("Pairwise Match Parameters",1200,400);
gd.addCheckbox ("Use all available pairs", all_pairs, "Use all available pairs.");
gd.addNumericField("Minimal overlap fraction", min_overlap_frac, 3,7,"", "Minimal overlap fraction.");
gd.addNumericField("Satisfactory RMSE, final", max_rms_refine,3,7,"scaled pix", "Maximal RMSE to consider match, in scaled pixels, during refine.");
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 ("Use reversed pairs", use_inv, "Use reversed (late-early timestamps) pairs.");
......@@ -252,6 +256,8 @@ public class OrthoMultiLMA {
gd.showDialog();
if (gd.wasCanceled()) return -1;
all_pairs = gd.getNextBoolean();
min_overlap_frac = gd.getNextNumber();
max_rms_refine = gd.getNextNumber();
move_only = gd.getNextBoolean();
ignore_affines = gd.getNextBoolean();
use_inv = gd.getNextBoolean();
......@@ -270,6 +276,10 @@ public class OrthoMultiLMA {
maps_collection, // OrthoMapsCollection maps_collection,
orthoMapsCollection_path, // String orthoMapsCollection_path,
all_pairs, // boolean all_pairs,
// filtering of the pairs
min_overlap_frac, // double min_overlap_frac,
max_rms_refine, // double max_rms,
move_only, // boolean move_only,
ignore_affines, // boolean ignore_affines,
use_inv, // boolean use_inv,
......@@ -288,6 +298,9 @@ public class OrthoMultiLMA {
OrthoMapsCollection maps_collection,
String orthoMapsCollection_path,
boolean all_pairs,
double min_overlap_frac,
double max_rms,
boolean move_only,
boolean ignore_affines,
boolean use_inv,
......@@ -304,6 +317,7 @@ public class OrthoMultiLMA {
boolean corr_avg= (skew_pull > 0) || (tilt_pull > 0) || (scale_pull > 0);
int [] indices = null;
if (all_pairs) {
/*
boolean [] used_scenes = new boolean [maps_collection.ortho_maps.length];
for (int scene0 = 0; scene0 < (used_scenes.length-1); scene0++) {
Set<String> match_names = maps_collection.ortho_maps[scene0].pairwise_matches.keySet();
......@@ -328,11 +342,25 @@ public class OrthoMultiLMA {
if (debugLevel > -1) {
System.out.println("buildOrthoMap(): got "+indices.length+" scenes with pairs");
}
*/
} else {
indices = maps_collection.getScenesSelection(
null, // boolean select_all,
" to build a map with LMA from pair-wise matches"); // String purpose)
}
int [][] pairs_defined_abs = maps_collection.filterPairs( // absolute indices
indices, // int [] indices_in,
min_overlap_frac, // double min_overlap_frac,
max_rms, // double max_rmse,
true, // boolean max_resolution,
null); // int [][] remove_pairs
indices= maps_collection.getScenesFromPairs(
pairs_defined_abs,// int [][] pairs,
null); // int [] indices_in) // preselected indices or null
int [][] defined_pairs = maps_collection.condensePairs (pairs_defined_abs,indices);
OrthoMultiLMA oml = new OrthoMultiLMA(
corr_avg,
move_only);
......@@ -345,6 +373,7 @@ public class OrthoMultiLMA {
clt_parameters, // CLTParameters clt_parameters,
maps_collection, // OrthoMapsCollection maps_collection,
indices, // int [] indices,
defined_pairs, // int [][] pairs, // or null? condensed
ignore_affines, // boolean ignore_affines,
val_coord, // double [] val_coord, // 1 - valid, 0 - invalid, minimize coordinates errors
position_pull, // double position_pull,
......@@ -442,6 +471,7 @@ public class OrthoMultiLMA {
CLTParameters clt_parameters,
OrthoMapsCollection maps_collection,
int [] indices,
int [][] pairs_pre, // or null?
boolean ignore_affines,
double [] val_coord, // 1 - valid, 0 - invalid, minimize coordinates errors
double position_pull,
......@@ -455,31 +485,42 @@ public class OrthoMultiLMA {
num_scenes = indices.length;
matches = new PairwiseOrthoMatch[indices.length][indices.length];
ArrayList<Point> pairs_list = new ArrayList<Point>();
// ArrayList<Double> offset_list = new ArrayList<Double>();
for (int i = 0; i < num_scenes-1; i++) {
int scene0 = indices[i];
for (int j = i+1; j < num_scenes; j++){
int scene1 = indices[j];
// ArrayList<Double> offset_list = new ArrayList<Double>();
if (pairs_pre != null) {
for (int [] pair:pairs_pre) {
int i = pair[0], j = pair[1];
int scene0=indices[i],scene1=indices[j];
PairwiseOrthoMatch match = maps_collection.ortho_maps[scene0].getMatch(maps_collection.ortho_maps[scene1].getName());
PairwiseOrthoMatch inv_match = use_inv?
maps_collection.ortho_maps[scene1].getMatch(maps_collection.ortho_maps[scene0].getName()):null;
if ((match != null) || (inv_match != null)){
if (match == null) {
double [] enuOffset = maps_collection.ortho_maps[scene0].enuOffsetTo(maps_collection.ortho_maps[scene1]);
double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image
match = inv_match.getInverse(rd);
matches[i][j] = match;
// matches[j][i] = inv_match;
pairs_list.add(new Point(i,j)); // only once?
}
} else {
for (int i = 0; i < num_scenes-1; i++) {
int scene0 = indices[i];
for (int j = i+1; j < num_scenes; j++){
int scene1 = indices[j];
PairwiseOrthoMatch match = maps_collection.ortho_maps[scene0].getMatch(maps_collection.ortho_maps[scene1].getName());
PairwiseOrthoMatch inv_match = use_inv?
maps_collection.ortho_maps[scene1].getMatch(maps_collection.ortho_maps[scene0].getName()):null;
if ((match != null) || (inv_match != null)){
if (match == null) {
double [] enuOffset = maps_collection.ortho_maps[scene0].enuOffsetTo(maps_collection.ortho_maps[scene1]);
double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image
match = inv_match.getInverse(rd);
}
if (inv_match == null) {
double [] enuOffset = maps_collection.ortho_maps[scene1].enuOffsetTo(maps_collection.ortho_maps[scene0]);
double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image
inv_match = match.getInverse(rd);
}
}
if (inv_match == null) {
double [] enuOffset = maps_collection.ortho_maps[scene1].enuOffsetTo(maps_collection.ortho_maps[scene0]);
double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image
inv_match = match.getInverse(rd);
if (match != null) {
matches[i][j] = match;
matches[j][i] = inv_match;
pairs_list.add(new Point(i,j)); // only once?
}
}
if (match != null) {
matches[i][j] = match;
matches[j][i] = inv_match;
pairs_list.add(new Point(i,j)); // only once?
}
}
}
num_pairs = pairs_list.size();
......
......@@ -53,6 +53,7 @@ public class PairsGraph {
private int [][] pairs;
private final int debugLevel;
private boolean multi; // use single-threaded in debug mode?
public PairsGraph (
OrthoMapsCollection orthoMapsCollection,
......@@ -121,6 +122,50 @@ public class PairsGraph {
}
}
public PairsGraph (
OrthoMapsCollection orthoMapsCollection,
int [][] undefined_pairs_all, // indices in orthoMapsCollection.ortho_maps[] (all scenes, not just selected)
int [][] defined_pairs_all, // indices in orthoMapsCollection.ortho_maps[] (all scenes, not just selected)
boolean multi,
int debugLevel) {
this.orthoMapsCollection = orthoMapsCollection;
int [] indices0 = orthoMapsCollection.getScenesFromPairs(undefined_pairs_all, null);
this.indices = orthoMapsCollection.getScenesFromPairs(defined_pairs_all, indices0);
int [][] undefined_pairs = orthoMapsCollection.condensePairs (undefined_pairs_all,indices);
int [][] defined_pairs = orthoMapsCollection.condensePairs (defined_pairs_all,indices);
this.debugLevel = debugLevel;
this.multi = multi;
pair_state = new int [indices.length][indices.length];
overlaps = new double [indices.length][indices.length];
timestamps = new double [indices.length];
groups = new int [indices.length];
dist = new int [indices.length][indices.length];
OrthoMap [] ortho_maps=orthoMapsCollection.getMaps();
for (int i = 0; i < indices.length; i++) {
groups[i] = i;
timestamps[i] = ortho_maps[indices[i]].getTimeStamp();
}
for (int [] u_pair: undefined_pairs) {
pair_state[u_pair[0]][u_pair[0]] = PAIR_UNDEFINED;
}
for (int [] d_pair: defined_pairs) {
pair_state[d_pair[0]][d_pair[0]] = PAIR_DEFINED;
recordPair(
d_pair, // int [] pair,
true, // boolean success,
multi);
}
pairs = multi? getPairsIndicesMulti():getPairsIndicesSingle();
if (debugLevel > -1) {
System.out.println("Number of scenes - "+indices.length);
System.out.println("Number of defined pairs - "+defined_pairs.length);
System.out.println("Number of undefined pairs - "+undefined_pairs.length);
System.out.println("Number of disconnected groups - "+getNumberOfGroups());
}
}
public int getNumberOfGroups() {
HashSet<Integer> hs = new HashSet<Integer>();
for (int i:groups) {
......
......@@ -228,6 +228,10 @@ public class PairwiseOrthoMatch implements Serializable {
return affine1;
}
public int getZoomLevel() {
return zoom_lev;
}
public double [][] getAffine(){
if (affine == null) {
return new double [][] {{1,0,0},{0,1,0}};
......
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