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

Added 32-bit tiff output for ML data

parent 70ccd5f4
Loading
Loading
Loading
Loading
+122 −6
Original line number Diff line number Diff line
@@ -65,6 +65,25 @@ public class BiQuadParameters {
	public boolean rig_adjust_forward =        false;  // aux camera forward from the principal plane (not implemented)
	public double  rig_correction_scale=       1.0;    // scale calculaated correction

	public int     min_new =                   100;    // Minimal number of he new tiles during rig refine
	public int     num_inf_refine =            20;     // Number of infinity refine passes
	public int     num_near_refine =           20;     // Number of non-infinity refine passes
	public double  min_trusted_strength =      0.1;//14// Minimal trusted combo strength;
	public double  trusted_tolerance  =        1.0;    // Trusted tolerance for small baseline camera(s)

	public int     ml_hwidth =                 2;      // Half-width of the ML tiles to export (0-> 1x1, 1->3x3, 2 -> 5x5)
	public double  ml_disparity_sweep  =       2.0;    // Disparity sweep around ground truth, each side
	public int     ml_sweep_steps =            5;      // Number of disparity sweep steps

	public boolean ml_keep_aux =               true; // include auxiliary camera data in the ML output
	public boolean ml_keep_inter =             true; // include inter-camera correlation data in the ML output
	public boolean ml_keep_hor_vert =          true; // include combined horizontal and vertical pairs data in the ML output
	public boolean ml_keep_debug=              true; // include debug layer(s) data in the ML output
	public boolean ml_8bit=                    true; // output in 8-bit format (default - 32-bit TIFF
	public boolean ml_show_ml =                true; // show each generated MLoutput file





	public void dialogQuestions(GenericJTabbedDialog gd) {
@@ -136,6 +155,39 @@ public class BiQuadParameters {
		gd.addCheckbox    ("Adjust aux camera distance from the main principal plane",                            this.rig_adjust_forward,"Not implemented, assumed zero");
		gd.addNumericField("Scale calculated correction before applying",                                         this.rig_correction_scale,  3,6,"",
				"Debug feature");

		gd.addNumericField("Minimal number of he new tiles during rig refine",                                    this.min_new,  0,3,"",
				"Exit from refine infinity cycle if number of new refine candidates is less than this number");
		gd.addNumericField("Number of infinity refine passes",                                                    this.num_inf_refine,  0,3,"",
				"Exit from refine non- infinity cycle if number of new refine candidates is less than this number");
		gd.addNumericField("Number of non-infinity refine passes",                                                this.num_near_refine,  0,3,"",
				"Re-scan only previously selected tiles");
		gd.addNumericField("Minimal trusted combo strength",                                                      this.min_trusted_strength,  3,6,"",
				"Combo strength is cubic root of the product of main, aux and intyer correlation strengths");
		gd.addNumericField("Trusted tolerance for small baseline camera(s)",                                      this.trusted_tolerance,  3,6,"",
				"When downscaling valid residual disparity from the most sensitive inter-camera, do not reduce it to be lower than this");

        gd.addTab("ML","Parameters related to the ML files generation for the dual-quad camera rig");

		gd.addNumericField("Half-width of the ML tiles to export (0-> 1x1, 1->3x3, 2 -> 5x5)",                    this.ml_hwidth,  0,3,"",
				"Amount of data to export to the ML system");
		gd.addNumericField("Disparity sweep around ground truth, each side",                                      this.ml_disparity_sweep,  3,6,"",
				"Sweep symmetrically target disparity around the ground truth disparity, each side");
		gd.addNumericField("Number of target disparity sweep steps",                                                               this.ml_sweep_steps,  0,3,"",
				"Generate this many files for each file set. Each tile results depend on the target disparity and this tile data, do not depend on other tiles target disparity");
		gd.addCheckbox    ("Include auxiliary camera data in the ML output",                                      this.ml_keep_aux,
				"ML output will have the second set of the layers for the auxiliary camera. Disparity values should be scaled for the camera baseline");
		gd.addCheckbox    ("Keep inter-camera correlation data",                                                  this.ml_keep_inter,
				"Inter-camera correlation data has only one layer (and one correlation pair). It is used to generate ground truth data. Usable disparity range (measured in the main camera pixels) is ~1/5 of teh main camera");
		gd.addCheckbox    ("Keep combine horizonta/vertical pairs",                                               this.ml_keep_hor_vert,
				"Each of these two layers per camera are calculated from a pair of top/bottom and left/right pairs. Can possibly be used instead of originals to reduce amount of input data");
		gd.addCheckbox    ("Keep debug layer(s)",                                                                 this.ml_keep_debug,
				"Keep additional (debug) layers that may change for different file versions");
		gd.addCheckbox    ("Use 8 bpp TIFF (default - 32 bpp)",                                                   this.ml_8bit,
				"Reduce file size by lowering bpp");
		gd.addCheckbox    ("Show each generated ML file",                                                         this.ml_show_ml,
				"Use only for small number of generated files to reduce memory usage");

	}
	public void dialogAnswers(GenericJTabbedDialog gd) {
		this.rig_mode_debug=                gd.getNextBoolean();
@@ -174,6 +226,22 @@ public class BiQuadParameters {
		this.rig_adjust_distance=           gd.getNextBoolean();
		this.rig_adjust_forward=            gd.getNextBoolean();
		this.rig_correction_scale=          gd.getNextNumber();

		this.min_new=                 (int) gd.getNextNumber();
		this.num_inf_refine=          (int) gd.getNextNumber();
		this.num_near_refine=         (int) gd.getNextNumber();
		this.min_trusted_strength=          gd.getNextNumber();
		this.trusted_tolerance=             gd.getNextNumber();

		this.ml_hwidth=               (int) gd.getNextNumber();
		this.ml_disparity_sweep=            gd.getNextNumber();
		this.ml_sweep_steps=          (int) gd.getNextNumber();
		this.ml_keep_aux=                   gd.getNextBoolean();
		this.ml_keep_inter=                 gd.getNextBoolean();
		this.ml_keep_hor_vert=              gd.getNextBoolean();
		this.ml_keep_debug=                 gd.getNextBoolean();
		this.ml_8bit=                       gd.getNextBoolean();
		this.ml_show_ml=                    gd.getNextBoolean();
	}

	public void setProperties(String prefix,Properties properties){
@@ -216,6 +284,23 @@ public class BiQuadParameters {
		properties.setProperty(prefix+"rig_adjust_forward",        this.rig_adjust_forward+"");
		properties.setProperty(prefix+"rig_correction_scale",      this.rig_correction_scale+"");

		properties.setProperty(prefix+"min_new",                   this.min_new+"");
		properties.setProperty(prefix+"num_inf_refine",            this.num_inf_refine+"");
		properties.setProperty(prefix+"num_near_refine",           this.num_near_refine+"");
		properties.setProperty(prefix+"min_trusted_strength",      this.min_trusted_strength+"");
		properties.setProperty(prefix+"trusted_tolerance",         this.trusted_tolerance+"");

		properties.setProperty(prefix+"ml_hwidth",                 this.ml_hwidth+"");
		properties.setProperty(prefix+"ml_disparity_sweep",        this.ml_disparity_sweep+"");
		properties.setProperty(prefix+"ml_sweep_steps",            this.ml_sweep_steps+"");
		properties.setProperty(prefix+"ml_keep_aux",               this.ml_keep_aux+"");
		properties.setProperty(prefix+"ml_keep_inter",             this.ml_keep_inter+"");
		properties.setProperty(prefix+"ml_keep_hor_vert",          this.ml_keep_hor_vert+"");
		properties.setProperty(prefix+"ml_keep_debug",             this.ml_keep_debug+"");
		properties.setProperty(prefix+"ml_8bit",                   this.ml_8bit+"");
		properties.setProperty(prefix+"ml_show_ml",                this.ml_show_ml+"");


	}
	public void getProperties(String prefix,Properties properties){
		if (properties.getProperty(prefix+"rig_mode_debug")!=null)        this.rig_mode_debug=Boolean.parseBoolean(properties.getProperty(prefix+"rig_mode_debug"));
@@ -254,6 +339,21 @@ public class BiQuadParameters {
		if (properties.getProperty(prefix+"rig_adjust_forward")!=null)      this.rig_adjust_forward=Boolean.parseBoolean(properties.getProperty(prefix+"rig_adjust_forward"));
		if (properties.getProperty(prefix+"rig_correction_scale")!=null)    this.rig_correction_scale=Double.parseDouble(properties.getProperty(prefix+"rig_correction_scale"));

		if (properties.getProperty(prefix+"min_new")!=null)                 this.min_new=Integer.parseInt(properties.getProperty(prefix+"min_new"));
		if (properties.getProperty(prefix+"num_inf_refine")!=null)          this.num_inf_refine=Integer.parseInt(properties.getProperty(prefix+"num_inf_refine"));
		if (properties.getProperty(prefix+"num_near_refine")!=null)         this.num_near_refine=Integer.parseInt(properties.getProperty(prefix+"num_near_refine"));
		if (properties.getProperty(prefix+"min_trusted_strength")!=null)    this.min_trusted_strength=Double.parseDouble(properties.getProperty(prefix+"min_trusted_strength"));
		if (properties.getProperty(prefix+"trusted_tolerance")!=null)       this.trusted_tolerance=Double.parseDouble(properties.getProperty(prefix+"trusted_tolerance"));
		if (properties.getProperty(prefix+"ml_hwidth")!=null)               this.ml_hwidth=Integer.parseInt(properties.getProperty(prefix+"ml_hwidth"));

		if (properties.getProperty(prefix+"ml_disparity_sweep")!=null)      this.ml_disparity_sweep=Double.parseDouble(properties.getProperty(prefix+"ml_disparity_sweep"));
		if (properties.getProperty(prefix+"ml_sweep_steps")!=null)          this.ml_sweep_steps=Integer.parseInt(properties.getProperty(prefix+"ml_sweep_steps"));
		if (properties.getProperty(prefix+"ml_keep_aux")!=null)             this.ml_keep_aux=Boolean.parseBoolean(properties.getProperty(prefix+"ml_keep_aux"));
		if (properties.getProperty(prefix+"ml_keep_inter")!=null)           this.ml_keep_inter=Boolean.parseBoolean(properties.getProperty(prefix+"ml_keep_inter"));
		if (properties.getProperty(prefix+"ml_keep_hor_vert")!=null)        this.ml_keep_hor_vert=Boolean.parseBoolean(properties.getProperty(prefix+"ml_keep_hor_vert"));
		if (properties.getProperty(prefix+"ml_keep_debug")!=null)           this.ml_keep_debug=Boolean.parseBoolean(properties.getProperty(prefix+"ml_keep_debug"));
		if (properties.getProperty(prefix+"ml_8bit")!=null)                 this.ml_8bit=Boolean.parseBoolean(properties.getProperty(prefix+"ml_8bit"));
		if (properties.getProperty(prefix+"ml_show_ml")!=null)              this.ml_show_ml=Boolean.parseBoolean(properties.getProperty(prefix+"ml_show_ml"));
	}
	@Override
	public BiQuadParameters clone() throws CloneNotSupportedException {
@@ -293,6 +393,22 @@ public class BiQuadParameters {
		bqp.rig_adjust_distance=        this.rig_adjust_distance;
		bqp.rig_adjust_forward=         this.rig_adjust_forward;
		bqp.rig_correction_scale=       this.rig_correction_scale;

		bqp.min_new=                    this.min_new;
		bqp.num_inf_refine=             this.num_inf_refine;
		bqp.num_near_refine=            this.num_near_refine;
		bqp.min_trusted_strength=       this.min_trusted_strength;
		bqp.trusted_tolerance=          this.trusted_tolerance;

		bqp.ml_hwidth=                  this.ml_hwidth;
		bqp.ml_disparity_sweep=         this.ml_disparity_sweep;
		bqp.ml_sweep_steps=             this.ml_sweep_steps;
		bqp.ml_keep_aux=                this.ml_keep_aux;
		bqp.ml_keep_inter=              this.ml_keep_inter;
		bqp.ml_keep_hor_vert=           this.ml_keep_hor_vert;
		bqp.ml_keep_debug=              this.ml_keep_debug;
		bqp.ml_8bit=                    this.ml_8bit;
		bqp.ml_show_ml=                 this.ml_show_ml;
		return bqp;


+3 −3
Original line number Diff line number Diff line
@@ -512,7 +512,7 @@ public class CLTPass3d{
		 *
		 * Replace weak by a weighted average of non-weak. If there are none - use weak ones, including this one too.
		 */
		public boolean[] replaceWeakOutlayers(
		public boolean[] replaceWeakOutliers(
				final boolean [] selection,
				final double weakStrength,    // strength to be considered weak, subject to this replacement
				final double maxDiff,
@@ -546,7 +546,7 @@ public class CLTPass3d{
									(disparity[nTile] < absMinDisparity) ||
									(disparity[nTile] > absMaxDisparity))&& ((selection == null) || selection[nTile])) {
								if (nTile == dbg_nTile){
									System.out.println("replaceWeakOutlayers():1 nTile="+nTile);
									System.out.println("replaceWeakOutliers():1 nTile="+nTile);
								}
								double [] dbg_disparity = disparity;
								double dbg_disparity_nTile = disparity[nTile];
@@ -602,7 +602,7 @@ public class CLTPass3d{
					public void run() {
						for (int nTile = ai.getAndIncrement(); nTile < nTiles; nTile = ai.getAndIncrement()) {
							if (nTile == dbg_nTile){
								System.out.println("replaceWeakOutlayers():2 nTile="+nTile);
								System.out.println("replaceWeakOutliers():2 nTile="+nTile);
							}
							if (weakOutlayers[nTile]) {
								double sw = 0.0, sd = 0.0;
+175 −2
Original line number Diff line number Diff line
@@ -185,6 +185,42 @@ public class Correlation2d {
    		double [][] clt_data2,
    		double [][] tcorr, // null or initialized to [4][transform_len]
    		double      fat_zero) {
    	if (tcorr == null) tcorr = new double [4][transform_len];
    	double [] a2 = new double[transform_len];
    	double sa2 = 0.0;
		for (int i = 0; i < transform_len; i++) {
			double s1 = 0.0, s2=0.0;
			for (int n = 0; n< 4; n++){
				s1+=clt_data1[n][i] * clt_data1[n][i];
				s2+=clt_data2[n][i] * clt_data2[n][i];
			}
			a2[i] = Math.sqrt(s1*s2);
			sa2 += a2[i];
		}
		double fz2 = sa2/transform_len * fat_zero * fat_zero; // fat_zero squared to match units
		for (int i = 0; i < transform_len; i++) {
			double scale = 1.0 / (a2[i] + fz2);
			for (int n = 0; n<4; n++){
				tcorr[n][i] = 0;
				for (int k=0; k<4; k++){
					if (ZI[n][k] < 0)
						tcorr[n][i] -=
								clt_data1[-ZI[n][k]][i] * clt_data2[k][i];
					else
						tcorr[n][i] +=
								clt_data1[ZI[n][k]][i] * clt_data2[k][i];
				}
				tcorr[n][i] *= scale;
			}
		}
		return tcorr;
    }

    public double[][] correlateSingleColorFD_old(
    		double [][] clt_data1,
    		double [][] clt_data2,
    		double [][] tcorr, // null or initialized to [4][transform_len]
    		double      fat_zero) {
    	if (tcorr == null) tcorr = new double [4][transform_len];
		for (int i = 0; i < transform_len; i++) {
			double s1 = 0.0, s2=0.0;
@@ -210,6 +246,7 @@ public class Correlation2d {
    }



    /**
     * Calculate color channels FD phase correlations, mix results with weights, apply optional low-pass filter
     * and convert to the pixel domain  as [(2*transform_size-1) * (2*transform_size-1)] tiles (15x15)
@@ -845,6 +882,7 @@ public class Correlation2d {
	}
	/**
	 * Calculate 1-d maximum location, strength and half-width for the special strip (odd rows shifted by 0.5
	 * Negative values are ignored!
	 * Both x and y half-windows can be variable length (to reduce calculations with 0.0 elements), normalized
	 * so sums of zero element and twice all others are 1.0
	 * Window in Y direction corresponds to correlation stripe rows, corresponding to sqrt(2)/2 sensor pixels
@@ -992,6 +1030,140 @@ public class Correlation2d {
	}


	/**
	 * Extract center 2-d correlation around zero from the full (now 15x15)
	 * @param hwidth half width of the output tile (0 -> 1x1, 1-> 3x3, 2->5x5)
	 * @param full_corr  full pixel-domain correlation (now 15x15=225 long)
	 * @param center_corr - output array [(2*hwidth+1)*(2*hwidth+1)] or null
	 * @return center_corr - center part of the correlation in linescan order
	 */
    public double [] corrCenterValues(
    		int       hwidth,
    		double [] full_corr,
    		double [] center_corr) {
    	if (full_corr == null) return null;
    	int center = transform_size - 1;
    	int width = 2 * center + 1;
    	int owidth = 2*hwidth+1;
    	if (center_corr == null) center_corr = new double [owidth*owidth];
    	int indx = 0;
    	int findx = (center - hwidth) * (width + 1); // top left corner
    	for (int row = 0; row < owidth; row++) {
        	for (int col = 0; col < owidth; col++) {
        		center_corr[indx++] = full_corr[findx++];
        	}
        	findx += width-owidth;
    	}
    	return center_corr;
    }

    /**
     * Extract center 2-d correlations around zero from the full (now 15x15) correlations
     * for each of the 6 pairs and 2 combined directions (horizontal, vertical)
     * @param hwidth half width of the output tile (0 -> 1x1, 1-> 3x3, 2->5x5)
     * @param offset add before multiplication, subtract in the end. If negative - use averaging
     *  instead of the shifted multiplication
     * @param full_corr  full pixel-domain correlation (now 15x15=225 long)for each of 6 pairs
     * @param center_corr - output array [(2*hwidth+1)*(2*hwidth+1)]. should be [8][]
     */
    public void corrCenterValues(
    		int         hwidth,
    		double      offset,
    		double [][] full_corr,
    		double [][] center_corr) {
    	// first 6 layers - directly correspond to pairs (top, bottom, left, right, diagonal main, diagonal other)
    	for (int i = 0; i < 6; i++) {
    		center_corr[i] = corrCenterValues(
    				hwidth,
    				full_corr[i],
    				center_corr[i]);
    	}

    	// combine vertical and horizontal pairs
    	int center = transform_size - 1;
    	int width =  2 * center + 1;
    	int owidth = 2 * hwidth + 1;
    	for (int ndir = 0; ndir < 2; ndir++) { // 0- hor, 1- vert
    		if (center_corr[ndir] == null) center_corr[ndir] = new double [owidth*owidth];
    		int indx = 0;
    		int findx = (center - hwidth) * (width + 1); // top left corner
    		for (int row = 0; row < owidth; row++) {
    			for (int col = 0; col < owidth; col++) {
    				double fc0 = full_corr[2 * ndir + 0][findx]; // 0 (top), 2 (left)
    				double fc1 = full_corr[2 * ndir + 1][findx++]; // 1 - bottom, 3 (right)
    				double cc = 0.0;
    				if (offset >= 0.0) {
    					if ((fc0 > 0.0) && (fc1 > 0.0)) {
    						cc = Math.sqrt((fc0+offset)*(fc1+offset)) - offset;
    					}
    				} else {
    					cc =  0.5*(fc0+fc1);
    				}

    				center_corr[ndir + 6][indx++] = cc; // save to 6-th and 7-th layer
    			}
    			findx += width-owidth;
    		}
    	}
    }

    /**
     * Save 2d correlation data for one layer, one tile into the combined multi-layer ML array, viewable as an image
     * @param tileX horizontal tile index
     * @param tileY vertical tile index
     * @param ml_hwidth half-width of the preserved 2d correlation (0 - single point, 1 -> 3x3, 2 -> 5x5, 7 - all data)
     * @param ml_data multi-layer array, each layer matches an image of ((2 * ml_hwidth + 1) * tilesX) by ((2 * ml_hwidth + 1) * tilesY) in scanline order
     * Each tile corresponds to  (2 * ml_hwidth + 1) * (2 * ml_hwidth + 1) square in the image. Only selected tiles will be updated, so it is good to initialize array
     * with all Double.NaN values
     * @param ml_layer layer to save tile data
     * @param ml_tile (2 * ml_hwidth + 1) * (2 * ml_hwidth + 1) tile data to be saved
     * @param tilesX image width in tiles
     */
    public void saveMlTile(
    		int         tileX,
    		int         tileY,
    		int         ml_hwidth,
    		double [][] ml_data,
    		int         ml_layer,
    		double []   ml_tile,
    		int         tilesX) {
    	int tile_width = 2 * ml_hwidth + 1;
    	int full_width = tile_width * tilesX;
    	int oindex = tileY *tile_width * full_width  + tileX * tile_width;
    	for (int row = 0; row < tile_width; row++) {
			System.arraycopy(ml_tile, row * tile_width, ml_data[ml_layer], oindex, tile_width);
			oindex += full_width;
    	}
    }
    /**
     * Save a single value to the combined multi-layer ML array, viewable as an image
     * @param tileX horizontal tile index
     * @param tileY vertical tile index
     * @param ml_hwidth half-width of the preserved 2d correlation (0 - single point, 1 -> 3x3, 2 -> 5x5, 7 - all data)
     * @param ml_data multi-layer array, each layer matches an image of ((2 * ml_hwidth + 1) * tilesX) by ((2 * ml_hwidth + 1) * tilesY) in scanline order
     * Each tile corresponds to  (2 * ml_hwidth + 1) * (2 * ml_hwidth + 1) square in the image. Only selected tiles will be updated, so it is good to initialize array
     * with all Double.NaN values
     * @param ml_layer layer to save tile data
     * @param ml_index data index within tile
     * @param ml_value value to set
     * @param tilesX image width in tiles
     */
    public void saveMlTilePixel(
    		int         tileX,
    		int         tileY,
    		int         ml_hwidth,
    		double [][] ml_data,
    		int         ml_layer,
    		int         ml_index,
    		double      ml_value,
    		int         tilesX) {
    	int tile_width = 2 * ml_hwidth + 1;
    	int full_width = tile_width * tilesX;
    	int oindex = tileY *tile_width * full_width  + tileX * tile_width + (ml_index/tile_width)*full_width + (ml_index%tile_width) ;
    	ml_data[ml_layer][oindex] = ml_value;
    }




    public double [] debugStrip(
@@ -1238,6 +1410,7 @@ public class Correlation2d {
    	return rslt;
    }

    // ignores negative values
    public double [] single2dCM( // returns x-xcenter, y, strength (sign same as disparity)
    		ImageDttParameters  imgdtt_params,
    		double []           corr,
@@ -1408,7 +1581,7 @@ public class Correlation2d {
    		System.out.println(String.format("eff_strength = [%8.5f, %8.5f, %8.5f, %8.5f]", eff_strength[0], eff_strength[1], eff_strength[2], eff_strength[3]));
    		System.out.println(String.format("width_d =      [%8.5f, %8.5f, %8.5f, %8.5f]", width_d[0],      width_d[1],      width_d[2],      width_d[3]));
    	}
		if (!strong[isel] || (isel <0)) {
		if ((isel <0) || !strong[isel]) {
			corr = Double.NaN;
			if (debug) System.out.println("Direction with "+(bg?"min":"max")+" disparity is not strong enough -> no correction");
		} else 		if (width_d[isel] > max_hwidth) {
@@ -1446,7 +1619,7 @@ public class Correlation2d {
    		}
    		if (debug) System.out.println("lim =  "+lim+", disp = "+disp);
    	}
    	double [] rslt = {disp, eff_strength[isel], mx - mn, are_ortho ?1.0 : 0.0};
    	double [] rslt = {disp, (isel >=0) ? eff_strength[isel]:0.0, mx - mn, are_ortho ?1.0 : 0.0};
		if (debug) System.out.println(String.format("foregroundCorrect() -> [%8.5f, %8.5f, %8.5f, %3.1f]", rslt[0], rslt[1], rslt[2], rslt[3]));

    	return    rslt;
+26 −8

File changed.

Preview size limit exceeded, changes collapsed.

+123 −3

File changed.

Preview size limit exceeded, changes collapsed.

Loading