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

Debugging LMA-based LY measurement, added initial LY estimation, more

model functions
parent 6293946d
Loading
Loading
Loading
Loading
+44 −5
Original line number Diff line number Diff line
@@ -301,6 +301,13 @@ public class CLTParameters {
	private double    lym_change_aux =  1e-4;    // same for aux camera (currntly)lwir
	public double     lym_poly_change = 0.002;   // Parameter vector difference to exit from polynomial correction
	
	public boolean    lym_mod_map =     true;    // Modify preliminary disparity map before running LY
	public boolean    lym_top_bg =      true;    // All above found BG is also BG (valid for most, but not all scenes)
	public int        lym_fill_gaps_bg = 0;      // fill small gaps in found background 
	public int        lym_fill_gaps_combo = 2;   // 1 - in 4 directions by 1, 2 - in 8 directions by 1,
	public boolean    lym_use_strength = true;   // Use strength when averaging disparity from neighbors
	public double     lym_scale_deriv_str=0.5;   // Scale strength of the interpolated tiles from average neighbors strength
	
	public boolean    lyf_filter =      false;   // Filter lazy eye pairs by their values
	public int        lyf_smpl_side =   3;       // 8 x8 masked, 16x16 sampled
	public double     lyf_rms_max =     0.1;     // Maximal RMS (all components to components average)
@@ -1190,15 +1197,20 @@ public class CLTParameters {
		properties.setProperty(prefix+"ly_disp_rvar_gt",            this.ly_disp_rvar_gt +"");
		properties.setProperty(prefix+"ly_norm_disp",               this.ly_norm_disp +"");
		properties.setProperty(prefix+"lym_overexp",                this.lym_overexp +"");

		properties.setProperty(prefix+"lym_dbg_path",                this.lym_dbg_path +"");
		
		properties.setProperty(prefix+"lym_update_disp",            this.lym_update_disp+"");
		properties.setProperty(prefix+"lym_iter",                   this.lym_iter+"");
		properties.setProperty(prefix+"lym_change",                 this.lym_change +"");
		properties.setProperty(prefix+"lym_change_aux",             this.lym_change_aux +"");
		properties.setProperty(prefix+"lym_poly_change",            this.lym_poly_change +"");

		properties.setProperty(prefix+"lym_mod_map",                this.lym_mod_map +"");
		properties.setProperty(prefix+"lym_top_bg",                 this.lym_top_bg +"");
		properties.setProperty(prefix+"lym_fill_gaps_bg",           this.lym_fill_gaps_bg +"");
		properties.setProperty(prefix+"lym_fill_gaps_combo",        this.lym_fill_gaps_combo +"");
		properties.setProperty(prefix+"lym_use_strength",           this.lym_use_strength +"");
		properties.setProperty(prefix+"lym_scale_deriv_str",        this.lym_scale_deriv_str +"");

		properties.setProperty(prefix+"lyf_filter",                 this.lyf_filter+"");
		properties.setProperty(prefix+"lyf_smpl_side",              this.lyf_smpl_side+"");
		properties.setProperty(prefix+"lyf_rms_max",                this.lyf_rms_max +"");
@@ -2007,9 +2019,15 @@ public class CLTParameters {
		if (properties.getProperty(prefix+"lym_iter")!=null)                      this.lym_iter=Integer.parseInt(properties.getProperty(prefix+"lym_iter"));
		if (properties.getProperty(prefix+"lym_change")!=null)                    this.lym_change=Double.parseDouble(properties.getProperty(prefix+"lym_change"));
		if (properties.getProperty(prefix+"lym_change_aux")!=null)                this.lym_change_aux=Double.parseDouble(properties.getProperty(prefix+"lym_change_aux"));

		if (properties.getProperty(prefix+"lym_poly_change")!=null)               this.lym_poly_change=Double.parseDouble(properties.getProperty(prefix+"lym_poly_change"));

		if (properties.getProperty(prefix+"lym_mod_map")!=null)                   this.lym_mod_map=Boolean.parseBoolean(properties.getProperty(prefix+"lym_mod_map"));
		if (properties.getProperty(prefix+"lym_top_bg")!=null)                    this.lym_top_bg=Boolean.parseBoolean(properties.getProperty(prefix+"lym_top_bg"));
		if (properties.getProperty(prefix+"lym_fill_gaps_bg")!=null)              this.lym_fill_gaps_bg=Integer.parseInt(properties.getProperty(prefix+"lym_fill_gaps_bg"));
		if (properties.getProperty(prefix+"lym_fill_gaps_combo")!=null)           this.lym_fill_gaps_combo=Integer.parseInt(properties.getProperty(prefix+"lym_fill_gaps_combo"));
		if (properties.getProperty(prefix+"lym_use_strength")!=null)              this.lym_use_strength=Boolean.parseBoolean(properties.getProperty(prefix+"lym_use_strength"));
		if (properties.getProperty(prefix+"lym_scale_deriv_str")!=null)           this.lym_scale_deriv_str=Double.parseDouble(properties.getProperty(prefix+"lym_scale_deriv_str"));
		
		if (properties.getProperty(prefix+"lyf_filter")!=null)                    this.lyf_filter=Boolean.parseBoolean(properties.getProperty(prefix+"lyf_filter"));
		if (properties.getProperty(prefix+"lyf_smpl_side")!=null)                 this.lyf_smpl_side=Integer.parseInt(properties.getProperty(prefix+"lyf_smpl_side"));
		if (properties.getProperty(prefix+"lyf_rms_max")!=null)                   this.lyf_rms_max=Double.parseDouble(properties.getProperty(prefix+"lyf_rms_max"));
@@ -2908,9 +2926,23 @@ public class CLTParameters {
		gd.addNumericField("Maximal number of iterations",                                                      this.lym_iter,  0);
		gd.addNumericField("Parameter vector difference to exit (main camera)",                                 this.lym_change,  10,12,"");
		gd.addNumericField("Parameter vector difference to exit (aux camera)",                                  this.lym_change_aux,  10,12,"");

		gd.addNumericField("Parameter vector difference to exit from polynomial correction",                    this.lym_poly_change,  10);

		gd.addMessage     ("--- Lazy eye data preparation ---");
		gd.addCheckbox    ("Modify preliminary disparity map before running LY",                                this.lym_mod_map,
				"LY may tolerate some disparity errors when just pure LY is needed");
		gd.addCheckbox    ("Consider all above infinity to be infinity",                                        this.lym_top_bg,
				"Valid for many, but not all scenes, such as tree branches over sky background");
		gd.addNumericField("Fill gaps in background selection",                                                 this.lym_fill_gaps_bg,  0, 2, "pix",
				"1 -  1 pixel in 4 directions, 2 - 1 step in 8 directions, ...");
		gd.addNumericField("Fill gaps in combo selection",                                                      this.lym_fill_gaps_combo,  0, 2, "pix",
				"1 -  1 pixel in 4 directions, 2 - 1 step in 8 directions, ...");
		gd.addCheckbox    ("Use strength when averaging disparity from neighbors",                              this.lym_use_strength,
				"Weight by strength when averaging missing disparity tiles, false - use equal weights");
		gd.addNumericField("Scale strength of the interpolated tiles from average neighbors strength",          this.lym_scale_deriv_str,  3, 6, "",
				"Multiply average strength of neighbors when assigning to a missing tile");
		
		
		gd.addMessage     ("--- Lazy eye samples filter ---");
		gd.addCheckbox    ("Filter lazy eye pairs by their values",                                             this.lyf_filter);
		gd.addNumericField("Fileter sample side (if 8, 8 x8 masked, 16x16 sampled)",                            this.lyf_smpl_side,  0);
@@ -3851,6 +3883,13 @@ public class CLTParameters {

		this.lym_poly_change=       gd.getNextNumber();
		
		this.lym_mod_map=           gd.getNextBoolean();
		this.lym_top_bg=            gd.getNextBoolean();
		this.lym_fill_gaps_bg = (int) gd.getNextNumber();
		this.lym_fill_gaps_combo = (int) gd.getNextNumber();
		this.lym_use_strength=      gd.getNextBoolean();
		this.lym_scale_deriv_str =  gd.getNextNumber();

		this.lyf_filter=            gd.getNextBoolean();
		this.lyf_smpl_side=   (int) gd.getNextNumber();
		this.lyf_rms_max=           gd.getNextNumber();
+5 −0
Original line number Diff line number Diff line
@@ -504,6 +504,11 @@ public class CLTPass3d{
			}
			return strength;
		}
		
		public void setStrength(double [] strength) {
			this.strength = strength;
		}
		
		/**
		 * Get four pairs (original) correlation strength. Not a copy
		 * @return line-scan array of per-tile horizontal pairs correlation strength by reference (not a copy)
+515 −38

File changed.

Preview size limit exceeded, changes collapsed.

+9 −3
Original line number Diff line number Diff line
@@ -597,8 +597,11 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)?
	}
	
	@Override
	public String toString() // USED in lwir
	{
	public String toString() { // USED in lwir
		return toString(false);
	}
	
	public String toString(boolean short_out) {
		String s;
		double [] sym_vect = toSymArray(null);
		double [] v = new double [vector.length];
@@ -649,6 +652,9 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)?
		s+= "azimuth (right):"; for (int i = 0; i < n; i++) s += String.format(" %8.4fpx", azimuths[i]); s+=" (shift of the image center)\n"; 
		s+= "roll    (CW):   "; for (int i = 0; i < n; i++) s += String.format(" %8.4fpx", rolls[i]);    s+=" (shift at the image half-width from the center)\n"; 
		s+= "diff zoom (in): "; for (int i = 0; i < n; i++) s += String.format(" %8.4fpx", zooms[i]);    s+=" (shift at the image half-width from the center)\n";
		if (short_out) {
			return s;
		}
		s += "Symmetrical vector:\n";
		if (getNumSensors() == 4) { // Use arrows for quad camera only (but update to match new
			// ← → ↑ ↓ ⇖ ⇗ ⇘ ⇙ ↔ ↺ ↻ 
+110 −13
Original line number Diff line number Diff line
@@ -2120,6 +2120,45 @@ public class Correlation2d {
		}
		return rslt;
	}
	
	/**
	 * Get fractional center as a "center of mass" for all pixels
	 * Data should be masked by the caller 
	 * @param data correlation data [(2 * transform_size - 1) * (2 * transform_size - 1)]
	 * @param data_width
	 * @param center_row
	 * @param debug
	 * @return argmax() relative to the tile center
	 */
	
	public double [] getMaxXYCm( // not used in lwir
			double [] data,
			int       data_width,      //  = 2 * transform_size - 1;
			int       center_row,
			boolean   debug)
	{
		int data_height = data.length/data_width;
		int center_x = (data_width - 1)/2; //  = transform_size - 1;
		//calculate as "center of mass"
		double s0 = 0, sx=0,sy = 0;
		for (int iy = 0; iy < data_height; iy++) {
			double y = iy - center_row;
			for (int ix = 0; ix < data_width; ix++) {
				double x = ix - center_x;
				double d =  data[iy * data_width + ix];
				s0 += d;
				sx += d * x;
				sy += d * y;
			}
		}
		double [] rslt = {sx / s0, sy / s0};
		if (debug){
			System.out.println("getMaxXYCm() -> "+rslt[0]+":"+rslt[1]);
		}
		return rslt;
	}
	
	
	/**
	 * Calculate 1-d maximum location, strength and half-width for the special strip (odd rows shifted by 0.5
	 * Negative values are ignored!
@@ -3430,7 +3469,6 @@ public class Correlation2d {
    						imgdtt_params.lma_adjust_wy,  // boolean adjust_ellipse,   // allow non-circular correlation maximums lma_adjust_wy
    						true, // imgdtt_params.lma_adjust_wxy, // boolean adjust_lazyeye_par,   // adjust disparity corrections parallel to disparities  lma_adjust_wxy
    						true, // imgdtt_params.lma_adjust_ly1, // boolean adjust_lazyeye_ortho, // adjust disparity corrections orthogonal to disparities lma_adjust_ly1

    						ds, // disp_str, // xcenter_str,                  // double [][] disp_str,         // initial value of disparity/strength/?
    						imgdtt_params.lma_half_width, // double  half_width,       // A=1/(half_widh)^2   lma_half_width
    						imgdtt_params.lma_cost_wy,     // double  cost_lazyeye_par,     // cost for each of the non-zero disparity corrections        lma_cost_wy
@@ -3600,7 +3638,7 @@ public class Correlation2d {


    	double [][] dbg_corr =    debug_graphic ? new double [corrs.length][] : null;
    	double [][] dbg_weights = debug_graphic ? new double [corrs.length][] : null;
//    	double [][] dbg_weights = debug_graphic ? new double [corrs.length][] : null;
    	if (debug_graphic) {
    		(new ShowDoubleFloatArrays()).showArrays(
    				corrs,
@@ -3614,6 +3652,7 @@ public class Correlation2d {


//    	for (int npair = 0; npair < corrs.length; npair++) if ((corrs[npair] != null) && (((pair_mask >> npair) & 1) !=0)){
    	double [][] filtWeight = new double [corrs.length][];
   		for (int npair = 0; npair < corrs.length; npair++) if ((corrs[npair] != null) && (pair_mask[npair])){
    		
//    		double[] corr = corrs[npair].clone();
@@ -3638,7 +3677,7 @@ public class Correlation2d {
    		// filter convex
    		int ix0 = (imx % corr_size) - center; // signed, around center to match filterConvex
    		int iy0 = (imx / corr_size) - center; // signed, around center to match filterConvex
    	    double [] filtWeight =  filterConvex(
    	    filtWeight[npair] =  filterConvex(
    	    		corr_blur,             // double [] corr_data,
    	            imgdtt_params.cnvx_hwnd_size, // int       hwin,
    	            ix0,                          // int       x0,
@@ -3647,17 +3686,17 @@ public class Correlation2d {
    	            imgdtt_params.cnvx_weight,    // double    nc_cost,
    	            (debug_level > 2));           // boolean   debug);
    	    if (dbg_corr    != null) 	dbg_corr   [npair] = corr_blur;
    	    if (dbg_weights != null) 	dbg_weights[npair] = filtWeight;
//    	    if (dbg_weights != null) 	dbg_weights[npair] = filtWeight[npair];

    	    // Normalize weight for each pair to compensate for different number of convex samples?

//    	    int fcam = PAIRS[npair][0];
//    	    int scam = PAIRS[npair][1];
    	    for (int i = 1; i < filtWeight.length; i++) if (filtWeight[i] > 0.0) {
    	    for (int i = 1; i < filtWeight[npair].length; i++) if (filtWeight[npair][i] > 0.0) {
    	    	int ix = i % corr_size; // >=0
    	    	int iy = i / corr_size; // >=0
    	    	double v = corrs[npair][i]; // not blurred
    	    	double w = filtWeight[i];
    	    	double w = filtWeight[npair][i];
    	        if (vasw_pwr != 0) {
    	            w *= Math.pow(Math.abs(v), vasw_pwr);
    	        }
@@ -3685,7 +3724,7 @@ public class Correlation2d {
    				getCorrTitles());

    		(new ShowDoubleFloatArrays()).showArrays(
    				dbg_weights,
    				filtWeight,
    				corr_size,
    				corr_size,
    				true,
@@ -3699,22 +3738,45 @@ public class Correlation2d {
    		disp_str2[0] = disp_str;
    	}
//    	double [][] disp_str2 = {{0.0, 1.0}}; // temporary // will be calculated/set later
    	
    	
    	
    	boolean lmaSuccess = false;
		double [] disp = null;
		// adjust_ly
		double [][] ly_offsets_pairs = null;
		if (adjust_ly) {
			ly_offsets_pairs = getPairsCenters(
					corrs, // 		double [][] corrs,
					filtWeight); // double [][] weights)
		}
		double      step_weight = 0.5; // scale corrections
		double      min_correction = 0.1; //  exit when maximal XY correction is below
		
		while (!lmaSuccess) {
    		lma.initVector( // USED in lwir
    		lma.initVector(
    				imgdtt_params.lmas_adjust_wm,  // boolean adjust_width,     // adjust width of the maximum - lma_adjust_wm
    				imgdtt_params.lmas_adjust_ag,  // boolean adjust_scales,    // adjust 2D correlation scales - lma_adjust_ag
    				imgdtt_params.lmas_adjust_wy,  // boolean adjust_ellipse,   // allow non-circular correlation maximums lma_adjust_wy
    				(adjust_ly ? imgdtt_params.lma_adjust_wxy : false), //imgdtt_params.lma_adjust_wxy, // boolean adjust_lazyeye_par,   // adjust disparity corrections parallel to disparities  lma_adjust_wxy
    				(adjust_ly ? imgdtt_params.lma_adjust_ly1: false), // imgdtt_params.lma_adjust_ly1, // boolean adjust_lazyeye_ortho, // adjust disparity corrections orthogonal to disparities lma_adjust_ly1
    				disp_str2, // xcenter,                      // double  disp0,            // initial value of disparity
    				disp_str2, // xcenter, 
    				imgdtt_params.lma_half_width, // double  half_width,       // A=1/(half_widh)^2   lma_half_width
    				(adjust_ly ? imgdtt_params.lma_cost_wy : 0.0), // imgdtt_params.lma_cost_wy,     // double  cost_lazyeye_par,     // cost for each of the non-zero disparity corrections        lma_cost_wy
    				(adjust_ly ? imgdtt_params.lma_cost_wxy : 0.0) //imgdtt_params.lma_cost_wxy     // double  cost_lazyeye_odtho    // cost for each of the non-zero ortho disparity corrections  lma_cost_wxy
    				);
    		
    		lma.setMatrices(disp_dist);
    		lma.initMatrices(); // should be called after initVector and after setMatrices
    		boolean all_sensors_used = lma.setInitialLYOffsets(
    				ly_offsets_pairs,  // double [][] pair_centers,
    				step_weight,       // double      step_weight, // scale corrections
    				min_correction,    // double      min_correction ){  // exit when maximal XY correction is below
    				(debug_level > 0)); // 
    		if (adjust_ly && !all_sensors_used) {
    			return null; //LY requested, but not all sensors present
    		}

    		//center
    		disp = null;
    		if (need_poly) {
@@ -3724,8 +3786,15 @@ public class Correlation2d {
    					debug_graphic?dbg_title:null); // 		double [] rslt = {-approx2d[0], approx2d[2], hwx, hwy};

    			if (disp == null) {
    				if (imgdtt_params.lmas_poly_continue && (disp == null)) {
    					disp = disp_str2[0];
    					if (debug_level > 0) {
    					System.out.println("Poly disparity=NULL");
    						System.out.println("Poly disparity=NULL, using tile center for initial LMA");
    					}
    				} else {
    					if (debug_level > 0) {
    						System.out.println("Poly disparity=NULL, set lmas_poly_continue to true to use tile center instead");
    					}
    				}
    			} else {
    				disp[1] *= imgdtt_params.lmas_poly_str_scale;
@@ -3748,6 +3817,9 @@ public class Correlation2d {
    		} else {
    			disp = disp_str;
    		}
    		
    		
    		
    		if (disp != null) {
    			disp_str2[0] = disp;
    			lma.initDisparity( // USED in lwir
@@ -3785,7 +3857,7 @@ public class Correlation2d {
    		lma.updateFromVector();


    		double [][] dispStr = lma.lmaDisparityStrength(
    		double [][] dispStr = lma.lmaDisparityStrength( //TODO: add parameter to filter out negative minimums ?
    				imgdtt_params.lmas_max_rel_rms,  // maximal relative (to average max/min amplitude LMA RMS) // May be up to 0.3)
    				imgdtt_params.lmas_min_strength, // minimal composite strength (sqrt(average amp squared over absolute RMS)
    				imgdtt_params.lmas_min_ac,       // minimal of A and C coefficients maximum (measures sharpest point/line)
@@ -3846,6 +3918,31 @@ public class Correlation2d {
    	return lmaSuccess? lma: null;
    }

    public double [][] getPairsCenters(
    		double [][] corrs,
    		double [][] weights){
    	double [][] xy_offsets_pairs = new double[corrs.length][]; // 
    	for (int np = 0; np < corrs.length; np++) if (corrs[np]!= null) {
            double [] wcorr = new double [corrs[np].length];
        	double  pair_weights = 0.0;
            for (int i = 0; i < wcorr.length; i++) if (weights[np][i] > 0.0){
            	wcorr[i] = corrs[np][i]*weights[np][i];
            	pair_weights += wcorr [i];
            }
            double [] dxy = getMaxXYCm(
            		wcorr,   // double [] data,
                    getCombWidth(), //       data_width,
                    getCombHeight()/2 - getCombOffset(), // int       center_row
        			false); // boolean   debug)
            xy_offsets_pairs[np] = new double[3];
            xy_offsets_pairs[np][0] = dxy[0];
            xy_offsets_pairs[np][1] = dxy[1];
            xy_offsets_pairs[np][2] = pair_weights;
    	}
    	return xy_offsets_pairs;
    }
    
    
    
    public Correlations2dLMA corrLMA( // USED in lwir
    		ImageDttParameters  imgdtt_params,
Loading