Commit ab8d3318 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Bug fixing to make run for many scenes. Started LPF for the ground w/o

SfM
parent 3f84a242
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5090,7 +5090,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
			System.out.println("=== IMS ===");
			QUAD_CLT_AUX.showQuatCorr();
			System.out.println("=== IMU ===");
			QUAD_CLT_AUX.showPimuOffsets();
			QUAD_CLT_AUX.showPimuOffsets(CLT_PARAMETERS); //
			@SuppressWarnings("unused")
			QuadCLT dbg_QUAD_CLT = QUAD_CLT;
			@SuppressWarnings("unused")
+1 −1
Original line number Diff line number Diff line
@@ -295,7 +295,7 @@ public class ElphelTiffWriter {
	private static IIOMetadataNode createTimeStamp(LocalDateTime dt, int digits_after) { // 3
		int denom = 1;
		for (int i = 0; i < digits_after; i++) denom *= 10;
		int fsec = dt.getSecond()*denom+((int) Math.round(denom * dt.getNano()*1E-9));
		int fsec = dt.getSecond()*denom+((int) Math.round(denom * (dt.getNano()*1E-9)));
		
	    IIOMetadataNode node_rationals = new IIOMetadataNode(TIFF_RATIONALS_TAG);
	    IIOMetadataNode node_hrs =       new IIOMetadataNode(TIFF_RATIONAL_TAG);
+180 −9
Original line number Diff line number Diff line
@@ -23,8 +23,10 @@
 */
package com.elphel.imagej.tileprocessor;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
@@ -508,6 +510,11 @@ public class Interscene {
			double  sfm_fracall =        clt_parameters.imp.sfm_fracall; // 0.3;   // minimal relative area of the SfM-e		
	     	boolean fmg_initial_en =     clt_parameters.imp.fmg_initial_en; // enable IMS-based FPN mitigation for initial orientation
	    	double  fmg_distance =       clt_parameters.imp.fmg_distance; // try to find other reference scene not closer than this pixels
	    	// todo: improve to use "preferred" distance
	    	if (fmg_distance < (min_offset + 2)) {
	    		fmg_distance = min_offset + 2;
	    	}
	    	
	    	double  fmg_max_quad =       clt_parameters.imp.fmg_max_quad; // estimate offset by 4 points (rooll-aware, 25% from center) if center
	    	                                           // offset is too small
	    	boolean fmg_rectilinear =    clt_parameters.imp.fmg_rectilinear;// use rectilinear model for scene offset estimation 
@@ -680,6 +687,10 @@ public class Interscene {
			if (fmg_initial_en && !fpn_list.isEmpty()) {
				// here max_offset is not critical, min_offset can be 0 too
				//double [] min_max = {min_offset, max_offset, 0.0} ; // {min, max, actual rms)
				if (fmg_distance < (min_max[0] + 2)) {
					fmg_distance = min_max[0] + 2;
				}
				
				int [][] fpn_pairs = getFPNPairs(
						fpn_list,          // ArrayList<Integer> fpn_list,
						fmg_distance, // double             fpn_mitigate_dist,
@@ -689,6 +700,15 @@ public class Interscene {
						avg_z,             // double             avg_z,
						last_index, // ref_index,         // int                ref_index, // >= earliest_scene 
						earliest_index);   // int                earliest_scene)
				// mitigating problem, that in the process of adjusting offset can fall below
				// the minimum and coordinates will be NaN:
				/*
					Mitigating FPN for scene 361 being too close to reference 344, using scene 367 as a reference
					interCorrPair(): avg_offs = 10.755562139763402 <= 256.0, sw = 4217.0 iter=3, RMS=0.5364197453455559 (Pure RMS=0.5364197453455559)
					interCorrPair(): avg_offs = 7.795390182218127 < 8.0, sw = 4219.0
					adjustPairsLMAInterscene() returned null
				 */
				double [] min_max_fpn = {0,min_max[1]}; 
				for (int ipair = 0; ipair < fpn_pairs.length; ipair++) if (fpn_pairs[ipair][1] >= 0) {
					if (debugLevel > -4) {
						System.out.println("Mitigating FPN for scene "+fpn_pairs[ipair][0]+
@@ -701,7 +721,7 @@ public class Interscene {
	    					use_lma_dsi,         // clt_parameters.imp.use_lma_dsi,
	    					false,               //	boolean        fpn_disable,   // disable fpn filter if images are known to be too close
	    					true,                // boolean        disable_ers,
	    					min_max,             // double []      min_max,       // null or pair of minimal and maximal offsets
	    					min_max_fpn,// min_max,// double []    min_max,       // null or pair of minimal and maximal offsets
	    					fail_reason,         // int []         fail_reason,   // null or int[1]: 0 - OK, 1 - LMA, 2 - min, 3 - max
	    					quadCLTs,            // QuadCLT []     quadCLTs,
	    					ref_index,           // int            ref_index,
@@ -755,6 +775,23 @@ public class Interscene {
					}
				}
			}
			// Add to log
	    	StringBuffer sb = new StringBuffer();
	    	sb.append(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+"\n");
			sb.append("Finished invertInitialOrientation():\n");
	    	sb.append("getNumOrient()= "+quadCLTs[ref_index].getNumOrient()+" of "+clt_parameters.imp.min_num_orient+"\n");
	    	sb.append("getNumAccum()=  "+quadCLTs[ref_index].getNumAccum()+ " of "+clt_parameters.imp.min_num_interscene+"\n");
	    	sb.append("earliest_scene= "+earliest_index+"\n");
	    	sb.append("ref_index=      "+ref_index+"\n");
	    	sb.append("last_index=     "+last_index+"\n");
	    	sb.append("old_ref_index=  "+ref_old+"\n");
	    	sb.append("Maximal RMSE=   "+maximal_series_rms+"\n");
	    	sb.append("------------------------\n\n");
			quadCLTs[ref_index].saveStringInModelDirectory(sb.toString(), QuadCLT.ORIENTATION_LOGS_SUFFIX); // String  suffix)

			
			
			
		}
		return 0;
	}
@@ -1161,6 +1198,9 @@ public class Interscene {
		if (fmg_initial_en && !fpn_list.isEmpty()) {
			// here max_offset is not critical, min_offset can be 0 too
			double [] min_max = {min_offset, max_offset, 0.0} ; // {min, max, actual rms)
			if (fmg_distance < (min_max[0] + 2)) {
				fmg_distance = min_max[0] + 2;
			}
			int [][] fpn_pairs = getFPNPairs(
					fpn_list,          // ArrayList<Integer> fpn_list,
					fmg_distance, // double             fpn_mitigate_dist,
@@ -1170,6 +1210,15 @@ public class Interscene {
					avg_z,             // double             avg_z,
					ref_index,         // int                ref_index, // >= earliest_scene 
					earliest_scene);   // int                earliest_scene)
			// mitigating problem, that in the process of adjusting offset can fall below
			// the minimum and coordinates will be NaN:
			/*
				Mitigating FPN for scene 361 being too close to reference 344, using scene 367 as a reference
				interCorrPair(): avg_offs = 10.755562139763402 <= 256.0, sw = 4217.0 iter=3, RMS=0.5364197453455559 (Pure RMS=0.5364197453455559)
				interCorrPair(): avg_offs = 7.795390182218127 < 8.0, sw = 4219.0
				adjustPairsLMAInterscene() returned null
			 */
			double [] min_max_fpn = {0,min_max[1]}; 
			for (int ipair = 0; ipair < fpn_pairs.length; ipair++) if (fpn_pairs[ipair][1] >= 0) {
				if (debugLevel > -4) {
					System.out.println("Mitigating FPN for scene "+fpn_pairs[ipair][0]+
@@ -1182,7 +1231,7 @@ public class Interscene {
    					use_lma_dsi,         // clt_parameters.imp.use_lma_dsi,
    					false,               //	boolean        fpn_disable,   // disable fpn filter if images are known to be too close
    					true,                // boolean        disable_ers,
    					min_max,             // double []      min_max,       // null or pair of minimal and maximal offsets
    					min_max_fpn, // min_max,// double []   min_max,       // null or pair of minimal and maximal offsets
    					fail_reason,         // int []         fail_reason,   // null or int[1]: 0 - OK, 1 - LMA, 2 - min, 3 - max
    					quadCLTs,            // QuadCLT []     quadCLTs,
    					ref_index,           // int            ref_index,
@@ -1249,6 +1298,17 @@ public class Interscene {
		quadCLTs[ref_index].saveInterProperties( // save properties for interscene processing (extrinsics, ers, ...)  // null pointer
				null, // String path,             // full name with extension or w/o path to use x3d directory
				debugLevel+1);
		// Add to log
    	StringBuffer sb = new StringBuffer();
    	sb.append(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+"\n");
		sb.append("Finished setInitialOrientationsIms():\n");
    	sb.append("getNumOrient()= "+quadCLTs[ref_index].getNumOrient()+" of "+clt_parameters.imp.min_num_orient+"\n");
    	sb.append("getNumAccum()=  "+quadCLTs[ref_index].getNumAccum()+ " of "+clt_parameters.imp.min_num_interscene+"\n");
    	sb.append("earliest_scene= "+earliest_scene+"\n");
    	sb.append("ref_index=      "+ref_index+"\n");
    	sb.append("Maximal RMSE=   "+maximal_series_rms+"\n");
    	sb.append("------------------------\n\n");
		quadCLTs[ref_index].saveStringInModelDirectory(sb.toString(), QuadCLT.ORIENTATION_LOGS_SUFFIX); // String  suffix)
		return earliest_scene;
	}

@@ -1919,6 +1979,7 @@ public class Interscene {
    	double  fmg_distance =       clt_parameters.imp.fmg_distance; // try to find other reference scene not closer than this pixels
    	double  fmg_max_quad =       clt_parameters.imp.fmg_max_quad; // estimate offset by 4 points (rooll-aware, 25% from center) if center
    	boolean fmg_rectilinear =    clt_parameters.imp.fmg_rectilinear;// use rectilinear model for scene offset estimation 
		boolean use_precomp =        clt_parameters.imp.use_precomp;// try to predict initial error from previous scenes
		
//		int     avg_len	=                clt_parameters.imp.avg_len;
        // Set up velocities from known coordinates, use averaging
@@ -2091,6 +2152,28 @@ public class Interscene {
            		last_scene);    // int           last_index)
//        } else if (readjust_xy_ims && (reg_weight_xy > 0.0)) {
        } else if (readjust_xy_ims) {
        	// optionally run adjustment here (QuadCLT.rotateImsToCameraXYZ()? Or only 
        	scenes_xyzatr_pull = QuadCLT.refineXYZFromIMU(
        			clt_parameters, // CLTParameters clt_parameters,
        			false, // true, // false,          // boolean       common_scale_only // false - individual by direction
        			use_Z,          // boolean       keepZ, // if adjusting Z, qill use its old value
        			quadCLTs,       // QuadCLT[]     quadCLTs,
        			scenes_xyzatr,  // double [][][] xyzatr,
            		null,           // double [][][] pimu_xyzatr, // if null - will be recalculated
            		ref_index,      // int           ref_index,
            		earliest_scene, // int           early_index,
            		last_scene,     // int           last_index,
            		debugLevel);    //int           debugLevel)
    		for (int nscene = earliest_scene; nscene <= last_scene; nscene++) if (scenes_xyzatr[nscene] != null) {
    			scenes_xyzatr_pull[nscene] =  modifyATRtoXYZ(
    					scenes_xyzatr[nscene],         // double [][] cur_xyzatr, // careful with Z - using the new one
    					scenes_xyzatr_pull[nscene][0], // double []   new_xyz,
    					avg_z);                        // double      avg_z
    		}
        	
        	
        	/*
        	
			double [][][] pimu_xyzatr = QuadCLT.integratePIMU(
					clt_parameters, // final CLTParameters clt_parameters,
					quadCLTs,       // final QuadCLT[]     quadCLTs,
@@ -2146,6 +2229,7 @@ public class Interscene {
	    					avg_z);                    // double      avg_z
	    		}
	    	}
	    	*/
	    	// old version
        	/*
        	scenes_xyzatr_pull = QuadCLT.refineFromImsVelocities(
@@ -2287,6 +2371,18 @@ public class Interscene {
			System.out.println("test_adjust = "+test_adjust);			
		}		
		
		// Main cycle - first goes down from the center, then up, and finally processes "fpn" scenes (close to reference)
		double [][] precomp_xyzatr = new double [2][3];
		int last_processed_scene = -2; // none
		/*
		 * There is still a problem with a large mismatch at start position for far off-reference scenes,
		 * especiall those that were not refined after inversion - reversing order of earlier processed "later"
		 * half (after the reference in the center) earlier processed as the bottom half of the other sub-sequence.
		 * 
		 * For mitigation we'll use that both half-sequences start from the center with small mismatches. The
		 * precomp_xyzatr will be used to store how much LMA corrected from the original estimation and add it
		 * to the next scene (only when it is the next), similar to the initial orientation.   
		 */
		
    	for (int nscene:scene_seq) {
			if (nscene == debug_scene) {
@@ -2351,6 +2447,26 @@ public class Interscene {
	    		if (est_shift < min_max[0]) {
	    			fail_reason[0]=FAIL_REASON_MIN;
	    		} else {
	    			double [][] corr_xyzatr_pull = new double [][] {scenes_xyzatr_pull[nscene][0].clone(), scenes_xyzatr_pull[nscene][1].clone()};
	    			/*
	    			 * scenes_xyzatr[ref_index],// double [][]    scene0_xyzatr, - scene to compare to
	    			 * scenes_xyzatr[nscene],   // double [][]    scene1_xyzatr - previous known pose?
	    			 * scenes_xyzatr_pull[nscene], // double [][]    scene1_xyzatr_pull, - now not a pull,
	    			 *  but a rigid target set as initial approximation 
	    			 */
	    			boolean applied_precomp = false;
	    			if (use_precomp && (last_processed_scene >= nscene-1) && (last_processed_scene <= nscene+1)) {
	    				corr_xyzatr_pull=ErsCorrection.combineXYZATR(
	    						scenes_xyzatr_pull[nscene],
	    						precomp_xyzatr);
	    				applied_precomp = true;
	    				if (debugLevel > -2) {
	    					System.out.println(String.format(
	    							"Applied precompensation: [%9.6f, %9.6f, %9.6f] [%9.6f, %9.6f, %9.6f]",
	    							precomp_xyzatr[0][0], precomp_xyzatr[0][1], precomp_xyzatr[0][2], 
	    							precomp_xyzatr[1][0], precomp_xyzatr[1][1], precomp_xyzatr[1][2]));
	    				}
	    			}
	    			scenes_xyzatr[nscene] = adjustDiffPairsLMAInterscene( // compare two scenes, first may be reference, use motion blur
	    					clt_parameters,          //CLTParameters  clt_parameters,
	    					use_lma_dsi,             //,boolean        use_lma_dsi,
@@ -2371,7 +2487,7 @@ public class Interscene {
	    					scenes_xyzatr[ref_index],// double [][]    scene0_xyzatr,
	    					scenes_xyzatr[nscene],   // double [][]    scene1_xyzatr,
	    					avg_z,                   // double         average_z,     
	    					scenes_xyzatr_pull[nscene], // double [][]    scene1_xyzatr_pull,
	    					corr_xyzatr_pull, // scenes_xyzatr_pull[nscene], // double [][]    scene1_xyzatr_pull,
	    					param_select,            // boolean[]      param_select,
	    					param_regweights,        // double []      param_regweights,
	    					lma_rms,                 // double []      rms_out, // null or double [2]
@@ -2381,6 +2497,22 @@ public class Interscene {
	    					mb_max_gain,             // double         mb_max_gain, // 5.0;   // motion blur maximal gain (if more - move second point more than a pixel
	    					clt_parameters.imp.debug_level); // int            debugLevel)
	    			adjust_OK = scenes_xyzatr[nscene] != null;
	    			if (!adjust_OK) {
	    				last_processed_scene = -2;
	    			} else if (use_precomp) {
	    				double [][] last_corr_xyzatr = ErsCorrection.combineXYZATR(
	    						scenes_xyzatr[nscene],
	    						ErsCorrection.invertXYZATR(corr_xyzatr_pull));
	    				// add precomp_xyzatr if it was applied:
	    				if (applied_precomp) {
	    					precomp_xyzatr = ErsCorrection.combineXYZATR(
	    							precomp_xyzatr,
	    							last_corr_xyzatr);
	    				} else { // just use difference
	    					precomp_xyzatr = last_corr_xyzatr;
	    				}
	    				last_processed_scene = nscene;
	    			}
	    		}
				if (adjust_OK && fail_on_zoom_roll) { // check only for initial orientation, do not check on readjustments
					if (Math.abs(scenes_xyzatr[nscene][1][2]) > max_roll) {
@@ -2460,6 +2592,9 @@ public class Interscene {
			System.out.println("num_fpn_mitigate= "+fpn_list.size());
		}
		if (fmg_reorient_en && !fpn_list.isEmpty()) {
			if (fmg_distance < (min_max[0] + 2)) {
				fmg_distance = min_max[0] + 2;
			}
			int [][] fpn_pairs = getFPNPairs(
					fpn_list,          // ArrayList<Integer> fpn_list,
					fmg_distance,      // double             fpn_mitigate_dist,
@@ -2469,6 +2604,15 @@ public class Interscene {
					avg_z,             // double             avg_z,
					last_scene,        // latest_scene,         // int                ref_index, // >= earliest_scene 
					earliest_scene);   // int                earliest_scene)
			// mitigating problem, that in the process of adjusting offset can fall below
			// the minimum and coordinates will be NaN:
			/*
				Mitigating FPN for scene 361 being too close to reference 344, using scene 367 as a reference
				interCorrPair(): avg_offs = 10.755562139763402 <= 256.0, sw = 4217.0 iter=3, RMS=0.5364197453455559 (Pure RMS=0.5364197453455559)
				interCorrPair(): avg_offs = 7.795390182218127 < 8.0, sw = 4219.0
				adjustPairsLMAInterscene() returned null
			 */
			double [] min_max_fpn = {0,min_max[1]}; 
			boolean test_adjust1 = debugLevel > 1000;
			if (test_adjust1) {
				int [][] fpn_pairs_dbg = new int [fpn_pairs.length+3][2];
@@ -2503,7 +2647,7 @@ public class Interscene {
						use_lma_dsi,             //,boolean        use_lma_dsi,
						fpn_disable,             // boolean        fpn_disable,   // disable fpn filter if images are known to be too close
						disable_ers,             // boolean        disable_ers,
						min_max,                 // double []      min_max,       // null or pair of minimal and maximal offsets
						min_max_fpn, // min_max, // double []      min_max,       // null or pair of minimal and maximal offsets
						fail_reason,             // int []         fail_reason,   // null or int[1]: 0 - OK, 1 - LMA, 2 - min, 3 - max
						quadCLTs,                // QuadCLT []     quadCLTs,
						ref_index,               // int            ref_index,
@@ -2624,6 +2768,31 @@ public class Interscene {
		quadCLTs[ref_index].saveInterProperties( // save properties for interscene processing (extrinsics, ers, ...)
				null, // String path,             // full name with extension or w/o path to use x3d directory
				debugLevel+1);
		
		// Add to log
    	StringBuffer sb = new StringBuffer();
    	sb.append(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())+"\n");
		sb.append("Finished reAdjustPairsLMAInterscene():\n");
    	sb.append("getNumOrient()= "+quadCLTs[ref_index].getNumOrient()+" of "+clt_parameters.imp.min_num_orient+"\n");
    	sb.append("getNumAccum()=  "+quadCLTs[ref_index].getNumAccum()+ " of "+clt_parameters.imp.min_num_interscene+"\n");
    	sb.append("earliest_scene= "+range[0]+"\n");
    	sb.append("ref_index=      "+ref_index+"\n");
    	sb.append("last_index=     "+range[1]+"\n");
    	sb.append("Maximal RMSE=   "+maximal_series_rms+"\n");
    	sb.append("lpf_xy=         "+lpf_xy+"\n");
    	sb.append("readjust_xy_ims="+readjust_xy_ims+"\n");
    	sb.append("lma_xyzatr=     "+lma_xyzatr+"\n");
    	sb.append("use_R=          "+use_R+"\n");
    	sb.append("use_R=          "+use_R+"\n");
    	sb.append("mb_max_gain=    "+mb_max_gain+"\n");
    	sb.append("avg_z=          "+avg_z+"m\n");
    	sb.append("reg_weight_xy=  "+reg_weight_xy+"\n");
    	sb.append("disable_ers=    "+disable_ers+"\n");
    	sb.append("disable_ers_y=  "+disable_ers_y+"\n");
    	sb.append("disable_ers_r=  "+disable_ers_r+"\n");
    	sb.append("use_precomp=    "+use_precomp+"\n");
    	sb.append("------------------------\n\n");
		quadCLTs[ref_index].saveStringInModelDirectory(sb.toString(), QuadCLT.ORIENTATION_LOGS_SUFFIX); // String  suffix)
		return earliest_scene;
	}
	
@@ -2644,13 +2813,15 @@ public class Interscene {
			){
		double dx = new_xyz[0] - cur_xyzatr[0][0];
		double dy = new_xyz[1] - cur_xyzatr[0][1];
//		System.out.println(String.format("modifyATRtoXYZ(): dx=%7.3f, dy=%7.3f", dx, dy));
		double [][] diff_xyzatr = new double[][] {{dx, dy, 0},{dx/avg_z, -dy/avg_z,0}};
		double [][] new_xyzatr = ErsCorrection.combineXYZATR(cur_xyzatr,diff_xyzatr); 
		return new_xyzatr;
	}

	
	
	
	
	// Make it the only entry point
	// uses *_dt from
	// quadCLTs[nscene*].getErsCorrection().getErsXYZATR_dt()
@@ -5186,9 +5357,9 @@ public class Interscene {
			double []  corr_angles = rot.getAngles(RotationOrder.YXZ, ErsCorrection.ROT_CONV);
			double []  corr_degrees = new double[3];
			for (int i = 0; i < 3; i++) corr_degrees[i]=corr_angles[i]*180/Math.PI;
			System.out.println("quatCorr=["+quatCorr[0]+", "+quatCorr[1]+", "+quatCorr[2]+", "+quatCorr[3]+"]");
			System.out.println("ATR(rad)=["+corr_angles[0]+", "+corr_angles[1]+", "+corr_angles[2]+"]");
			System.out.println("ATR(deg)=["+corr_degrees[0]+", "+corr_degrees[1]+", "+corr_degrees[2]+"]");
			System.out.println("generateEgomotionTable(): quatCorr=["+quatCorr[0]+", "+quatCorr[1]+", "+quatCorr[2]+", "+quatCorr[3]+"]");
			System.out.println("generateEgomotionTable(): ATR(rad)=["+corr_angles[0]+", "+corr_angles[1]+", "+corr_angles[2]+"]");
			System.out.println("generateEgomotionTable(): ATR(deg)=["+corr_degrees[0]+", "+corr_degrees[1]+", "+corr_degrees[2]+"]");
		}
		
		for (int nscene = earliest_scene; nscene < quadCLTs.length; nscene++) {
@@ -5544,7 +5715,7 @@ public class Interscene {
		}
    }

    
    // relative to the GPS/compass
    public static double [] getQuaternionCorrection(
			CLTParameters  clt_parameters,
			QuadCLT []     quadCLTs,
Loading