Loading src/main/java/com/elphel/imagej/tileprocessor/BiQuadParameters.java +8 −4 Original line number Diff line number Diff line Loading @@ -260,6 +260,7 @@ public class BiQuadParameters { // FG/BG split for far tiles where dual max can only be detected with LMA as it is too small public boolean fsplit_en = true; // enable split of far tiles into FG/BG with LMA // fsplit_mode==2 now (04/17/2023) worse than fsplit_mode==1 public int fsplit_mode = 1; // 0: disable, 1:avg->fg+bg, 2: avg->fg+fg:fg:bg public double fsplit_str = 0.4; // minimal strength of the tile to split public int fsplit_neibs = 3; // minimal number of neighbors to consider split Loading @@ -270,6 +271,7 @@ public class BiQuadParameters { public double fsplit_adiff = 0.02; //4;// minimal tile (combo) absolute disparity difference from neighbors public double fsplit_rdiff = 0.02; // 1; // minimal tile (combo) relative disparity difference from neighbors public double fsplit_kfg_min = 0.05; // *** minimal fraction of kfg and (1.0-kfg) public boolean fsplit_dbg = false; public boolean mll_generate_scene_outlines = false; // Uses 2 GB - change format, add dimensions (separate color for ref) Loading Loading @@ -741,6 +743,8 @@ public class BiQuadParameters { "Maximal relative (to average) disparity difference from average of neighbors for FG/BG split."); gd.addNumericField("Minimal kFG fraction", this.fsplit_kfg_min, 3,6,"", "Minimal fraction of kfg and (1.0-kfg)."); gd.addCheckbox ("Debug far FG/BG split ", this.fsplit_dbg, "Generate and save scene outlines for scene series (need to change format, it is 2GB with uncompressed Tiff)"); gd.addMessage("Other"); gd.addCheckbox ("Generate scene outlines", this.mll_generate_scene_outlines, Loading Loading @@ -1059,7 +1063,7 @@ public class BiQuadParameters { this.fsplit_adiff = gd.getNextNumber(); this.fsplit_rdiff = gd.getNextNumber(); this.fsplit_kfg_min = gd.getNextNumber(); this.fsplit_dbg = gd.getNextBoolean(); this.mll_generate_scene_outlines= gd.getNextBoolean(); this.mll_add_combo= gd.getNextBoolean(); Loading Loading @@ -1323,8 +1327,7 @@ public class BiQuadParameters { properties.setProperty(prefix+"fsplit_adiff", this.fsplit_adiff+""); // double properties.setProperty(prefix+"fsplit_rdiff", this.fsplit_rdiff+""); // double properties.setProperty(prefix+"fsplit_kfg_min", this.fsplit_kfg_min+""); // double properties.setProperty(prefix+"mll_generate_scene_outlines",this.mll_generate_scene_outlines+""); properties.setProperty(prefix+"fsplit_dbg", this.fsplit_dbg+""); properties.setProperty(prefix+"mll_add_combo", this.mll_add_combo+""); properties.setProperty(prefix+"mll_save_accum", this.mll_save_accum+""); Loading Loading @@ -1584,6 +1587,7 @@ public class BiQuadParameters { if (properties.getProperty(prefix+"fsplit_adiff")!=null) this.fsplit_adiff=Double.parseDouble(properties.getProperty(prefix+"fsplit_adiff")); if (properties.getProperty(prefix+"fsplit_rdiff")!=null) this.fsplit_rdiff=Double.parseDouble(properties.getProperty(prefix+"fsplit_rdiff")); if (properties.getProperty(prefix+"fsplit_kfg_min")!=null) this.fsplit_kfg_min=Double.parseDouble(properties.getProperty(prefix+"fsplit_kfg_min")); if (properties.getProperty(prefix+"fsplit_dbg")!=null) this.fsplit_dbg=Boolean.parseBoolean(properties.getProperty(prefix+"fsplit_dbg")); if (properties.getProperty(prefix+"mll_generate_scene_outlines")!=null) this.mll_generate_scene_outlines=Boolean.parseBoolean(properties.getProperty(prefix+"mll_generate_scene_outlines")); Loading Loading @@ -1845,7 +1849,7 @@ public class BiQuadParameters { bqp.fsplit_adiff = this.fsplit_adiff; bqp.fsplit_rdiff = this.fsplit_rdiff; bqp.fsplit_kfg_min = this.fsplit_kfg_min; bqp.fsplit_dbg = this.fsplit_dbg; bqp.mll_generate_scene_outlines = this.mll_generate_scene_outlines; bqp.mll_add_combo = this.mll_add_combo; Loading src/main/java/com/elphel/imagej/tileprocessor/ImageDtt.java +4 −353 Original line number Diff line number Diff line Loading @@ -2241,6 +2241,10 @@ public class ImageDtt extends ImageDttCPU { !Double.isNaN(disp_str_lma[0][0]) && !Double.isNaN(disp_str_lma[1][0])) { int indx = sel_fg_bg[0]; // sometimes got inverted fg/bg in a pair if (disp_str_lma[indx][0] < disp_str_lma[1 - indx][0]) { indx = 1-indx; } // set FG to DISPARITY_INDEX_POLY/DISPARITY_INDEX_POLY+1 disparity_map[DISPARITY_INDEX_POLY ][nTile] = disp_str_lma[indx][0]; // disparity LMA disparity_map[DISPARITY_INDEX_POLY + 1][nTile] = disp_str_lma[indx][2]; // strength LMA Loading Loading @@ -2564,359 +2568,6 @@ public class ImageDtt extends ImageDttCPU { } public void clt_process_tl_correlations_GPU_DBG( // convert to pixel domain and process correlations already prepared in fcorr_td and/or fcorr_combo_td final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others // both arrays should have same non-null tiles final float [][][][] fcorr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs final float [][][][] fcorr_combo_td, // [4][tilesY][tilesX][4*64] TD of combo corrs: qud, cross, hor,vert // each of the top elements may be null to skip particular combo type final double [][][][] corr_tiles, // [tilesY][tilesX][pair][] ([(2*gpu_corr_rad+1)*(2*gpu_corr_rad+1)]) or null final double [][][][][] clt_corr_partial,// [tilesY][tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate // [tilesY][tilesX] should be set by caller final float [][][] fcorr_tiles, // [tile][index][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate // When clt_mismatch is non-zero, no far objects extraction will be attempted final double [][] clt_mismatch, // [12][tilesY * tilesX] // ***** transpose unapplied ***** ?. null - do not calculate // values in the "main" directions have disparity (*_CM) subtracted, in the perpendicular - as is final double [][] disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do not calculate // last 2 - contrast, avg/ "geometric average) final int corr_pairs_mask, // which pairs to use in LMA final int disparity_modes, // bit mask of disparity_map slices to calculate/return final double gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0 final int gpu_corr_rad, // = transform_size - 1 ? final double max_corr_radius, // 3.9; final int window_type, // GPU: will not be used final int debug_tileX, final int debug_tileY, final int threadsMax, // maximal number of threads to launch final int globalDebugLevel) { final int [] dbg_tiles = (globalDebugLevel > -1)? new int []{37721, 39022, 40975, 38042, 40963, 42253, 38694, 39343, 36443} : null; final float gpu_fcorr_scale = (float) gpu_corr_scale; if (this.gpuQuad == null) { System.out.println("clt_aberrations_quad_corr_GPU(): this.gpuQuad is null, bailing out"); return; } final boolean [][] saturation_imp = gpuQuad.quadCLT.saturation_imp; // boolean [][] saturation_imp, // (near) saturated pixels or null //gpuQuad final boolean debug_distort= globalDebugLevel > 0; ///false; // true; // final double [][] debug_offsets = new double[imgdtt_params.lma_dbg_offset.length][2]; final double [][] debug_offsets = new double[getNumSensors()][2]; for (int i = 0; i < imgdtt_params.lma_dbg_offset.length; i++) for (int j = 0; j < debug_offsets[i].length; j++) { debug_offsets[i][j] = imgdtt_params.lma_dbg_offset[i][j]*imgdtt_params.lma_dbg_scale; } //dbg_pair_mask final int quad = 4; // number of subcameras // final int numcol = isMonochrome()?1:3; final int width = gpuQuad.getImageWidth(); final int height = gpuQuad.getImageHeight(); final int tilesX=gpuQuad.getTilesX(); // width/transform_size; final int tilesY=gpuQuad.getTilesY(); // final int tilesY=height/transform_size; final Thread[] threads = newThreadArray(threadsMax); final AtomicInteger ai = new AtomicInteger(0); // final double [] col_weights= new double [numcol]; // colors are RBG final double [][] dbg_distort = debug_distort? (new double [4*quad][tilesX*tilesY]) : null; // not yet used with GPU /** final double [][] corr_wnd = Corr2dLMA.getCorrWnd( transform_size, imgdtt_params.lma_wnd); final double [] corr_wnd_inv_limited = (imgdtt_params.lma_min_wnd <= 1.0)? new double [corr_wnd.length * corr_wnd[0].length]: null; if (corr_wnd_inv_limited != null) { double inv_pwr = imgdtt_params.lma_wnd_pwr - (imgdtt_params.lma_wnd - 1.0); // compensate for lma_wnd for (int i = imgdtt_params.lma_hard_marg; i < (corr_wnd.length - imgdtt_params.lma_hard_marg); i++) { for (int j = imgdtt_params.lma_hard_marg; j < (corr_wnd.length - imgdtt_params.lma_hard_marg); j++) { corr_wnd_inv_limited[i * (corr_wnd.length) + j] = 1.0/Math.max(Math.pow(corr_wnd[i][j],inv_pwr), imgdtt_params.lma_min_wnd); } } } */ // keep for now for mono, find out what do they mean for macro mode final int corr_size = transform_size * 2 - 1; // reducing weight of on-axis correlation values to enhance detection of vertical/horizontal lines // multiply correlation results inside the horizontal center strip 2*enhortho_width - 1 wide by enhortho_scale final double [] enh_ortho_scale = new double [corr_size]; for (int i = 0; i < corr_size; i++){ if ((i < (transform_size - imgdtt_params.getEnhOrthoWidth(isAux()))) || (i > (transform_size - 2 + imgdtt_params.getEnhOrthoWidth(isAux())))) { enh_ortho_scale[i] = 1.0; } else { enh_ortho_scale[i] = imgdtt_params.getEnhOrthoScale(isAux()); } if (i == (transform_size-1)) enh_ortho_scale[i] = 0.0 ; // hardwired 0 in the center enh_ortho_scale[i] *= Math.sin(Math.PI*(i+1.0)/(2*transform_size)); } if (globalDebugLevel > 1){ System.out.println("getEnhOrthoWidth(isAux())="+ imgdtt_params.getEnhOrthoWidth(isAux())+" getEnhOrthoScale(isAux())="+ imgdtt_params.getEnhOrthoScale(isAux())); for (int i = 0; i < corr_size; i++){ System.out.println(" enh_ortho_scale["+i+"]="+ enh_ortho_scale[i]); } } // Create window to select center correlation strip using // ortho_height - full width of non-zero elements // ortho_eff_height - effective height (ration of the weighted column sum to the center value) int wcenter = transform_size - 1; final double [] ortho_weights = new double [corr_size]; // [15] for (int i = 0; i < corr_size; i++){ if ((i >= wcenter - imgdtt_params.ortho_height/2) && (i <= wcenter + imgdtt_params.ortho_height/2)) { double dx = 1.0*(i-wcenter)/(imgdtt_params.ortho_height/2 + 1); ortho_weights[i] = 0.5*(1.0+Math.cos(Math.PI*dx))/imgdtt_params.ortho_eff_height; } } if (globalDebugLevel > 1){ System.out.println("ortho_height="+ imgdtt_params.ortho_height+" ortho_eff_height="+ imgdtt_params.ortho_eff_height); for (int i = 0; i < corr_size; i++){ System.out.println("e. ortho_weights["+i+"]="+ ortho_weights[i]); } } if (globalDebugLevel > 1) { System.out.println("clt_aberrations_quad_corr(): width="+width+" height="+height+" transform_size="+transform_size+ " debug_tileX="+debug_tileX+" debug_tileY="+debug_tileY+" globalDebugLevel="+globalDebugLevel); } if (disparity_map != null){ for (int i = 0; i<disparity_map.length;i++) if ((disparity_modes & (1 << i)) != 0){ if ((i == OVEREXPOSED) && (saturation_imp == null)) { continue; } disparity_map[i] = new double [tilesY*tilesX]; } } if (clt_mismatch != null){ for (int i = 0; i<clt_mismatch.length;i++){ clt_mismatch[i] = new double [tilesY*tilesX]; // will use only "center of mass" centers } } /* DttRad2 dtt = new DttRad2(transform_size); dtt.set_window(window_type); final double [] lt_window = dtt.getWin2d(); // [256] - never used final double [] lt_window2 = new double [lt_window.length]; // squared - never used for (int i = 0; i < lt_window.length; i++) lt_window2[i] = lt_window[i] * lt_window[i]; */ /// final boolean use_main = geometryCorrection_main != null; /// final int all_pairs = imgdtt_params.dbg_pair_mask; //TODO: use tile tasks int [] corr_indices_ = null; float [][] fcorr2D_ = null; if (fcorr_td != null) { int [][] pairs_map = {{0,0},{1,1},{2,2},{3,3},{4,4},{5,5}}; corr_indices_ = gpuQuad.setCorrTilesTd( // .length = 295866 should set num_corr_tiles! fcorr_td, // final float [][][][] corr_tiles, // [tileY][tileX][pair][4*64] pairs_map); // int [][] pairs) // typically {{0,0},{1,1},{2,2},{3,3},{4,4},{5,5} [0] - 3rd index in corr_tiles, [1] - gpuQuad.execCorr2D_normalize( false, // boolean combo, // normalize combo correlations (false - per-pair ones) gpu_fat_zero, // double fat_zero); null, // float [] fcorr_weights, // null or one per correlation tile (num_corr_tiles) to divide fat zero2 gpu_corr_rad); // int corr_radius fcorr2D_ = gpuQuad.getCorr2D(gpu_corr_rad); // int corr_rad); } final int [] corr_indices = corr_indices_; final float [][] fcorr2D = fcorr2D_; // len = 49311 final int num_combo= (fcorr_combo_td != null)? fcorr_combo_td.length : 0; final int [][] corr_combo_indices = (fcorr_combo_td != null)? new int [num_combo][] : null; final float [][][] fcorr2D_combo = (fcorr_combo_td != null)? new float[num_combo][][] : null; if (num_combo > 0) { int [] ipairs = {0xf, 0x30, 0x3, 0xc}; // does not matter. using quad, cross, hor, vert for (int i = 0; i < num_combo; i++) { corr_combo_indices[i] = gpuQuad.setCorrTilesComboTd( fcorr_combo_td[i], // final float [][][] corr_tiles, // [tileY][tileX][4*64] ipairs[i]); // change to smth? int ipair) // just to set in the index low bits // normalize and convert to pixel domain gpuQuad.execCorr2D_normalize( true, // boolean combo, // normalize combo correlations (false - per-pair ones) gpu_fat_zero, // double fat_zero); null, // float [] fcorr_weights, // null or one per correlation tile (num_corr_tiles) to divide fat zero2 gpu_corr_rad); // int corr_radius fcorr2D_combo[i] = gpuQuad.getCorr2DCombo(gpu_corr_rad); } } final boolean fneed_macro = false; if (corr_indices.length > 0) { /* if (true) { // debugging only int [] wh = new int[2]; double [][] dbg_corr = GPUTileProcessor.getCorr2DView( tilesX, tilesY, corr_indices, fcorr2D, wh); ShowDoubleFloatArrays.showArrays( dbg_corr, wh[0], wh[1], true, "dbg-corr2D-fromTD", // name+"-CORR2D-D"+clt_parameters.disparity, GPUTileProcessor.getCorrTitles()); } */ final int corr_length = fcorr2D[0].length;// all correlation tiles have the same size // assuming that the correlation pairs sets are the same for each tile that has correlations // find this number int nt0 = (corr_indices[0] >> GPUTileProcessor.CORR_NTILE_SHIFT); int nc0 = 1; for (int i = 1; (i < corr_indices.length) && ((corr_indices[i] >> GPUTileProcessor.CORR_NTILE_SHIFT) == nt0) ; i++) { nc0++; } final int num_tile_corr = nc0; // normally 6 final int num_tiles = corr_indices.length / num_tile_corr; // FIXME: will not work with combining pairs !!! final int num_pairs = Correlation2d.getNumPairs(numSensors); // Runtime.getRuntime().gc(); // System.out.println("--- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")"); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { @Override public void run() { Correlation2d corr2d = new Correlation2d( numSensors, imgdtt_params, // ImageDttParameters imgdtt_params, transform_size, // int transform_size, 2.0, // double wndx_scale, // (wndy scale is always 1.0) isMonochrome(), // boolean monochrome, (globalDebugLevel > -1)); // boolean debug) corr2d.createOrtoNotch( imgdtt_params.getEnhOrthoWidth(isAux()), // double getEnhOrthoWidth(isAux()), imgdtt_params.getEnhOrthoScale(isAux()), //double getEnhOrthoScale(isAux()), (imgdtt_params.lma_debug_level > 1)); // boolean debug); for (int indx_tile = ai.getAndIncrement(); indx_tile < num_tiles; indx_tile = ai.getAndIncrement()) { // double [][] corrs = new double [num_pairs][corr_length]; // 225-long (15x15) // added quad and cross combos double [][] corrs = new double [num_pairs + num_combo][corr_length]; // 225-long (15x15) float [][] fcorrs = (fcorr_tiles == null) ? null : new float [num_pairs + num_combo][corr_length]; // 225-long (15x15) int indx_corr = indx_tile * num_tile_corr; int nt = (corr_indices[indx_corr] >> GPUTileProcessor.CORR_NTILE_SHIFT); int tileX = nt % tilesX; int tileY = nt / tilesX; int tIndex = tileY * tilesX + tileX; // Prepare the same (currently 10-layer) corrs as double [][], as in CPU version int pair_mask = 0; if (fcorr_td != null) { for (int indx_pair = 0; indx_pair < num_tile_corr; indx_pair++) { int pair = corr_indices[indx_corr] & GPUTileProcessor.CORR_PAIRS_MASK; // ((1 << CORR_NTILE_SHIFT) - 1); // np should assert pair < num_pairs : "invalid correllation pair"; pair_mask |= (1 << pair); for (int i = 0; i < corr_length; i++) { corrs[pair][i] = gpu_corr_scale * fcorr2D[indx_corr][i]; // from float to double } if (fcorrs != null) for (int i = 0; i < corr_length; i++) { fcorrs[pair][i] = gpu_fcorr_scale * fcorr2D[indx_corr][i]; } indx_corr++; } } // add 4 combo layers : quad, cross, hor, vert if (num_combo > 0) { for (int ncm = 0; ncm < num_combo; ncm++) if (corr_combo_indices[ncm]!=null){ nt = (corr_combo_indices[ncm][indx_tile] >> GPUTileProcessor.CORR_NTILE_SHIFT); // corr_quad_indices - different sequence int pair = num_pairs + ncm; // 6+ for (int i = 0; i < corr_length; i++) { corrs[pair][i] = gpu_corr_scale * fcorr2D_combo[ncm][indx_tile][i]; // from float to double } if (fcorrs != null) for (int i = 0; i < corr_length; i++) { fcorrs[pair][i] = gpu_fcorr_scale * fcorr2D_combo[ncm][indx_tile][i]; } } } if (corr_tiles != null) { corr_tiles[tileY][tileX] = corrs; } if (fcorr_tiles != null) { fcorr_tiles[tileY * tilesX + tileX] = fcorrs; // does not require corr_common_GPU() } if ((disparity_map != null) || (clt_corr_partial != null) || (clt_mismatch != null)) { // int used_pairs = pair_mask; // imgdtt_params.dbg_pair_mask; //TODO: use tile tasks int used_pairs = pair_mask & corr_pairs_mask; // imgdtt_params.dbg_pair_mask; // imgdtt_params.dbg_pair_mask; //TODO: use tile tasks int tile_lma_debug_level = ((tileX == debug_tileX) && (tileY == debug_tileY))? (imgdtt_params.lma_debug_level-1) : -2; boolean debugTile =(tileX == debug_tileX) && (tileY == debug_tileY) && (globalDebugLevel > -1); if (dbg_tiles != null) for (int ii : dbg_tiles){ if (ii == tIndex) { debugTile=true; System.out.println("Debugging tile "+tIndex+" ( "+tileX+" / "+tileY+" )"); break; } } corr_common_GPU( imgdtt_params, // final ImageDttParameters imgdtt_params, clt_corr_partial, // final double [][][][][] clt_corr_partial, used_pairs, // final int used_pairs, disparity_map, // final double [][] disparity_map, clt_mismatch, // final double [][] clt_mismatch, saturation_imp, // final boolean [][] saturation_imp, fneed_macro, // final boolean fneed_macro, corr2d, // final Correlation2d corr2d, corrs, // final double [][] corrs, tileX, // final int tileX, tileY, // final int tileY, max_corr_radius, // final double max_corr_radius, // 3.9; tile_lma_debug_level, // int tile_lma_debug_level, debugTile, // boolean debugTile, globalDebugLevel); // final int globalDebugLevel) } // double extra_disparity = 0.0; // used for textures: if allowed, shift images extra before trying to combine /* // Disabled for GPU if (corr_mode == 0) extra_disparity = disparity_map[DISPARITY_INDEX_INT][tIndex]; else if (corr_mode == 1) extra_disparity = disparity_map[DISPARITY_INDEX_CM][tIndex]; else if (corr_mode == 2) extra_disparity = disparity_map[DISPARITY_INDEX_POLY][tIndex]; else if (corr_mode == 3) extra_disparity = disparity_map[DISPARITY_INDEX_HOR][tIndex]; // not used in lwir else if (corr_mode == 4) extra_disparity = disparity_map[DISPARITY_INDEX_VERT][tIndex]; // not used in lwir if (Double.isNaN(extra_disparity)) extra_disparity = 0; // used in lwir */ if (Double.isNaN(disparity_map[DISPARITY_STRENGTH_INDEX][tIndex])) { System.out.println("BUG: 3. disparity_map[DISPARITY_STRENGTH_INDEX][tIndex] should not be NaN"); } // only debug is left // old (per-color correlation) // removed } // end of tile } }; } startAndJoin(threads); } else { // no correlation tiles to process } if ((dbg_distort != null) &&(globalDebugLevel >= 0)) { ShowDoubleFloatArrays.showArrays(dbg_distort, tilesX, tilesY, true, "disparity_distortions"); // , dbg_titles); } /* // final double [][] dbg_distort = debug_distort? (new double [4*quad][tilesX*tilesY]) : null; if ((dbg_distort != null) &&(globalDebugLevel >=0)) { ShowDoubleFloatArrays.showArrays(dbg_distort, tilesX, tilesY, true, "disparity_distortions"); // , dbg_titles); } if (dbg_ports_coords != null) { ShowDoubleFloatArrays.showArrays(dbg_ports_coords, tilesX, tilesY, true, "ports_coordinates", dbg_titles); } */ // return clt_data; } public void corr_common_GPU( final ImageDttParameters imgdtt_params, final double [][][][][] clt_corr_partial, Loading Loading
src/main/java/com/elphel/imagej/tileprocessor/BiQuadParameters.java +8 −4 Original line number Diff line number Diff line Loading @@ -260,6 +260,7 @@ public class BiQuadParameters { // FG/BG split for far tiles where dual max can only be detected with LMA as it is too small public boolean fsplit_en = true; // enable split of far tiles into FG/BG with LMA // fsplit_mode==2 now (04/17/2023) worse than fsplit_mode==1 public int fsplit_mode = 1; // 0: disable, 1:avg->fg+bg, 2: avg->fg+fg:fg:bg public double fsplit_str = 0.4; // minimal strength of the tile to split public int fsplit_neibs = 3; // minimal number of neighbors to consider split Loading @@ -270,6 +271,7 @@ public class BiQuadParameters { public double fsplit_adiff = 0.02; //4;// minimal tile (combo) absolute disparity difference from neighbors public double fsplit_rdiff = 0.02; // 1; // minimal tile (combo) relative disparity difference from neighbors public double fsplit_kfg_min = 0.05; // *** minimal fraction of kfg and (1.0-kfg) public boolean fsplit_dbg = false; public boolean mll_generate_scene_outlines = false; // Uses 2 GB - change format, add dimensions (separate color for ref) Loading Loading @@ -741,6 +743,8 @@ public class BiQuadParameters { "Maximal relative (to average) disparity difference from average of neighbors for FG/BG split."); gd.addNumericField("Minimal kFG fraction", this.fsplit_kfg_min, 3,6,"", "Minimal fraction of kfg and (1.0-kfg)."); gd.addCheckbox ("Debug far FG/BG split ", this.fsplit_dbg, "Generate and save scene outlines for scene series (need to change format, it is 2GB with uncompressed Tiff)"); gd.addMessage("Other"); gd.addCheckbox ("Generate scene outlines", this.mll_generate_scene_outlines, Loading Loading @@ -1059,7 +1063,7 @@ public class BiQuadParameters { this.fsplit_adiff = gd.getNextNumber(); this.fsplit_rdiff = gd.getNextNumber(); this.fsplit_kfg_min = gd.getNextNumber(); this.fsplit_dbg = gd.getNextBoolean(); this.mll_generate_scene_outlines= gd.getNextBoolean(); this.mll_add_combo= gd.getNextBoolean(); Loading Loading @@ -1323,8 +1327,7 @@ public class BiQuadParameters { properties.setProperty(prefix+"fsplit_adiff", this.fsplit_adiff+""); // double properties.setProperty(prefix+"fsplit_rdiff", this.fsplit_rdiff+""); // double properties.setProperty(prefix+"fsplit_kfg_min", this.fsplit_kfg_min+""); // double properties.setProperty(prefix+"mll_generate_scene_outlines",this.mll_generate_scene_outlines+""); properties.setProperty(prefix+"fsplit_dbg", this.fsplit_dbg+""); properties.setProperty(prefix+"mll_add_combo", this.mll_add_combo+""); properties.setProperty(prefix+"mll_save_accum", this.mll_save_accum+""); Loading Loading @@ -1584,6 +1587,7 @@ public class BiQuadParameters { if (properties.getProperty(prefix+"fsplit_adiff")!=null) this.fsplit_adiff=Double.parseDouble(properties.getProperty(prefix+"fsplit_adiff")); if (properties.getProperty(prefix+"fsplit_rdiff")!=null) this.fsplit_rdiff=Double.parseDouble(properties.getProperty(prefix+"fsplit_rdiff")); if (properties.getProperty(prefix+"fsplit_kfg_min")!=null) this.fsplit_kfg_min=Double.parseDouble(properties.getProperty(prefix+"fsplit_kfg_min")); if (properties.getProperty(prefix+"fsplit_dbg")!=null) this.fsplit_dbg=Boolean.parseBoolean(properties.getProperty(prefix+"fsplit_dbg")); if (properties.getProperty(prefix+"mll_generate_scene_outlines")!=null) this.mll_generate_scene_outlines=Boolean.parseBoolean(properties.getProperty(prefix+"mll_generate_scene_outlines")); Loading Loading @@ -1845,7 +1849,7 @@ public class BiQuadParameters { bqp.fsplit_adiff = this.fsplit_adiff; bqp.fsplit_rdiff = this.fsplit_rdiff; bqp.fsplit_kfg_min = this.fsplit_kfg_min; bqp.fsplit_dbg = this.fsplit_dbg; bqp.mll_generate_scene_outlines = this.mll_generate_scene_outlines; bqp.mll_add_combo = this.mll_add_combo; Loading
src/main/java/com/elphel/imagej/tileprocessor/ImageDtt.java +4 −353 Original line number Diff line number Diff line Loading @@ -2241,6 +2241,10 @@ public class ImageDtt extends ImageDttCPU { !Double.isNaN(disp_str_lma[0][0]) && !Double.isNaN(disp_str_lma[1][0])) { int indx = sel_fg_bg[0]; // sometimes got inverted fg/bg in a pair if (disp_str_lma[indx][0] < disp_str_lma[1 - indx][0]) { indx = 1-indx; } // set FG to DISPARITY_INDEX_POLY/DISPARITY_INDEX_POLY+1 disparity_map[DISPARITY_INDEX_POLY ][nTile] = disp_str_lma[indx][0]; // disparity LMA disparity_map[DISPARITY_INDEX_POLY + 1][nTile] = disp_str_lma[indx][2]; // strength LMA Loading Loading @@ -2564,359 +2568,6 @@ public class ImageDtt extends ImageDttCPU { } public void clt_process_tl_correlations_GPU_DBG( // convert to pixel domain and process correlations already prepared in fcorr_td and/or fcorr_combo_td final ImageDttParameters imgdtt_params, // Now just extra correlation parameters, later will include, most others // both arrays should have same non-null tiles final float [][][][] fcorr_td, // [tilesY][tilesX][pair][4*64] transform domain representation of 6 corr pairs final float [][][][] fcorr_combo_td, // [4][tilesY][tilesX][4*64] TD of combo corrs: qud, cross, hor,vert // each of the top elements may be null to skip particular combo type final double [][][][] corr_tiles, // [tilesY][tilesX][pair][] ([(2*gpu_corr_rad+1)*(2*gpu_corr_rad+1)]) or null final double [][][][][] clt_corr_partial,// [tilesY][tilesX][quad]color][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate // [tilesY][tilesX] should be set by caller final float [][][] fcorr_tiles, // [tile][index][(2*transform_size-1)*(2*transform_size-1)] // if null - will not calculate // When clt_mismatch is non-zero, no far objects extraction will be attempted final double [][] clt_mismatch, // [12][tilesY * tilesX] // ***** transpose unapplied ***** ?. null - do not calculate // values in the "main" directions have disparity (*_CM) subtracted, in the perpendicular - as is final double [][] disparity_map, // [8][tilesY][tilesX], only [6][] is needed on input or null - do not calculate // last 2 - contrast, avg/ "geometric average) final int corr_pairs_mask, // which pairs to use in LMA final int disparity_modes, // bit mask of disparity_map slices to calculate/return final double gpu_corr_scale, // 0.75; // reduce GPU-generated correlation values final double gpu_fat_zero, // clt_parameters.getGpuFatZero(is_mono);absolute == 30.0 final int gpu_corr_rad, // = transform_size - 1 ? final double max_corr_radius, // 3.9; final int window_type, // GPU: will not be used final int debug_tileX, final int debug_tileY, final int threadsMax, // maximal number of threads to launch final int globalDebugLevel) { final int [] dbg_tiles = (globalDebugLevel > -1)? new int []{37721, 39022, 40975, 38042, 40963, 42253, 38694, 39343, 36443} : null; final float gpu_fcorr_scale = (float) gpu_corr_scale; if (this.gpuQuad == null) { System.out.println("clt_aberrations_quad_corr_GPU(): this.gpuQuad is null, bailing out"); return; } final boolean [][] saturation_imp = gpuQuad.quadCLT.saturation_imp; // boolean [][] saturation_imp, // (near) saturated pixels or null //gpuQuad final boolean debug_distort= globalDebugLevel > 0; ///false; // true; // final double [][] debug_offsets = new double[imgdtt_params.lma_dbg_offset.length][2]; final double [][] debug_offsets = new double[getNumSensors()][2]; for (int i = 0; i < imgdtt_params.lma_dbg_offset.length; i++) for (int j = 0; j < debug_offsets[i].length; j++) { debug_offsets[i][j] = imgdtt_params.lma_dbg_offset[i][j]*imgdtt_params.lma_dbg_scale; } //dbg_pair_mask final int quad = 4; // number of subcameras // final int numcol = isMonochrome()?1:3; final int width = gpuQuad.getImageWidth(); final int height = gpuQuad.getImageHeight(); final int tilesX=gpuQuad.getTilesX(); // width/transform_size; final int tilesY=gpuQuad.getTilesY(); // final int tilesY=height/transform_size; final Thread[] threads = newThreadArray(threadsMax); final AtomicInteger ai = new AtomicInteger(0); // final double [] col_weights= new double [numcol]; // colors are RBG final double [][] dbg_distort = debug_distort? (new double [4*quad][tilesX*tilesY]) : null; // not yet used with GPU /** final double [][] corr_wnd = Corr2dLMA.getCorrWnd( transform_size, imgdtt_params.lma_wnd); final double [] corr_wnd_inv_limited = (imgdtt_params.lma_min_wnd <= 1.0)? new double [corr_wnd.length * corr_wnd[0].length]: null; if (corr_wnd_inv_limited != null) { double inv_pwr = imgdtt_params.lma_wnd_pwr - (imgdtt_params.lma_wnd - 1.0); // compensate for lma_wnd for (int i = imgdtt_params.lma_hard_marg; i < (corr_wnd.length - imgdtt_params.lma_hard_marg); i++) { for (int j = imgdtt_params.lma_hard_marg; j < (corr_wnd.length - imgdtt_params.lma_hard_marg); j++) { corr_wnd_inv_limited[i * (corr_wnd.length) + j] = 1.0/Math.max(Math.pow(corr_wnd[i][j],inv_pwr), imgdtt_params.lma_min_wnd); } } } */ // keep for now for mono, find out what do they mean for macro mode final int corr_size = transform_size * 2 - 1; // reducing weight of on-axis correlation values to enhance detection of vertical/horizontal lines // multiply correlation results inside the horizontal center strip 2*enhortho_width - 1 wide by enhortho_scale final double [] enh_ortho_scale = new double [corr_size]; for (int i = 0; i < corr_size; i++){ if ((i < (transform_size - imgdtt_params.getEnhOrthoWidth(isAux()))) || (i > (transform_size - 2 + imgdtt_params.getEnhOrthoWidth(isAux())))) { enh_ortho_scale[i] = 1.0; } else { enh_ortho_scale[i] = imgdtt_params.getEnhOrthoScale(isAux()); } if (i == (transform_size-1)) enh_ortho_scale[i] = 0.0 ; // hardwired 0 in the center enh_ortho_scale[i] *= Math.sin(Math.PI*(i+1.0)/(2*transform_size)); } if (globalDebugLevel > 1){ System.out.println("getEnhOrthoWidth(isAux())="+ imgdtt_params.getEnhOrthoWidth(isAux())+" getEnhOrthoScale(isAux())="+ imgdtt_params.getEnhOrthoScale(isAux())); for (int i = 0; i < corr_size; i++){ System.out.println(" enh_ortho_scale["+i+"]="+ enh_ortho_scale[i]); } } // Create window to select center correlation strip using // ortho_height - full width of non-zero elements // ortho_eff_height - effective height (ration of the weighted column sum to the center value) int wcenter = transform_size - 1; final double [] ortho_weights = new double [corr_size]; // [15] for (int i = 0; i < corr_size; i++){ if ((i >= wcenter - imgdtt_params.ortho_height/2) && (i <= wcenter + imgdtt_params.ortho_height/2)) { double dx = 1.0*(i-wcenter)/(imgdtt_params.ortho_height/2 + 1); ortho_weights[i] = 0.5*(1.0+Math.cos(Math.PI*dx))/imgdtt_params.ortho_eff_height; } } if (globalDebugLevel > 1){ System.out.println("ortho_height="+ imgdtt_params.ortho_height+" ortho_eff_height="+ imgdtt_params.ortho_eff_height); for (int i = 0; i < corr_size; i++){ System.out.println("e. ortho_weights["+i+"]="+ ortho_weights[i]); } } if (globalDebugLevel > 1) { System.out.println("clt_aberrations_quad_corr(): width="+width+" height="+height+" transform_size="+transform_size+ " debug_tileX="+debug_tileX+" debug_tileY="+debug_tileY+" globalDebugLevel="+globalDebugLevel); } if (disparity_map != null){ for (int i = 0; i<disparity_map.length;i++) if ((disparity_modes & (1 << i)) != 0){ if ((i == OVEREXPOSED) && (saturation_imp == null)) { continue; } disparity_map[i] = new double [tilesY*tilesX]; } } if (clt_mismatch != null){ for (int i = 0; i<clt_mismatch.length;i++){ clt_mismatch[i] = new double [tilesY*tilesX]; // will use only "center of mass" centers } } /* DttRad2 dtt = new DttRad2(transform_size); dtt.set_window(window_type); final double [] lt_window = dtt.getWin2d(); // [256] - never used final double [] lt_window2 = new double [lt_window.length]; // squared - never used for (int i = 0; i < lt_window.length; i++) lt_window2[i] = lt_window[i] * lt_window[i]; */ /// final boolean use_main = geometryCorrection_main != null; /// final int all_pairs = imgdtt_params.dbg_pair_mask; //TODO: use tile tasks int [] corr_indices_ = null; float [][] fcorr2D_ = null; if (fcorr_td != null) { int [][] pairs_map = {{0,0},{1,1},{2,2},{3,3},{4,4},{5,5}}; corr_indices_ = gpuQuad.setCorrTilesTd( // .length = 295866 should set num_corr_tiles! fcorr_td, // final float [][][][] corr_tiles, // [tileY][tileX][pair][4*64] pairs_map); // int [][] pairs) // typically {{0,0},{1,1},{2,2},{3,3},{4,4},{5,5} [0] - 3rd index in corr_tiles, [1] - gpuQuad.execCorr2D_normalize( false, // boolean combo, // normalize combo correlations (false - per-pair ones) gpu_fat_zero, // double fat_zero); null, // float [] fcorr_weights, // null or one per correlation tile (num_corr_tiles) to divide fat zero2 gpu_corr_rad); // int corr_radius fcorr2D_ = gpuQuad.getCorr2D(gpu_corr_rad); // int corr_rad); } final int [] corr_indices = corr_indices_; final float [][] fcorr2D = fcorr2D_; // len = 49311 final int num_combo= (fcorr_combo_td != null)? fcorr_combo_td.length : 0; final int [][] corr_combo_indices = (fcorr_combo_td != null)? new int [num_combo][] : null; final float [][][] fcorr2D_combo = (fcorr_combo_td != null)? new float[num_combo][][] : null; if (num_combo > 0) { int [] ipairs = {0xf, 0x30, 0x3, 0xc}; // does not matter. using quad, cross, hor, vert for (int i = 0; i < num_combo; i++) { corr_combo_indices[i] = gpuQuad.setCorrTilesComboTd( fcorr_combo_td[i], // final float [][][] corr_tiles, // [tileY][tileX][4*64] ipairs[i]); // change to smth? int ipair) // just to set in the index low bits // normalize and convert to pixel domain gpuQuad.execCorr2D_normalize( true, // boolean combo, // normalize combo correlations (false - per-pair ones) gpu_fat_zero, // double fat_zero); null, // float [] fcorr_weights, // null or one per correlation tile (num_corr_tiles) to divide fat zero2 gpu_corr_rad); // int corr_radius fcorr2D_combo[i] = gpuQuad.getCorr2DCombo(gpu_corr_rad); } } final boolean fneed_macro = false; if (corr_indices.length > 0) { /* if (true) { // debugging only int [] wh = new int[2]; double [][] dbg_corr = GPUTileProcessor.getCorr2DView( tilesX, tilesY, corr_indices, fcorr2D, wh); ShowDoubleFloatArrays.showArrays( dbg_corr, wh[0], wh[1], true, "dbg-corr2D-fromTD", // name+"-CORR2D-D"+clt_parameters.disparity, GPUTileProcessor.getCorrTitles()); } */ final int corr_length = fcorr2D[0].length;// all correlation tiles have the same size // assuming that the correlation pairs sets are the same for each tile that has correlations // find this number int nt0 = (corr_indices[0] >> GPUTileProcessor.CORR_NTILE_SHIFT); int nc0 = 1; for (int i = 1; (i < corr_indices.length) && ((corr_indices[i] >> GPUTileProcessor.CORR_NTILE_SHIFT) == nt0) ; i++) { nc0++; } final int num_tile_corr = nc0; // normally 6 final int num_tiles = corr_indices.length / num_tile_corr; // FIXME: will not work with combining pairs !!! final int num_pairs = Correlation2d.getNumPairs(numSensors); // Runtime.getRuntime().gc(); // System.out.println("--- Free memory="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")"); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { @Override public void run() { Correlation2d corr2d = new Correlation2d( numSensors, imgdtt_params, // ImageDttParameters imgdtt_params, transform_size, // int transform_size, 2.0, // double wndx_scale, // (wndy scale is always 1.0) isMonochrome(), // boolean monochrome, (globalDebugLevel > -1)); // boolean debug) corr2d.createOrtoNotch( imgdtt_params.getEnhOrthoWidth(isAux()), // double getEnhOrthoWidth(isAux()), imgdtt_params.getEnhOrthoScale(isAux()), //double getEnhOrthoScale(isAux()), (imgdtt_params.lma_debug_level > 1)); // boolean debug); for (int indx_tile = ai.getAndIncrement(); indx_tile < num_tiles; indx_tile = ai.getAndIncrement()) { // double [][] corrs = new double [num_pairs][corr_length]; // 225-long (15x15) // added quad and cross combos double [][] corrs = new double [num_pairs + num_combo][corr_length]; // 225-long (15x15) float [][] fcorrs = (fcorr_tiles == null) ? null : new float [num_pairs + num_combo][corr_length]; // 225-long (15x15) int indx_corr = indx_tile * num_tile_corr; int nt = (corr_indices[indx_corr] >> GPUTileProcessor.CORR_NTILE_SHIFT); int tileX = nt % tilesX; int tileY = nt / tilesX; int tIndex = tileY * tilesX + tileX; // Prepare the same (currently 10-layer) corrs as double [][], as in CPU version int pair_mask = 0; if (fcorr_td != null) { for (int indx_pair = 0; indx_pair < num_tile_corr; indx_pair++) { int pair = corr_indices[indx_corr] & GPUTileProcessor.CORR_PAIRS_MASK; // ((1 << CORR_NTILE_SHIFT) - 1); // np should assert pair < num_pairs : "invalid correllation pair"; pair_mask |= (1 << pair); for (int i = 0; i < corr_length; i++) { corrs[pair][i] = gpu_corr_scale * fcorr2D[indx_corr][i]; // from float to double } if (fcorrs != null) for (int i = 0; i < corr_length; i++) { fcorrs[pair][i] = gpu_fcorr_scale * fcorr2D[indx_corr][i]; } indx_corr++; } } // add 4 combo layers : quad, cross, hor, vert if (num_combo > 0) { for (int ncm = 0; ncm < num_combo; ncm++) if (corr_combo_indices[ncm]!=null){ nt = (corr_combo_indices[ncm][indx_tile] >> GPUTileProcessor.CORR_NTILE_SHIFT); // corr_quad_indices - different sequence int pair = num_pairs + ncm; // 6+ for (int i = 0; i < corr_length; i++) { corrs[pair][i] = gpu_corr_scale * fcorr2D_combo[ncm][indx_tile][i]; // from float to double } if (fcorrs != null) for (int i = 0; i < corr_length; i++) { fcorrs[pair][i] = gpu_fcorr_scale * fcorr2D_combo[ncm][indx_tile][i]; } } } if (corr_tiles != null) { corr_tiles[tileY][tileX] = corrs; } if (fcorr_tiles != null) { fcorr_tiles[tileY * tilesX + tileX] = fcorrs; // does not require corr_common_GPU() } if ((disparity_map != null) || (clt_corr_partial != null) || (clt_mismatch != null)) { // int used_pairs = pair_mask; // imgdtt_params.dbg_pair_mask; //TODO: use tile tasks int used_pairs = pair_mask & corr_pairs_mask; // imgdtt_params.dbg_pair_mask; // imgdtt_params.dbg_pair_mask; //TODO: use tile tasks int tile_lma_debug_level = ((tileX == debug_tileX) && (tileY == debug_tileY))? (imgdtt_params.lma_debug_level-1) : -2; boolean debugTile =(tileX == debug_tileX) && (tileY == debug_tileY) && (globalDebugLevel > -1); if (dbg_tiles != null) for (int ii : dbg_tiles){ if (ii == tIndex) { debugTile=true; System.out.println("Debugging tile "+tIndex+" ( "+tileX+" / "+tileY+" )"); break; } } corr_common_GPU( imgdtt_params, // final ImageDttParameters imgdtt_params, clt_corr_partial, // final double [][][][][] clt_corr_partial, used_pairs, // final int used_pairs, disparity_map, // final double [][] disparity_map, clt_mismatch, // final double [][] clt_mismatch, saturation_imp, // final boolean [][] saturation_imp, fneed_macro, // final boolean fneed_macro, corr2d, // final Correlation2d corr2d, corrs, // final double [][] corrs, tileX, // final int tileX, tileY, // final int tileY, max_corr_radius, // final double max_corr_radius, // 3.9; tile_lma_debug_level, // int tile_lma_debug_level, debugTile, // boolean debugTile, globalDebugLevel); // final int globalDebugLevel) } // double extra_disparity = 0.0; // used for textures: if allowed, shift images extra before trying to combine /* // Disabled for GPU if (corr_mode == 0) extra_disparity = disparity_map[DISPARITY_INDEX_INT][tIndex]; else if (corr_mode == 1) extra_disparity = disparity_map[DISPARITY_INDEX_CM][tIndex]; else if (corr_mode == 2) extra_disparity = disparity_map[DISPARITY_INDEX_POLY][tIndex]; else if (corr_mode == 3) extra_disparity = disparity_map[DISPARITY_INDEX_HOR][tIndex]; // not used in lwir else if (corr_mode == 4) extra_disparity = disparity_map[DISPARITY_INDEX_VERT][tIndex]; // not used in lwir if (Double.isNaN(extra_disparity)) extra_disparity = 0; // used in lwir */ if (Double.isNaN(disparity_map[DISPARITY_STRENGTH_INDEX][tIndex])) { System.out.println("BUG: 3. disparity_map[DISPARITY_STRENGTH_INDEX][tIndex] should not be NaN"); } // only debug is left // old (per-color correlation) // removed } // end of tile } }; } startAndJoin(threads); } else { // no correlation tiles to process } if ((dbg_distort != null) &&(globalDebugLevel >= 0)) { ShowDoubleFloatArrays.showArrays(dbg_distort, tilesX, tilesY, true, "disparity_distortions"); // , dbg_titles); } /* // final double [][] dbg_distort = debug_distort? (new double [4*quad][tilesX*tilesY]) : null; if ((dbg_distort != null) &&(globalDebugLevel >=0)) { ShowDoubleFloatArrays.showArrays(dbg_distort, tilesX, tilesY, true, "disparity_distortions"); // , dbg_titles); } if (dbg_ports_coords != null) { ShowDoubleFloatArrays.showArrays(dbg_ports_coords, tilesX, tilesY, true, "ports_coordinates", dbg_titles); } */ // return clt_data; } public void corr_common_GPU( final ImageDttParameters imgdtt_params, final double [][][][][] clt_corr_partial, Loading