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

Next snapshot, working onpairs selection and LMA map

parent c3505d27
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -849,6 +849,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
			addButton("Read Tiff",  panelLWIRWorld, color_process);
			addButton("Read Tiff",  panelLWIRWorld, color_process);
			addButton("Test video",  panelLWIRWorld, color_process);
			addButton("Test video",  panelLWIRWorld, color_process);
			addButton("Ortho Pairs",  panelLWIRWorld, color_process);
			addButton("Ortho Pairs",  panelLWIRWorld, color_process);
			addButton("Manual pair",  panelLWIRWorld, color_process);
			addButton("Extract Objects",  panelLWIRWorld, color_process);
			addButton("Extract Objects",  panelLWIRWorld, color_process);
			addButton("Mismatched resolutions",  panelLWIRWorld, color_process);
			addButton("Mismatched resolutions",  panelLWIRWorld, color_process);
			addButton("Generate DATI",  panelLWIRWorld, color_process);
			addButton("Generate DATI",  panelLWIRWorld, color_process);
@@ -5709,7 +5710,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
				e.printStackTrace();
				e.printStackTrace();
			}
			}
//			ComboMatch.testReadTiff();
//			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;
			DEBUG_LEVEL = MASTER_DEBUG_LEVEL;
			EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
			EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL);
			if (GPU_TILE_PROCESSOR == null) {
			if (GPU_TILE_PROCESSOR == null) {
@@ -5731,6 +5732,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
					CLT_PARAMETERS,     // CLTParameters    clt_parameters,
					CLT_PARAMETERS,     // CLTParameters    clt_parameters,
					GPU_TILE_PROCESSOR,
					GPU_TILE_PROCESSOR,
					label.equals("Extract Objects"), // boolean    extract_mines,
					label.equals("Extract Objects"), // boolean    extract_mines,
					label.equals("Manual pair"), // boolean          manual_pair,
					DEBUG_LEVEL);
					DEBUG_LEVEL);
		} else if (label.equals("Test video")) {
		} else if (label.equals("Test video")) {
			ImagePlus imp_sel = WindowManager.getCurrentImage();
			ImagePlus imp_sel = WindowManager.getCurrentImage();
+2 −1
Original line number Original line Diff line number Diff line
@@ -61,6 +61,7 @@ public class ComboMatch {
			 CLTParameters    clt_parameters,
			 CLTParameters    clt_parameters,
			 GPUTileProcessor gpu_tile_processor, // initialized by the caller
			 GPUTileProcessor gpu_tile_processor, // initialized by the caller
			 boolean          extract_objects,
			 boolean          extract_objects,
			 boolean          manual_pair,
			 int              debugLevel) {
			 int              debugLevel) {
		boolean create_kernels = debugLevel>1000;
		boolean create_kernels = debugLevel>1000;
		if (create_kernels) {
		if (create_kernels) {
@@ -70,7 +71,7 @@ public class ComboMatch {
		GPU_TILE_PROCESSOR = gpu_tile_processor;
		GPU_TILE_PROCESSOR = gpu_tile_processor;
		PairwiseOrthoMatch pairwiseOrthoMatch = null;
		PairwiseOrthoMatch pairwiseOrthoMatch = null;
		String [] pair_names = new String[2];
		String [] pair_names = new String[2];
		ImagePlus imp_sel = WindowManager.getCurrentImage();
		ImagePlus imp_sel = manual_pair? WindowManager.getCurrentImage() : null;
		String [] gpu_spair = null;
		String [] gpu_spair = null;
		boolean use_marked_image =    false; // will be set if found
		boolean use_marked_image =    false; // will be set if found
		String [] all_scenes = null;
		String [] all_scenes = null;
+136 −0
Original line number Original line Diff line number Diff line
@@ -21,9 +21,11 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.List;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicInteger;


@@ -5230,6 +5232,19 @@ public class OrthoMapsCollection implements Serializable{
		heur =             (int) gd.getNextNumber();
		heur =             (int) gd.getNextNumber();
		use_multi =              gd.getNextBoolean();
		use_multi =              gd.getNextBoolean();
		double max_rmse_reuse= max_rms_refine;
		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(
		PairsGraph  pairsGraph = new PairsGraph(
				this,             // OrthoMapsCollection orthoMapsCollection,
				this,             // OrthoMapsCollection orthoMapsCollection,
				indices,          // int []  indices,
				indices,          // int []  indices,
@@ -5237,6 +5252,13 @@ public class OrthoMapsCollection implements Serializable{
				max_rmse_reuse,   // double  max_rmse_reuse,
				max_rmse_reuse,   // double  max_rmse_reuse,
				use_multi,        // boolean multi,
				use_multi,        // boolean multi,
				debugLevel);      // int     debugLevel);
				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) {
		if (dry_run) {
			return pairsGraph.dryRun(
			return pairsGraph.dryRun(
@@ -6184,4 +6206,118 @@ public class OrthoMapsCollection implements Serializable{
		ImageDtt.startAndJoin(threads);
		ImageDtt.startAndJoin(threads);
		return overlaps;
		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;
	}
	
}
}
+62 −21
Original line number Original line Diff line number Diff line
@@ -221,6 +221,8 @@ public class OrthoMultiLMA {
			String              orthoMapsCollection_path
			String              orthoMapsCollection_path
			) {
			) {
		boolean all_pairs =      true;
		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 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;
        boolean use_inv =        clt_parameters.imp.pmap_use_inv;        // 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);
		GenericJTabbedDialog gd = new GenericJTabbedDialog("Pairwise Match Parameters",1200,400);
		gd.addCheckbox    ("Use all available pairs",  all_pairs,  "Use all available pairs.");
		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    ("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.");
@@ -252,6 +256,8 @@ public class OrthoMultiLMA {
 		gd.showDialog();
 		gd.showDialog();
		if (gd.wasCanceled()) return -1;
		if (gd.wasCanceled()) return -1;
		all_pairs =           gd.getNextBoolean();
		all_pairs =           gd.getNextBoolean();
		min_overlap_frac =    gd.getNextNumber(); 
 		max_rms_refine   =    gd.getNextNumber();
        move_only =		      gd.getNextBoolean();
        move_only =		      gd.getNextBoolean();
        ignore_affines =      gd.getNextBoolean();
        ignore_affines =      gd.getNextBoolean();
        use_inv =             gd.getNextBoolean();
        use_inv =             gd.getNextBoolean();
@@ -270,6 +276,10 @@ public class OrthoMultiLMA {
				maps_collection,          // OrthoMapsCollection maps_collection,
				maps_collection,          // OrthoMapsCollection maps_collection,
				orthoMapsCollection_path, // String              orthoMapsCollection_path,
				orthoMapsCollection_path, // String              orthoMapsCollection_path,
				all_pairs,                // boolean             all_pairs,
				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,
				move_only,                // boolean             move_only,
				ignore_affines,           // boolean             ignore_affines,
				ignore_affines,           // boolean             ignore_affines,
				use_inv,                  // boolean             use_inv,
				use_inv,                  // boolean             use_inv,
@@ -288,6 +298,9 @@ public class OrthoMultiLMA {
				OrthoMapsCollection maps_collection,
				OrthoMapsCollection maps_collection,
				String              orthoMapsCollection_path,
				String              orthoMapsCollection_path,
				boolean             all_pairs,
				boolean             all_pairs,
				double              min_overlap_frac,
				double              max_rms,
				
				boolean             move_only,
				boolean             move_only,
				boolean             ignore_affines,
				boolean             ignore_affines,
		        boolean             use_inv,
		        boolean             use_inv,
@@ -304,6 +317,7 @@ public class OrthoMultiLMA {
		boolean             corr_avg= (skew_pull > 0) || (tilt_pull > 0) || (scale_pull > 0);
		boolean             corr_avg= (skew_pull > 0) || (tilt_pull > 0) || (scale_pull > 0);
		int [] indices = null;
		int [] indices = null;
		if (all_pairs) {
		if (all_pairs) {
			/*
			boolean [] used_scenes = new boolean [maps_collection.ortho_maps.length];
			boolean [] used_scenes = new boolean [maps_collection.ortho_maps.length];
			for (int scene0 = 0; scene0 < (used_scenes.length-1); scene0++) {
			for (int scene0 = 0; scene0 < (used_scenes.length-1); scene0++) {
				Set<String> match_names = maps_collection.ortho_maps[scene0].pairwise_matches.keySet();
				Set<String> match_names = maps_collection.ortho_maps[scene0].pairwise_matches.keySet();
@@ -328,11 +342,25 @@ public class OrthoMultiLMA {
			if (debugLevel > -1) {
			if (debugLevel > -1) {
				System.out.println("buildOrthoMap(): got "+indices.length+" scenes with pairs");
				System.out.println("buildOrthoMap(): got "+indices.length+" scenes with pairs");
			}
			}
			*/
		} else {
		} else {
			indices = maps_collection.getScenesSelection(
			indices = maps_collection.getScenesSelection(
					null, // boolean select_all,
					null, // boolean select_all,
					" to build a map with LMA from pair-wise matches"); // String purpose)
					" 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(
		OrthoMultiLMA oml = new OrthoMultiLMA(
				corr_avg,
				corr_avg,
				move_only);
				move_only);
@@ -345,6 +373,7 @@ public class OrthoMultiLMA {
				clt_parameters,   // CLTParameters       clt_parameters,
				clt_parameters,   // CLTParameters       clt_parameters,
				maps_collection,  // OrthoMapsCollection maps_collection,
				maps_collection,  // OrthoMapsCollection maps_collection,
				indices,          // int []              indices,
				indices,          // int []              indices,
				defined_pairs, // int [][]            pairs, // or null? condensed
				ignore_affines,   // boolean             ignore_affines,
				ignore_affines,   // boolean             ignore_affines,
				val_coord,        // double []           val_coord, // 1 - valid, 0 - invalid, minimize coordinates errors
				val_coord,        // double []           val_coord, // 1 - valid, 0 - invalid, minimize coordinates errors
				position_pull,    // double              position_pull,
				position_pull,    // double              position_pull,
@@ -442,6 +471,7 @@ public class OrthoMultiLMA {
			CLTParameters       clt_parameters,
			CLTParameters       clt_parameters,
			OrthoMapsCollection maps_collection,
			OrthoMapsCollection maps_collection,
			int []              indices,
			int []              indices,
			int [][]            pairs_pre, // or null?
			boolean             ignore_affines,
			boolean             ignore_affines,
			double []           val_coord, // 1 - valid, 0 - invalid, minimize coordinates errors
			double []           val_coord, // 1 - valid, 0 - invalid, minimize coordinates errors
			double              position_pull,
			double              position_pull,
@@ -456,6 +486,16 @@ public class OrthoMultiLMA {
		matches = new PairwiseOrthoMatch[indices.length][indices.length];
		matches = new PairwiseOrthoMatch[indices.length][indices.length];
		ArrayList<Point> pairs_list = new ArrayList<Point>();
		ArrayList<Point> pairs_list = new ArrayList<Point>();
//		ArrayList<Double> offset_list = new ArrayList<Double>();
//		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());
				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++) {
			for (int i = 0; i < num_scenes-1; i++) {
				int scene0 = indices[i]; 
				int scene0 = indices[i]; 
				for (int j = i+1; j < num_scenes; j++){
				for (int j = i+1; j < num_scenes; j++){
@@ -482,6 +522,7 @@ public class OrthoMultiLMA {
					}
					}
				}
				}
			}
			}
		}
		num_pairs = pairs_list.size();
		num_pairs = pairs_list.size();
		offsets = new double [num_pairs][2];
		offsets = new double [num_pairs][2];
		pairs =   new int[num_pairs][2];
		pairs =   new int[num_pairs][2];
+45 −0
Original line number Original line Diff line number Diff line
@@ -54,6 +54,7 @@ public class PairsGraph {
	private final int         debugLevel;
	private final int         debugLevel;
	private boolean           multi; // use single-threaded in debug mode?
	private boolean           multi; // use single-threaded in debug mode?


	
	public PairsGraph (
	public PairsGraph (
			OrthoMapsCollection orthoMapsCollection,
			OrthoMapsCollection orthoMapsCollection,
			int []  indices,
			int []  indices,
@@ -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() {
	public int getNumberOfGroups() {
		HashSet<Integer> hs = new HashSet<Integer>();
		HashSet<Integer> hs = new HashSet<Integer>();
		for (int i:groups) {
		for (int i:groups) {
Loading