Commit 5e03168f authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Fixed affine inversion

parent 0da53711
Loading
Loading
Loading
Loading
+158 −15
Original line number Original line Diff line number Diff line
@@ -805,12 +805,26 @@ public class ComboMatch {
					int default_choice = 0;
					int default_choice = 0;
					int num_scene_lines = 50;
					int num_scene_lines = 50;
					String scene_name = 	maps_collection.selectOneScene(
					String scene_name = 	maps_collection.selectOneScene(
							0, // int num_scene,
							default_choice, // int default_choice,
							default_choice, // int default_choice,
							num_scene_lines); // int num_choice_lines)
							num_scene_lines); // int num_choice_lines)
					if (scene_name == null) {
					if (scene_name == null) {
						return false;
						return false;
					}
					}
					if (process_correlation) { // select a second image to match
						// select a second image and set gpu_spair
						int default_choice1 = 0;
						String scene_name1 = 	maps_collection.selectOneScene(
								1, // int num_scene,
								default_choice1, // int default_choice,
								num_scene_lines); // int num_choice_lines)
						if (scene_name1 == null) {
							return false;
						}
						gpu_spair = new String[] {scene_name, scene_name1};
					} else { // pattern match - single image
						gpu_spair = new String[] {scene_name};
						gpu_spair = new String[] {scene_name};
					}
				} else {
				} else {
					gpu_spair = new String[] {
					gpu_spair = new String[] {
							maps_collection.ortho_maps[available_pairs[pair][0]].getName(),
							maps_collection.ortho_maps[available_pairs[pair][0]].getName(),
@@ -818,15 +832,19 @@ public class ComboMatch {
				}
				}
        	}
        	}
        	int [] gpu_pair = new int[gpu_spair.length];
        	int [] gpu_pair = new int[gpu_spair.length];
        	for (int i = 0; i < gpu_pair.length; i++) {
        		gpu_pair[i] = maps_collection.getIndex(gpu_spair[i]);
        	}
        	int min_zoom_lev = maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel();
        	int min_zoom_lev = maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel();
        	int max_zoom_lev = maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel();
        	int max_zoom_lev = maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel();

        	double max_agl = maps_collection.ortho_maps[gpu_pair[0]].getAGL();
        	for (int i = 0; i < gpu_pair.length; i++) {
        	for (int i = 0; i < gpu_pair.length; i++) {
        		gpu_pair[i] = maps_collection.getIndex(gpu_spair[i]);
        		max_agl = Math.max(max_agl, maps_collection.ortho_maps[gpu_pair[i]].getAGL());
        		min_zoom_lev = Math.min(min_zoom_lev, maps_collection.ortho_maps[gpu_pair[i]].getOriginalZoomLevel());
        		min_zoom_lev = Math.min(min_zoom_lev, maps_collection.ortho_maps[gpu_pair[i]].getOriginalZoomLevel());
        		max_zoom_lev = Math.max(max_zoom_lev, maps_collection.ortho_maps[gpu_pair[i]].getOriginalZoomLevel());
        		max_zoom_lev = Math.max(max_zoom_lev, maps_collection.ortho_maps[gpu_pair[i]].getOriginalZoomLevel());
        		
        	}
        	}
        	double agl_ratio = max_agl/50.0;
        	double metric_error_adj = metric_error * agl_ratio * agl_ratio; // metric_error settings is good for 50m. Increase for higher Maybe squared?
        	int initial_zoom = max_zoom_lev - 4;  // another algorithm?
        	int initial_zoom = max_zoom_lev - 4;  // another algorithm?


        	System.out.println("Setting up GPU");
        	System.out.println("Setting up GPU");
@@ -849,7 +867,7 @@ public class ComboMatch {
    		double [][] affine1 = null;
    		double [][] affine1 = null;


        	if (gpu_spair.length < 2) {
        	if (gpu_spair.length < 2) {
        		System.out.println("Selected a single image");
        		System.out.println("Selected a single image, not a pair");
    			double [][][] affines = {affine0}; // or use affine1 = null as second?
    			double [][][] affines = {affine0}; // or use affine1 = null as second?
				if (pattern_match) {
				if (pattern_match) {
					ImagePlus imp_pat_match = maps_collection.patternMatchDualWrap (
					ImagePlus imp_pat_match = maps_collection.patternMatchDualWrap (
@@ -860,9 +878,23 @@ public class ComboMatch {
					//						imp_pat_match.show();
					//						imp_pat_match.show();
				}
				}
        		
        		
        	} else {
        		if (process_correlation && !use_marked_image) { // match may or may not exist
        			// if match exists - ask if use it. If not - open dialog and start spiral
        			pairwiseOrthoMatch = initialPairAdjust(
        					clt_parameters,  // CLTParameters       clt_parameters,
        					maps_collection, // OrthoMapsCollection maps_collection,
        					frac_remove,     // double              frac_remove, //  =        0.25
        					metric_error_adj,// double              metric_error,
        					gpu_spair,       // String[]            gpu_spair,
        					debugLevel);     // int                 debugLevel)
        			if (pairwiseOrthoMatch == null) { // if OK - either match existed or created by SpiralMatch()
        				return false;
        			}
        		} else {
        		} else {
        			pairwiseOrthoMatch = maps_collection.ortho_maps[gpu_pair[0]].getMatch(
        			pairwiseOrthoMatch = maps_collection.ortho_maps[gpu_pair[0]].getMatch(
        					maps_collection.ortho_maps[gpu_pair[1]].getName());
        					maps_collection.ortho_maps[gpu_pair[1]].getName());
        		}
        		if (pairwiseOrthoMatch == null) {
        		if (pairwiseOrthoMatch == null) {
        			System.out.println("No correlation data is available for pairs "+gpu_spair[0]+
        			System.out.println("No correlation data is available for pairs "+gpu_spair[0]+
        					" - "+gpu_spair[1]+" need to implement/search reverse,  a spiral search or restart command");
        					" - "+gpu_spair[1]+" need to implement/search reverse,  a spiral search or restart command");
@@ -874,8 +906,10 @@ public class ComboMatch {
        			int [] zooms = {initial_zoom, min_zoom_lev, 1000,1000}; // make automatic
        			int [] zooms = {initial_zoom, min_zoom_lev, 1000,1000}; // make automatic
        			double scale = 2.0; // scale vectors when warping;
        			double scale = 2.0; // scale vectors when warping;
        			//				int num_tries  = 5; // make configurable
        			//				int num_tries  = 5; // make configurable
        			if (!process_correlation) {
        			if (!process_correlation || !use_marked_image) { // skip low-res
        				zooms = new int[] {min_zoom_lev, 1000};
        				zooms = new int[] {min_zoom_lev, 1000};
        			}
        			if (!process_correlation) { // 0 LMA adjustments
        				num_tries_fit = 0;
        				num_tries_fit = 0;
        				update_match = false;
        				update_match = false;
        			}
        			}
@@ -884,24 +918,31 @@ public class ComboMatch {
        			boolean ignore_prev_rms = true;
        			boolean ignore_prev_rms = true;
        			Rectangle woi = new Rectangle(); // used to return actual woi from correlateOrthoPair()
        			Rectangle woi = new Rectangle(); // used to return actual woi from correlateOrthoPair()
        			double [][] ground_planes = null;
        			double [][] ground_planes = null;
					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)

        			for (int zi = 0; zi < zooms.length; zi++) {
        			for (int zi = 0; zi < zooms.length; zi++) {
        				zoom_lev = zooms[zi];
        				zoom_lev = zooms[zi];
        				if (zoom_lev >=1000) {
        				if (zoom_lev >=1000) {
        					break;
        					break;
        				}
        				}
        				boolean show_vf = render_match || pattern_match;
        				boolean show_vf = false; // render_match || pattern_match;
        				if (render_match || pattern_match) {
        				if (render_match || pattern_match) {
        					ground_planes = new double [gpu_pair.length][];
        					ground_planes = new double [gpu_pair.length][];
        				}
        				}
        				// will modify affines[1], later add jtj, weight, smth. else?
        				// will modify affines[1], later add jtj, weight, smth. else?
        				PairwiseOrthoMatch pmatch = process_correlation? pairwiseOrthoMatch: null;
        				FineXYCorr warp = maps_collection.correlateOrthoPair(
        				FineXYCorr warp = maps_collection.correlateOrthoPair(
        						clt_parameters,  // CLTParameters    clt_parameters,
        						clt_parameters,  // CLTParameters    clt_parameters,
        						(process_correlation? pairwiseOrthoMatch: null), //PairwiseOrthoMatch pairwiseOrthoMatch, // will return statistics
        						(process_correlation? pairwiseOrthoMatch: null), //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
        						frac_remove,     // double           frac_remove, //  =        0.25
        						metric_error,    // 			double           metric_error,
        						metric_error_adj,// 			double           metric_error,
        						ignore_prev_rms, // boolean ignore_prev_rms,
        						ignore_prev_rms, // boolean ignore_prev_rms,
        						num_tries_fit,   //  = 5int              num_tries, //  = 5
        						num_tries_fit,   //  = 5int              num_tries, //  = 5
        						true,            // boolean          calc_warp,
        						true,            // boolean          calc_warp, (will return null if false)
        						batch_mode,      // boolean          batch_mode,
        						batch_mode,      // boolean          batch_mode,
        						gpu_pair,        // String []        gpu_spair,
        						gpu_pair,        // String []        gpu_spair,
        						affines,         // double [][][]    affines, // on top of GPS offsets
        						affines,         // double [][][]    affines, // on top of GPS offsets
@@ -910,7 +951,7 @@ public class ComboMatch {
        						show_vf,         // boolean show_vf,
        						show_vf,         // boolean show_vf,
        						ground_planes,   // double [][]      ground_planes, // null or double[2] - will return ground planes
        						ground_planes,   // double [][]      ground_planes, // null or double[2] - will return ground planes
        						debugLevel);     // final int        debugLevel)
        						debugLevel);     // final int        debugLevel)
        				if (warp == null) {
        				if ((warp == null) || ((pmatch != null) &&  Double.isNaN(pmatch.rms))) {
        					System.out.println("Failed correlateOrthoPair()");
        					System.out.println("Failed correlateOrthoPair()");
        					return false;
        					return false;
        				}
        				}
@@ -948,10 +989,10 @@ public class ComboMatch {
        					//						imp_pat_match.show();
        					//						imp_pat_match.show();
        				}
        				}
        				if (render_match) {
        				if (render_match) {
        					String title=String.format("multi_%03d-%03d_%s-%s_zoom%d_%d",gpu_pair[0],gpu_pair[1],gpu_spair[0],gpu_spair[1],min_zoom_lev,zoom_lev);
        					ImagePlus imp_img_pair = 	maps_collection.renderMulti (
        					ImagePlus imp_img_pair = 	maps_collection.renderMulti (
        							//_zoom<integer> is needed for opening with "Extract Objects" command
        							//_zoom<integer> is needed for opening with "Extract Objects" command
        							"multi_"+gpu_spair[0]+"-"+gpu_spair[1]+"_zoom"+min_zoom_lev+"_"+zoom_lev, // String      title,
        							title, // String      title,
        							//								false,             // boolean     use_alt,
        							OrthoMapsCollection.MODE_IMAGE,  // int           mode,    // 0 - regular image, 1 - altitudes, 2 - black/white mask       // boolean     use_alt,
        							OrthoMapsCollection.MODE_IMAGE,  // int           mode,    // 0 - regular image, 1 - altitudes, 2 - black/white mask       // boolean     use_alt,
        							gpu_pair,          // int []        indices, // null or which indices to use (normally just 2 for pairwise comparison)
        							gpu_pair,          // int []        indices, // null or which indices to use (normally just 2 for pairwise comparison)
        							bounds_to_indices, // boolean       bounds_to_indices,
        							bounds_to_indices, // boolean       bounds_to_indices,
@@ -978,6 +1019,98 @@ public class ComboMatch {
        }
        }
        return true;
        return true;
	}
	}
	public static PairwiseOrthoMatch initialPairAdjust(
			CLTParameters       clt_parameters,
			OrthoMapsCollection maps_collection,
			double              frac_remove, //  =        0.25
			double              metric_error,
			String[]            gpu_spair,
			int                 debugLevel) {
    	int [] gpu_pair = new int[gpu_spair.length];
    	gpu_pair[0] = maps_collection.getIndex(gpu_spair[0]);
    	int min_zoom_lev = maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel();
    	int max_zoom_lev = maps_collection.ortho_maps[gpu_pair[0]].getOriginalZoomLevel();

    	for (int i = 0; i < gpu_pair.length; i++) {
    		gpu_pair[i] = maps_collection.getIndex(gpu_spair[i]);
    		min_zoom_lev = Math.min(min_zoom_lev, maps_collection.ortho_maps[gpu_pair[i]].getOriginalZoomLevel());
    		max_zoom_lev = Math.max(max_zoom_lev, maps_collection.ortho_maps[gpu_pair[i]].getOriginalZoomLevel());
    	}
    	int initial_zoom = max_zoom_lev - 4;  // another algorithm?

		PairwiseOrthoMatch pairwiseOrthoMatch = maps_collection.ortho_maps[gpu_pair[0]].getMatch(
				maps_collection.ortho_maps[gpu_pair[1]].getName());
//		boolean has_match = pairwiseOrthoMatch != null;
		PairwiseOrthoMatch inv_match =  maps_collection.ortho_maps[gpu_pair[1]].getMatch(
				maps_collection.ortho_maps[gpu_pair[0]].getName());
		
		// dialog - ask parameters and if has_match -ask if to use it (then just return true)
		// if has inv - ask and, if yes, = create inverted as initial
		boolean use_exixting_pair =    false;
		boolean invert_exixting_pair = false;
		double search_step =           8.0; // pix
		double search_range =         50.0; // pix
		double maximal_rms =           0.25; //
		int    min_overlap =          3000; // do not try to match if there is too small overlap (scaled pixels)
		int    num_iter_lma =          5;
		GenericJTabbedDialog gd = new GenericJTabbedDialog("Setup SpiralMatch",1200,900);
		if (pairwiseOrthoMatch != null) {
			gd.addCheckbox    ("Use existing image pair",  use_exixting_pair, "Use existing affine settings for this pair, do not use spiral search.");
		}
		if (inv_match != null) {
			gd.addCheckbox    ("Invert existing image pair", invert_exixting_pair, "Invert existing image pair affine transform, do not use spiral search.");
		}
		gd.addNumericField("Spiral search step",     search_step,  3,7,"scaled pix",	"Distance between spiral search probes, in scaled pixels.");
		gd.addNumericField("Spiral search radius",   search_range, 3,7,"scaled pix",	"Maximal radius of the spiral search, in scaled pixels.");
		gd.addNumericField("Maximal RMSE",           maximal_rms,  3,7,"scaled pix",	"Maximal RMSE to consider match, in scaled pixels.");
		gd.addNumericField("Minimal overlap",        min_overlap,  0,4,"scaled pix ^ 2","Minimal overlap area in square scaled pixels.");
		gd.addNumericField("LMA iterations",         num_iter_lma, 0,2,"",              "Number of LMA iterations.");
		gd.showDialog();
		if (gd.wasCanceled()) return null;
		if (pairwiseOrthoMatch != null) {
			use_exixting_pair =    gd.getNextBoolean();
		}
		if (inv_match != null) {
			invert_exixting_pair = gd.getNextBoolean();
		}
		search_step=               gd.getNextNumber();
		search_range=              gd.getNextNumber();
		maximal_rms =              gd.getNextNumber();
		min_overlap =        (int) gd.getNextNumber();
		num_iter_lma =       (int) gd.getNextNumber();
		if (use_exixting_pair) {
			if (invert_exixting_pair) {
				System.out.println("Both direct and inverted matches are selected, using direct match");
			}
			return pairwiseOrthoMatch;
		} else if (invert_exixting_pair) {
			double [] enuOffset = maps_collection.ortho_maps[gpu_pair[0]].enuOffsetTo(maps_collection.ortho_maps[gpu_pair[1]]);
			double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image 
			// create inverted pairwiseOrthoMatch - move to PairwiseOrthoMatch
			return inv_match.getInverse(rd);
		}
		double [][] affine0 = {{1,0,0},{0,1,0}}; // will always stay the same
		double [][] affine1 = {{1,0,0},{0,1,0}}; // here (manual mode) start from the center, may use prediction in auto
		double [][][] affines = new double[][][] {affine0,affine1};

		pairwiseOrthoMatch = maps_collection.SpiralMatch (
				clt_parameters,  // CLTParameters    clt_parameters,
//				PairwiseOrthoMatch pairwiseOrthoMatch, // will return statistics, may be null if not needed
				frac_remove,     // double           frac_remove, //  =        0.25
				metric_error,    // double           metric_error,
				gpu_pair,        // int []           gpu_pair,
				affines,         // double [][][]    affines_init,  // here in meters, relative to vertical points
				initial_zoom,    // int              zoom_lev,
				search_step,     // double           pix_step,
				search_range,    // double           pix_range,
				maximal_rms,     // double           need_rms,
				num_iter_lma,    // int              num_tries, //  = 5
				min_overlap,     // int              min_overlap, // 3000
				debugLevel);    // int              debugLevel){
		return pairwiseOrthoMatch;
	}
	
	
	
	
	public static boolean updateBlBcFileNames(
	public static boolean updateBlBcFileNames(
			String suffix,
			String suffix,
@@ -1375,7 +1508,9 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341
		// get TD interscene correlation of 2 scenes, use only combo (all channels) data
		// get TD interscene correlation of 2 scenes, use only combo (all channels) data
		TDCorrTile [] corr_tiles = TDCorrTile.getFromGpu(
		TDCorrTile [] corr_tiles = TDCorrTile.getFromGpu(
				GPU_QUAD_AFFINE);
				GPU_QUAD_AFFINE);
		double  neib_radius =      clt_parameters.imp.rln_neib_radius;;
		
// depends on zoom level		
		double  neib_radius =      clt_parameters.imp.rln_neib_radius;
		boolean rln_neibs_fill =   clt_parameters.imp.rln_neibs_fill;		
		boolean rln_neibs_fill =   clt_parameters.imp.rln_neibs_fill;		
		double  rln_fat_zero =     clt_parameters.imp.rln_fat_zero;
		double  rln_fat_zero =     clt_parameters.imp.rln_fat_zero;
		boolean rln_use_neibs =    clt_parameters.imp.rln_use_neibs;
		boolean rln_use_neibs =    clt_parameters.imp.rln_use_neibs;
@@ -1384,6 +1519,14 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341
		double  rln_sngl_rstr =    clt_parameters.imp.rln_sngl_rstr;
		double  rln_sngl_rstr =    clt_parameters.imp.rln_sngl_rstr;
		double  rln_neib_rstr =    clt_parameters.imp.rln_neib_rstr;
		double  rln_neib_rstr =    clt_parameters.imp.rln_neib_rstr;
		
		
		double max_neib_radius = Math.min(woi.width, woi.height)/GPUTileProcessor.DTT_SIZE * clt_parameters.imp.rln_radius_frac;
		if (neib_radius > max_neib_radius) {
			neib_radius = max_neib_radius;
		}

		
		
		
		double [][][] corr_tiles_pd = new double [(neib_radius>0)? 2: 1][][];
		double [][][] corr_tiles_pd = new double [(neib_radius>0)? 2: 1][][];
		// use TDCorrTile.calcNeibs() here to get 8-neighbors
		// use TDCorrTile.calcNeibs() here to get 8-neighbors
		corr_tiles_pd[0] = TDCorrTile.convertTDtoPD(
		corr_tiles_pd[0] = TDCorrTile.convertTDtoPD(
+2 −0
Original line number Original line Diff line number Diff line
@@ -3005,6 +3005,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
		}
		}
		return true;
		return true;
	}
	}
	
	public static double [][] combineAffine(
	public static double [][] combineAffine(
			double [][] ref_affine,
			double [][] ref_affine,
			double [][] other_affine){
			double [][] other_affine){
@@ -3023,6 +3024,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
	}
	}


	
	
	
	/**
	/**
	 * Get planar approximation of the ground
	 * Get planar approximation of the ground
	 * 
	 * 
+163 −14

File changed.

Preview size limit exceeded, changes collapsed.

+11 −2
Original line number Original line Diff line number Diff line
@@ -54,21 +54,26 @@ public class OrthoPairLMA {
	private double [][]       last_jt =         null;
	private double [][]       last_jt =         null;
	private boolean           origin_center =   false; // true - origin in overlap center, false - top left corner (as it was)
	private boolean           origin_center =   false; // true - origin in overlap center, false - top left corner (as it was)
	private double []         origin =          null; // either {0,0} for top-left or center of the woi
	private double []         origin =          null; // either {0,0} for top-left or center of the woi
	public  int               num_good_tiles = 0;
	public OrthoPairLMA (boolean origin_center) {
	public OrthoPairLMA (boolean origin_center) {
		this.origin_center = origin_center;
		this.origin_center = origin_center;
	}
	}
	public void prepareLMA(
	public int prepareLMA(
			// will always calculate relative affine, starting with unity
			// will always calculate relative affine, starting with unity
			int           width, // tilesX
			int           width, // tilesX
			double [][]   vector_XYS,    // optical flow X,Y, confidence obtained from the correlate2DIterate()
			double [][]   vector_XYS,    // optical flow X,Y, confidence obtained from the correlate2DIterate()
			double [][]   centers,       // tile centers (in pixels)
			double [][]   centers,       // tile centers (in pixels)
			double []     weights_extra, // optional, may be null 
			double []     weights_extra, // optional, may be null 
			boolean       first_run,
			boolean       first_run,
			int           min_good_tiles,
			double        max_std,      // maximal standard deviation to limit center area  
			double        min_std_rad,  // minimal radius of the central area (if less - fail)
			final int     debug_level) {
			final int     debug_level) {
		tile_centers = centers;
		tile_centers = centers;
		this.width = width;
		this.width = width;
		int height = vector_XYS.length / width;
		int height = vector_XYS.length / width;
		int min_x = width, min_y=height, max_x = -1, max_y=-1;
		int min_x = width, min_y=height, max_x = -1, max_y=-1;
		num_good_tiles = 0;
		for (int tile = 0; tile < vector_XYS.length; tile++) if ((vector_XYS[tile] !=null)) {
		for (int tile = 0; tile < vector_XYS.length; tile++) if ((vector_XYS[tile] !=null)) {
			int tileX = tile % width;
			int tileX = tile % width;
			int tileY = tile / width;
			int tileY = tile / width;
@@ -76,8 +81,12 @@ public class OrthoPairLMA {
			if (tileX > max_x) max_x = tileX;
			if (tileX > max_x) max_x = tileX;
			if (tileY < min_y) min_y = tileY;
			if (tileY < min_y) min_y = tileY;
			if (tileY > max_y) max_y = tileY;
			if (tileY > max_y) max_y = tileY;
			num_good_tiles++;
		}
		}
		woi = new Rectangle (min_x, min_y, max_x - min_x + 1, max_y - min_y + 1);
		woi = new Rectangle (min_x, min_y, max_x - min_x + 1, max_y - min_y + 1);
		if (num_good_tiles < min_good_tiles) {
			return num_good_tiles;
		}
		origin = new double[2];
		origin = new double[2];
		if (origin_center) {
		if (origin_center) {
			origin = new double [] {
			origin = new double [] {
@@ -98,7 +107,7 @@ public class OrthoPairLMA {
		last_rms = new double [2];
		last_rms = new double [2];
		initial_rms = last_rms.clone();
		initial_rms = last_rms.clone();
		good_or_bad_rms = this.last_rms.clone();
		good_or_bad_rms = this.last_rms.clone();
		
		return num_good_tiles;
	}
	}
	
	
	public double [][] getAffine(){
	public double [][] getAffine(){
+31 −1
Original line number Original line Diff line number Diff line
@@ -14,10 +14,40 @@ public class PairwiseOrthoMatch implements Serializable {
	public PairwiseOrthoMatch() {
	public PairwiseOrthoMatch() {
		
		
	}
	}
	public PairwiseOrthoMatch(double [][] affine, double [][] jtj, double rms, int zoom_lev) {
	public PairwiseOrthoMatch(
			double [][] affine,
			double [][] jtj,
			double rms,
			int zoom_lev) {
		this.affine = affine;
		this.affine = affine;
		this.jtj = jtj;
		this.jtj = jtj;
		this.zoom_lev=zoom_lev;
	}
	}
	
	public PairwiseOrthoMatch getInverse(double [] rd) {
		double [][] affine = OrthoMap.invertAffine(getAffine());
		PairwiseOrthoMatch inverted_match = new PairwiseOrthoMatch(
				affine, // double [][] affine,
				null, // double [][] jtj,
				rms, // double rms,
				zoom_lev); // int zoom_lev)
		double [] corr = {
				rd[0] * (affine[0][0]-1.0)+ rd[1]*affine[0][1],
				rd[0] * affine[1][0]+       rd[1]*(affine[1][1]-1.0)};
		affine[0][2] += corr[0];
		affine[1][2] += corr[1];
		return inverted_match;	
	}

	public PairwiseOrthoMatch getInverse() {
		PairwiseOrthoMatch inverted_match = new PairwiseOrthoMatch(
				OrthoMap.invertAffine(getAffine()), // double [][] affine,
				null, // double [][] jtj,
				rms, // double rms,
				zoom_lev); // int zoom_lev)
		return inverted_match;
	}
	
	public double [][] getAffine(){
	public double [][] getAffine(){
		return affine;
		return affine;
	}
	}
Loading