Loading src/main/java/com/elphel/imagej/tileprocessor/IntersceneMatchParameters.java +98 −3 Original line number Diff line number Diff line Loading @@ -165,7 +165,7 @@ public class IntersceneMatchParameters { public int weak_min_neibs = 5; public double strong_strength= 0.5; public double weak_strength= 0.2; // none is below //------------ // Some "AGC" to adjust how much to discard Loading Loading @@ -267,6 +267,24 @@ public class IntersceneMatchParameters { public double min_strength = 0.08; public int lowest_sky_row = 50;// appears that low - invalid, remove completely // equalization of the inter-scene correlations public boolean eq_en = true;// equalize "important" FG tiles for better camera XYZ fitting public int eq_stride_hor = 8; // half of a equalization supertile width public int eq_stride_vert = 8; // half of a equalization supertile height // Supertile qualification public double eq_min_stile_weight = 0.2; // minimal total weight of the tiles in a supertile (lower will not be modified) public int eq_min_stile_number = 10; // minimal number of defined tiles in a supertile public double eq_min_stile_fraction = 0.02;// minimal total tile strength compared to the average one // Individual tiles qualification public double eq_min_disparity = 5; // minimal disparity of tiles to consider (applies after filtering / boosting) public double eq_max_disparity = 1000; // maximal disparity of tiles to consider (applies after filtering / boosting) // Boost amount public double eq_weight_add = 0.03; // calculate from min-strengths public double eq_weight_scale = 20.0; // maximal boost ratio public double eq_level = 0.9; // equalization level (0.0 - leave as is, 1.0 - boost to have the same supertile strength as average) public boolean renderRef() {return renderRef (debug_level);} public boolean renderScene() {return renderScene (debug_level);} public boolean show2dCorrelations() {return show2dCorrelations (debug_level);} Loading Loading @@ -780,6 +798,35 @@ public class IntersceneMatchParameters { "Input strength has some with zero values resulting in zero FOM. Make them at least this."); gd.addNumericField("Lowest sky row", this.lowest_sky_row, 0,3,"", "Last defense - if the detected sky area reaches near-bottom of the page - it is invalid, remove it (but keep in debug images)"); gd.addTab("Interscene Equalization","Equalization of the interscene correlation confidence to improve camera X,Y,Z matching"); gd.addCheckbox ("Enable equalization", this.eq_en, "Enable boosting of the weak but important interscene correlation tiles strength by equalizing average strength of the \"supertiles\""); gd.addMessage ("Equalization supertiles dimensions"); gd.addNumericField("Supertile horizontal stride", this.eq_stride_hor, 0,3,"tiles", "Half of a equalization supertile width - supertiles have a 50% overlap in each direction."); gd.addNumericField("Supertile vertical stride", this.eq_stride_hor, 0,3,"tiles", "Half of a equalization supertile height - supertiles have a 50% overlap in each direction."); gd.addMessage ("Supertile qualification (not qualified will keep the original strength value)"); gd.addNumericField("Minimal supertile total weight", this.eq_min_stile_weight, 5,7,"", "Minimal total weight of the tiles in a supertile (lower will not be modified)."); gd.addNumericField("Minimal number of defined tiles", this.eq_min_stile_number, 0,3,"tiles", "Minimal number of defined tiles in a supertile."); gd.addNumericField("Minimal weight fraction of average", this.eq_min_stile_fraction, 5,7,"", "Minimal total supertile strength RELATIVE to the average one."); gd.addMessage ("Individual tiles qualification (applied after calculating the amount of boost)."); gd.addNumericField("Minimal equalized tile disparity", this.eq_min_disparity, 5,7,"pix", "Allows to disqualify infinity and far tiles (do not contribute to camera X,Y,Z) freom boosting."); gd.addNumericField("Maximal equalized tile disparity", this.eq_max_disparity, 5,7,"pix", "Unlikely to have meaning, introduced for symmetry. Can be set to a large number."); gd.addMessage ("Boost amount. Each defined tile will be increased by approximately previous subtracted offset and then scaled"); gd.addNumericField("Add to strength before scaling", this.eq_weight_add, 5,7,"", "Add to strength, then scale."); gd.addNumericField("Maximal boost ratio", this.eq_weight_scale, 5,7,"", "Strength scale. If the new supertile strength exceed the target value, each tile will be scaled down to match."); gd.addNumericField("Equalization level", this.eq_level, 5,7,"", "Target supertile strength will be set to: 0 - original strength (no modification), 1.0 - average supertile strength."); } public void dialogAnswers(GenericJTabbedDialog gd) { Loading Loading @@ -1057,6 +1104,19 @@ public class IntersceneMatchParameters { this.min_strength = gd.getNextNumber(); this.lowest_sky_row = (int) gd.getNextNumber(); // equalization of the inter-scene correlations this.eq_en = gd.getNextBoolean(); this.eq_stride_hor = (int) gd.getNextNumber(); this.eq_stride_vert = (int) gd.getNextNumber(); this.eq_min_stile_weight = gd.getNextNumber(); this.eq_min_stile_number =(int) gd.getNextNumber(); this.eq_min_stile_fraction = gd.getNextNumber(); this.eq_min_disparity = gd.getNextNumber(); this.eq_max_disparity = gd.getNextNumber(); this.eq_weight_add = gd.getNextNumber(); this.eq_weight_scale = gd.getNextNumber(); this.eq_level = gd.getNextNumber(); if (this.weight_zero_neibs > 1.0) this.weight_zero_neibs = 1.0; Loading Loading @@ -1284,7 +1344,17 @@ public class IntersceneMatchParameters { properties.setProperty(prefix+"min_strength", this.min_strength+""); // double properties.setProperty(prefix+"lowest_sky_row", this.lowest_sky_row+""); // int properties.setProperty(prefix+"eq_en", this.eq_en+""); // boolean properties.setProperty(prefix+"eq_stride_hor", this.eq_stride_hor+""); // int properties.setProperty(prefix+"eq_stride_vert", this.eq_stride_vert+""); // int properties.setProperty(prefix+"eq_min_stile_weight", this.eq_min_stile_weight+""); // double properties.setProperty(prefix+"eq_min_stile_number", this.eq_min_stile_number+""); // int properties.setProperty(prefix+"eq_min_stile_fraction",this.eq_min_stile_fraction+"");// double properties.setProperty(prefix+"eq_min_disparity", this.eq_min_disparity+""); // double properties.setProperty(prefix+"eq_max_disparity", this.eq_max_disparity+""); // double properties.setProperty(prefix+"eq_weight_add", this.eq_weight_add+""); // double properties.setProperty(prefix+"eq_weight_scale", this.eq_weight_scale+""); // double properties.setProperty(prefix+"eq_level", this.eq_level+""); // double } public void getProperties(String prefix,Properties properties){ Loading Loading @@ -1535,6 +1605,18 @@ public class IntersceneMatchParameters { if (properties.getProperty(prefix+"sky_expand_extra")!=null) this.sky_expand_extra=Integer.parseInt(properties.getProperty(prefix+"sky_expand_extra")); if (properties.getProperty(prefix+"min_strength")!=null) this.min_strength=Double.parseDouble(properties.getProperty(prefix+"min_strength")); if (properties.getProperty(prefix+"lowest_sky_row")!=null) this.lowest_sky_row=Integer.parseInt(properties.getProperty(prefix+"lowest_sky_row")); if (properties.getProperty(prefix+"eq_en")!=null) this.eq_en=Boolean.parseBoolean(properties.getProperty(prefix+"eq_en")); if (properties.getProperty(prefix+"eq_stride_hor")!=null) this.eq_stride_hor=Integer.parseInt(properties.getProperty(prefix+"eq_stride_hor")); if (properties.getProperty(prefix+"eq_stride_vert")!=null) this.eq_stride_vert=Integer.parseInt(properties.getProperty(prefix+"eq_stride_vert")); if (properties.getProperty(prefix+"eq_min_stile_weight")!=null) this.eq_min_stile_weight=Double.parseDouble(properties.getProperty(prefix+"eq_min_stile_weight")); if (properties.getProperty(prefix+"eq_min_stile_number")!=null) this.eq_min_stile_number=Integer.parseInt(properties.getProperty(prefix+"eq_min_stile_number")); if (properties.getProperty(prefix+"eq_min_stile_fraction")!=null)this.eq_min_stile_fraction=Double.parseDouble(properties.getProperty(prefix+"eq_min_stile_fraction")); if (properties.getProperty(prefix+"eq_min_disparity")!=null) this.eq_min_disparity=Double.parseDouble(properties.getProperty(prefix+"eq_min_disparity")); if (properties.getProperty(prefix+"eq_max_disparity")!=null) this.eq_max_disparity=Double.parseDouble(properties.getProperty(prefix+"eq_max_disparity")); if (properties.getProperty(prefix+"eq_weight_add")!=null) this.eq_weight_add=Double.parseDouble(properties.getProperty(prefix+"eq_weight_add")); if (properties.getProperty(prefix+"eq_weight_scale")!=null) this.eq_weight_scale=Double.parseDouble(properties.getProperty(prefix+"eq_weight_scale")); if (properties.getProperty(prefix+"eq_level")!=null) this.eq_level=Double.parseDouble(properties.getProperty(prefix+"eq_level")); } @Override Loading Loading @@ -1744,6 +1826,19 @@ public class IntersceneMatchParameters { imp.sky_expand_extra = this.sky_expand_extra; imp.min_strength = this.min_strength; imp.lowest_sky_row = this.lowest_sky_row; imp.eq_en = this.eq_en; imp.eq_stride_hor = this.eq_stride_hor; imp.eq_stride_vert = this.eq_stride_vert; imp.eq_min_stile_weight = this.eq_min_stile_weight; imp.eq_min_stile_number = this.eq_min_stile_number; imp.eq_min_stile_fraction = this.eq_min_stile_fraction; imp.eq_min_disparity = this.eq_min_disparity; imp.eq_max_disparity = this.eq_max_disparity; imp.eq_weight_add = this.eq_weight_add; imp.eq_weight_scale = this.eq_weight_scale; imp.eq_level = this.eq_level; return imp; } public static long getLongColor(Color color) { Loading src/main/java/com/elphel/imagej/tileprocessor/OpticalFlow.java +141 −53 Original line number Diff line number Diff line Loading @@ -12145,6 +12145,22 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad double fpn_radius = clt_parameters.imp.fpn_radius; boolean fpn_ignore_border = clt_parameters.imp.fpn_ignore_border; // only if fpn_mask != null - ignore tile if maximum touches fpn_mask boolean eq_debug = false; boolean eq_en = near_important && clt_parameters.imp.eq_en; // true;// equalize "important" FG tiles for better camera XYZ fitting int eq_stride_hor = clt_parameters.imp.eq_stride_hor; // 8; int eq_stride_vert = clt_parameters.imp.eq_stride_vert; // 8; double eq_min_stile_weight = clt_parameters.imp.eq_min_stile_weight; // 0.2; // 1.0; int eq_min_stile_number = clt_parameters.imp.eq_min_stile_number; // 10; double eq_min_stile_fraction =clt_parameters.imp.eq_min_stile_fraction; // 0.02; // 0.05; double eq_min_disparity = clt_parameters.imp.eq_min_disparity; // 5; double eq_max_disparity = clt_parameters.imp.eq_max_disparity; // 100; double eq_weight_add = clt_parameters.imp.eq_weight_add; // 0.05; double eq_weight_scale = clt_parameters.imp.eq_weight_scale; // 10; double eq_level = clt_parameters.imp.eq_level; // 0.8; // equalize to (log) fraction of average/this strength if (scene_is_ref_test) { scene_xyz = ZERO3.clone(); scene_atr = ZERO3.clone(); Loading Loading @@ -12356,6 +12372,71 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad System.out.println("clt_process_tl_interscene() returned null"); return null; } if (eq_en) { // double eq_weight_add = (min_str * clt_parameters.imp.pd_weight + min_str_sum * clt_parameters.imp.td_weight) / // (clt_parameters.imp.pd_weight + clt_parameters.imp.td_weight); double [] strength_backup = null; if (eq_debug) { // **** Set manually in debugger **** strength_backup = new double [coord_motion[1].length]; for (int i = 0; i < strength_backup.length; i++) if (coord_motion[1][i] != null) { strength_backup[i] = coord_motion[1][i][2]; }else { strength_backup[i] = Double.NaN; } } do { // restore if (strength_backup != null) { for (int i = 0; i < strength_backup.length; i++) if (coord_motion[1][i] != null) { coord_motion[1][i][2] = strength_backup[i]; } } equalizeMotionVectorsWeights( coord_motion, // final double [][][] coord_motion, tilesX, // final int tilesX, eq_stride_hor, // final int stride_hor, eq_stride_vert, // final int stride_vert, eq_min_stile_weight, // final double min_stile_weight, eq_min_stile_number, // final int min_stile_number, eq_min_stile_fraction, // final double min_stile_fraction, eq_min_disparity, // final double min_disparity, eq_max_disparity, // final double max_disparity, eq_weight_add, // final double weight_add, eq_weight_scale, // final double weight_scale) eq_level); // equalize to (log) fraction of average/this strength if (eq_debug) { String [] mvTitles = {"dx", "dy","conf", "conf0", "pX", "pY","Disp","defined"}; // ,"blurX","blurY", "blur"}; double [][] dbg_img = new double [mvTitles.length][tilesX*tilesY]; for (int l = 0; l < dbg_img.length; l++) { Arrays.fill(dbg_img[l], Double.NaN); } for (int nTile = 0; nTile < coord_motion[0].length; nTile++) { if (coord_motion[0][nTile] != null) { for (int i = 0; i <3; i++) { dbg_img[4+i][nTile] = coord_motion[0][nTile][i]; } } dbg_img[3] = strength_backup; if (coord_motion[1][nTile] != null) { for (int i = 0; i <3; i++) { dbg_img[0+i][nTile] = coord_motion[1][nTile][i]; } } dbg_img[7][nTile] = ((coord_motion[0][nTile] != null)?1:0)+((coord_motion[0][nTile] != null)?2:0); } (new ShowDoubleFloatArrays()).showArrays( // out of boundary 15 dbg_img, tilesX, tilesY, true, scene.getImageName()+"-"+ref_scene.getImageName()+"-coord_motion-eq", mvTitles); } } while (eq_debug); } if (mov_en) { String debug_image_name = mov_debug_images ? (scene.getImageName()+"-"+ref_scene.getImageName()+"-movements"): null; boolean [] move_mask = getMovementMask( Loading Loading @@ -12513,6 +12594,8 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad * @param max_disparity maximal disparity of tiles to consider (after filtering) * @param weight_add add to each tile after scaling (if total weight < average) * @param weight_scale scale each tile (if total weight < average) * @param eq_level equalize (log scale) to this ratio between average and this * strength (0.0 - leave as is, equalize weak to average strength * If total new weight of a supertile exceeds average - scale each tile to match. If * lower - keep as is. Only after this step remove tiles (replace with original weight) * that are discarded by the disparity filter. Multiply result by the the window and Loading @@ -12529,7 +12612,8 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad final double min_disparity, final double max_disparity, final double weight_add, final double weight_scale) final double weight_scale, final double eq_level) // equalize to (log) fraction of average/this strength { final int tiles = coord_motion[0].length; final int tilesY = tiles/tilesX; Loading @@ -12539,8 +12623,8 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad double [] wvert = new double [stride_vert]; for (int i = 0; i < stride_hor; i++) whor[i] = 0.5 *(1.0 - Math.cos(Math.PI*(i+0.5)/stride_hor)); for (int i = 0; i < stride_vert; i++) wvert[i] = 0.5 *(1.0 - Math.cos(Math.PI*(i+0.5)/stride_vert)); final int stilesX = (tilesX - 1)/stride_hor; // 9 final int stilesY = (tilesY - 1)/stride_vert; // 7 final int stilesX = (tilesX - 1)/stride_hor + 2; // 10 // 9 final int stilesY = (tilesY - 1)/stride_vert + 2; // 8 // 7 final int stiles = stilesX * stilesY; int indx = 0; final double[] wind = new double[stile_height*stile_width]; Loading Loading @@ -12568,11 +12652,11 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad stile_weight[sTile] = 0.0; int num_tiles = 0; // for partial stiles for (int iy = 0; iy < stile_height;iy++) { int tileY = sTileY * stride_vert + iy; if (tileY >= tilesY) continue; int tileY = (sTileY - 1) * stride_vert + iy; if ((tileY < 0) || (tileY >= tilesY)) continue; for (int ix = 0; ix < stile_width; ix++) { int tileX = sTileX * stride_hor + ix; if (tileX >= tilesX) continue; int tileX = (sTileX - 1) * stride_hor + ix; if ((tileX < 0) || (tileX >= tilesX)) continue; num_tiles++; // for partial stiles int tile = tileX + tilesX*tileY; if ((coord_motion[1][tile] != null) && !Double.isNaN(coord_motion[0][tile][2])) { Loading @@ -12589,16 +12673,6 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad }; } ImageDtt.startAndJoin(threads); /* double avg_tile_str = 0.0; int num_defined = 0; for (int tile = 0; tile < coord_motion[0].length; tile++) { if ((coord_motion[1][tile] != null) && !Double.isNaN(coord_motion[0][tile][2])) { num_defined++; avg_tile_str +=coord_motion[1][tile][2]; } } */ double sum_stile_str = 0.0; int num_stiles_defined = 0; for (int sTile = 0; sTile < stiles; sTile++) { Loading Loading @@ -12646,15 +12720,18 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad if (stile_weight[sTile] >= avg_stile_str) { // already strong enough keep_old = true; } double target_str=Math.exp( eq_level*Math.log(avg_stile_str) + (1.0-eq_level)*stile_weight[sTile]); Arrays.fill(mod_weights,0); double sum_weights = 0.0; int num_tiles = 0; // for partial stiles for (int iy = 0; iy < stile_height;iy++) { int tileY = stileY * stride_vert + iy; if (tileY >= tilesY) continue; int tileY = (stileY - 1) * stride_vert + iy; if ((tileY < 0) || (tileY >= tilesY)) continue; for (int ix = 0; ix < stile_width; ix++) { int tileX = stileX * stride_hor + ix; if (tileX >= tilesX) continue; int tileX = (stileX - 1) * stride_hor + ix; if ((tileX < 0) || (tileX >= tilesX)) continue; int tile = tileX + tilesX*tileY; num_tiles ++; if ((coord_motion[1][tile] != null) && !Double.isNaN(coord_motion[0][tile][2])) { Loading @@ -12668,18 +12745,18 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad } sum_weights *= 1.0 * stile_height * stile_height / num_tiles ; // increase for partial tiles if (!keep_old) { if (sum_weights > avg_stile_str) { // scale back double s = avg_stile_str/sum_weights; if (sum_weights > target_str) { // scale back double s = target_str/sum_weights; for (int ltile = 0; ltile < mod_weights.length; ltile++) { mod_weights[ltile] *= s; } } for (int iy = 0; iy < stile_height;iy++) { int tileY = stileY * stride_vert + iy; if (tileY >= tilesY) continue; int tileY = (stileY - 1) * stride_vert + iy; if ((tileY < 0) || (tileY >= tilesY)) continue; for (int ix = 0; ix < stile_width; ix++) { int tileX = stileX * stride_hor + ix; if (tileX >= tilesX) continue; int tileX = (stileX - 1) * stride_hor + ix; if ((tileX < 0) || (tileX >= tilesX)) continue; int tile = tileX + tilesX*tileY; int ltile = ix + iy * stile_width; // remove out of range disparity Loading @@ -12695,11 +12772,11 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad } // multiply by window and accumulate for (int iy = 0; iy < stile_height;iy++) { int tileY = stileY * stride_vert + iy; if (tileY >= tilesY) continue; int tileY = (stileY - 1) * stride_vert + iy; if ((tileY < 0) || (tileY >= tilesY)) continue; for (int ix = 0; ix < stile_width; ix++) { int tileX = stileX * stride_hor + ix; if (tileX >= tilesX) continue; int tileX = (stileX - 1) * stride_hor + ix; if ((tileX < 0) || (tileX >= tilesX)) continue; int tile = tileX + tilesX*tileY; int ltile = ix + iy * stile_width; // wind Loading Loading @@ -13377,9 +13454,10 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad double[] camera_atr0 = camera_atr.clone(); double [][][] coord_motion = null; boolean show_corr_fpn = debug_level > -1; // -3; *********** Change to debug FPN correleation *** boolean run_equalize = false; // boolean run_equalize = true; // boolean debug_equalize = false; int nlma = 00; int nlma = 0; for (; nlma < clt_parameters.imp.max_cycles; nlma ++) { boolean near_important = nlma > 0; Loading @@ -13403,31 +13481,37 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad System.out.println("adjustPairsLMAInterscene() returned null"); return null; } /* int eq_stride_hor = 8; int eq_stride_vert = 8; double eq_min_stile_weight = 1.0; double eq_min_stile_weight = 0.2; // 1.0; int eq_min_stile_number = 10; double eq_min_stile_fraction = 0.05; double eq_min_stile_fraction = 0.02; // 0.05; double eq_min_disparity = 5; double eq_max_disparity = 100; double eq_weight_add = 0.1; double eq_weight_scale = 10; double eq_level = 0.8; // equalize to (log) fraction of average/this strength if (run_equalize && near_important) { TileProcessor tp = reference_QuadClt.getTileProcessor(); int tilesX = tp.getTilesX(); int tilesY = tp.getTilesY(); // backup coord_motion[1][][2] // strength double [] strength_backup = new double [coord_motion[1].length]; double [] strength_backup = null; if (debug_equalize) { strength_backup = new double [coord_motion[1].length]; for (int i = 0; i < strength_backup.length; i++) if (coord_motion[1][i] != null) { strength_backup[i] = coord_motion[1][i][2]; } } while (run_equalize) { // restore if (strength_backup != null) { for (int i = 0; i < strength_backup.length; i++) if (coord_motion[1][i] != null) { coord_motion[1][i][2] = strength_backup[i]; } } equalizeMotionVectorsWeights( coord_motion, // final double [][][] coord_motion, tilesX, // final int tilesX, Loading @@ -13439,7 +13523,12 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad eq_min_disparity, // final double min_disparity, eq_max_disparity, // final double max_disparity, eq_weight_add, // final double weight_add, eq_weight_scale); // final double weight_scale) eq_weight_scale, // final double weight_scale) eq_level); // equalize to (log) fraction of average/this strength if (!debug_equalize) { break; } String [] mvTitles = {"dx", "dy","conf", "conf0", "pX", "pY","Disp","defined"}; // ,"blurX","blurY", "blur"}; double [][] dbg_img = new double [mvTitles.length][tilesX*tilesY]; for (int l = 0; l < dbg_img.length; l++) { Loading Loading @@ -13469,8 +13558,7 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad } } */ intersceneLma.prepareLMA( camera_xyz0, // final double [] scene_xyz0, // camera center in world coordinates (or null to use instance) src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java +0 −7 Original line number Diff line number Diff line Loading @@ -461,13 +461,6 @@ public class QuadCLTCPU { return null; } double [] temp_scales = null; /* double cold_scale = 0.2; // <=1.0. 1.0 - disables temperature dependence double cold_frac = 0.005; // this and lower will scale fom by cold_scale double hot_frac = 0.9; // this and above will scale fom by 1.0 double min_strength = 0.08; int seed_rows = 5; // sky should appear in this top rows */ boolean failure = false; if (avg_val != null) { int num_bins = 1000; Loading Loading
src/main/java/com/elphel/imagej/tileprocessor/IntersceneMatchParameters.java +98 −3 Original line number Diff line number Diff line Loading @@ -165,7 +165,7 @@ public class IntersceneMatchParameters { public int weak_min_neibs = 5; public double strong_strength= 0.5; public double weak_strength= 0.2; // none is below //------------ // Some "AGC" to adjust how much to discard Loading Loading @@ -267,6 +267,24 @@ public class IntersceneMatchParameters { public double min_strength = 0.08; public int lowest_sky_row = 50;// appears that low - invalid, remove completely // equalization of the inter-scene correlations public boolean eq_en = true;// equalize "important" FG tiles for better camera XYZ fitting public int eq_stride_hor = 8; // half of a equalization supertile width public int eq_stride_vert = 8; // half of a equalization supertile height // Supertile qualification public double eq_min_stile_weight = 0.2; // minimal total weight of the tiles in a supertile (lower will not be modified) public int eq_min_stile_number = 10; // minimal number of defined tiles in a supertile public double eq_min_stile_fraction = 0.02;// minimal total tile strength compared to the average one // Individual tiles qualification public double eq_min_disparity = 5; // minimal disparity of tiles to consider (applies after filtering / boosting) public double eq_max_disparity = 1000; // maximal disparity of tiles to consider (applies after filtering / boosting) // Boost amount public double eq_weight_add = 0.03; // calculate from min-strengths public double eq_weight_scale = 20.0; // maximal boost ratio public double eq_level = 0.9; // equalization level (0.0 - leave as is, 1.0 - boost to have the same supertile strength as average) public boolean renderRef() {return renderRef (debug_level);} public boolean renderScene() {return renderScene (debug_level);} public boolean show2dCorrelations() {return show2dCorrelations (debug_level);} Loading Loading @@ -780,6 +798,35 @@ public class IntersceneMatchParameters { "Input strength has some with zero values resulting in zero FOM. Make them at least this."); gd.addNumericField("Lowest sky row", this.lowest_sky_row, 0,3,"", "Last defense - if the detected sky area reaches near-bottom of the page - it is invalid, remove it (but keep in debug images)"); gd.addTab("Interscene Equalization","Equalization of the interscene correlation confidence to improve camera X,Y,Z matching"); gd.addCheckbox ("Enable equalization", this.eq_en, "Enable boosting of the weak but important interscene correlation tiles strength by equalizing average strength of the \"supertiles\""); gd.addMessage ("Equalization supertiles dimensions"); gd.addNumericField("Supertile horizontal stride", this.eq_stride_hor, 0,3,"tiles", "Half of a equalization supertile width - supertiles have a 50% overlap in each direction."); gd.addNumericField("Supertile vertical stride", this.eq_stride_hor, 0,3,"tiles", "Half of a equalization supertile height - supertiles have a 50% overlap in each direction."); gd.addMessage ("Supertile qualification (not qualified will keep the original strength value)"); gd.addNumericField("Minimal supertile total weight", this.eq_min_stile_weight, 5,7,"", "Minimal total weight of the tiles in a supertile (lower will not be modified)."); gd.addNumericField("Minimal number of defined tiles", this.eq_min_stile_number, 0,3,"tiles", "Minimal number of defined tiles in a supertile."); gd.addNumericField("Minimal weight fraction of average", this.eq_min_stile_fraction, 5,7,"", "Minimal total supertile strength RELATIVE to the average one."); gd.addMessage ("Individual tiles qualification (applied after calculating the amount of boost)."); gd.addNumericField("Minimal equalized tile disparity", this.eq_min_disparity, 5,7,"pix", "Allows to disqualify infinity and far tiles (do not contribute to camera X,Y,Z) freom boosting."); gd.addNumericField("Maximal equalized tile disparity", this.eq_max_disparity, 5,7,"pix", "Unlikely to have meaning, introduced for symmetry. Can be set to a large number."); gd.addMessage ("Boost amount. Each defined tile will be increased by approximately previous subtracted offset and then scaled"); gd.addNumericField("Add to strength before scaling", this.eq_weight_add, 5,7,"", "Add to strength, then scale."); gd.addNumericField("Maximal boost ratio", this.eq_weight_scale, 5,7,"", "Strength scale. If the new supertile strength exceed the target value, each tile will be scaled down to match."); gd.addNumericField("Equalization level", this.eq_level, 5,7,"", "Target supertile strength will be set to: 0 - original strength (no modification), 1.0 - average supertile strength."); } public void dialogAnswers(GenericJTabbedDialog gd) { Loading Loading @@ -1057,6 +1104,19 @@ public class IntersceneMatchParameters { this.min_strength = gd.getNextNumber(); this.lowest_sky_row = (int) gd.getNextNumber(); // equalization of the inter-scene correlations this.eq_en = gd.getNextBoolean(); this.eq_stride_hor = (int) gd.getNextNumber(); this.eq_stride_vert = (int) gd.getNextNumber(); this.eq_min_stile_weight = gd.getNextNumber(); this.eq_min_stile_number =(int) gd.getNextNumber(); this.eq_min_stile_fraction = gd.getNextNumber(); this.eq_min_disparity = gd.getNextNumber(); this.eq_max_disparity = gd.getNextNumber(); this.eq_weight_add = gd.getNextNumber(); this.eq_weight_scale = gd.getNextNumber(); this.eq_level = gd.getNextNumber(); if (this.weight_zero_neibs > 1.0) this.weight_zero_neibs = 1.0; Loading Loading @@ -1284,7 +1344,17 @@ public class IntersceneMatchParameters { properties.setProperty(prefix+"min_strength", this.min_strength+""); // double properties.setProperty(prefix+"lowest_sky_row", this.lowest_sky_row+""); // int properties.setProperty(prefix+"eq_en", this.eq_en+""); // boolean properties.setProperty(prefix+"eq_stride_hor", this.eq_stride_hor+""); // int properties.setProperty(prefix+"eq_stride_vert", this.eq_stride_vert+""); // int properties.setProperty(prefix+"eq_min_stile_weight", this.eq_min_stile_weight+""); // double properties.setProperty(prefix+"eq_min_stile_number", this.eq_min_stile_number+""); // int properties.setProperty(prefix+"eq_min_stile_fraction",this.eq_min_stile_fraction+"");// double properties.setProperty(prefix+"eq_min_disparity", this.eq_min_disparity+""); // double properties.setProperty(prefix+"eq_max_disparity", this.eq_max_disparity+""); // double properties.setProperty(prefix+"eq_weight_add", this.eq_weight_add+""); // double properties.setProperty(prefix+"eq_weight_scale", this.eq_weight_scale+""); // double properties.setProperty(prefix+"eq_level", this.eq_level+""); // double } public void getProperties(String prefix,Properties properties){ Loading Loading @@ -1535,6 +1605,18 @@ public class IntersceneMatchParameters { if (properties.getProperty(prefix+"sky_expand_extra")!=null) this.sky_expand_extra=Integer.parseInt(properties.getProperty(prefix+"sky_expand_extra")); if (properties.getProperty(prefix+"min_strength")!=null) this.min_strength=Double.parseDouble(properties.getProperty(prefix+"min_strength")); if (properties.getProperty(prefix+"lowest_sky_row")!=null) this.lowest_sky_row=Integer.parseInt(properties.getProperty(prefix+"lowest_sky_row")); if (properties.getProperty(prefix+"eq_en")!=null) this.eq_en=Boolean.parseBoolean(properties.getProperty(prefix+"eq_en")); if (properties.getProperty(prefix+"eq_stride_hor")!=null) this.eq_stride_hor=Integer.parseInt(properties.getProperty(prefix+"eq_stride_hor")); if (properties.getProperty(prefix+"eq_stride_vert")!=null) this.eq_stride_vert=Integer.parseInt(properties.getProperty(prefix+"eq_stride_vert")); if (properties.getProperty(prefix+"eq_min_stile_weight")!=null) this.eq_min_stile_weight=Double.parseDouble(properties.getProperty(prefix+"eq_min_stile_weight")); if (properties.getProperty(prefix+"eq_min_stile_number")!=null) this.eq_min_stile_number=Integer.parseInt(properties.getProperty(prefix+"eq_min_stile_number")); if (properties.getProperty(prefix+"eq_min_stile_fraction")!=null)this.eq_min_stile_fraction=Double.parseDouble(properties.getProperty(prefix+"eq_min_stile_fraction")); if (properties.getProperty(prefix+"eq_min_disparity")!=null) this.eq_min_disparity=Double.parseDouble(properties.getProperty(prefix+"eq_min_disparity")); if (properties.getProperty(prefix+"eq_max_disparity")!=null) this.eq_max_disparity=Double.parseDouble(properties.getProperty(prefix+"eq_max_disparity")); if (properties.getProperty(prefix+"eq_weight_add")!=null) this.eq_weight_add=Double.parseDouble(properties.getProperty(prefix+"eq_weight_add")); if (properties.getProperty(prefix+"eq_weight_scale")!=null) this.eq_weight_scale=Double.parseDouble(properties.getProperty(prefix+"eq_weight_scale")); if (properties.getProperty(prefix+"eq_level")!=null) this.eq_level=Double.parseDouble(properties.getProperty(prefix+"eq_level")); } @Override Loading Loading @@ -1744,6 +1826,19 @@ public class IntersceneMatchParameters { imp.sky_expand_extra = this.sky_expand_extra; imp.min_strength = this.min_strength; imp.lowest_sky_row = this.lowest_sky_row; imp.eq_en = this.eq_en; imp.eq_stride_hor = this.eq_stride_hor; imp.eq_stride_vert = this.eq_stride_vert; imp.eq_min_stile_weight = this.eq_min_stile_weight; imp.eq_min_stile_number = this.eq_min_stile_number; imp.eq_min_stile_fraction = this.eq_min_stile_fraction; imp.eq_min_disparity = this.eq_min_disparity; imp.eq_max_disparity = this.eq_max_disparity; imp.eq_weight_add = this.eq_weight_add; imp.eq_weight_scale = this.eq_weight_scale; imp.eq_level = this.eq_level; return imp; } public static long getLongColor(Color color) { Loading
src/main/java/com/elphel/imagej/tileprocessor/OpticalFlow.java +141 −53 Original line number Diff line number Diff line Loading @@ -12145,6 +12145,22 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad double fpn_radius = clt_parameters.imp.fpn_radius; boolean fpn_ignore_border = clt_parameters.imp.fpn_ignore_border; // only if fpn_mask != null - ignore tile if maximum touches fpn_mask boolean eq_debug = false; boolean eq_en = near_important && clt_parameters.imp.eq_en; // true;// equalize "important" FG tiles for better camera XYZ fitting int eq_stride_hor = clt_parameters.imp.eq_stride_hor; // 8; int eq_stride_vert = clt_parameters.imp.eq_stride_vert; // 8; double eq_min_stile_weight = clt_parameters.imp.eq_min_stile_weight; // 0.2; // 1.0; int eq_min_stile_number = clt_parameters.imp.eq_min_stile_number; // 10; double eq_min_stile_fraction =clt_parameters.imp.eq_min_stile_fraction; // 0.02; // 0.05; double eq_min_disparity = clt_parameters.imp.eq_min_disparity; // 5; double eq_max_disparity = clt_parameters.imp.eq_max_disparity; // 100; double eq_weight_add = clt_parameters.imp.eq_weight_add; // 0.05; double eq_weight_scale = clt_parameters.imp.eq_weight_scale; // 10; double eq_level = clt_parameters.imp.eq_level; // 0.8; // equalize to (log) fraction of average/this strength if (scene_is_ref_test) { scene_xyz = ZERO3.clone(); scene_atr = ZERO3.clone(); Loading Loading @@ -12356,6 +12372,71 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad System.out.println("clt_process_tl_interscene() returned null"); return null; } if (eq_en) { // double eq_weight_add = (min_str * clt_parameters.imp.pd_weight + min_str_sum * clt_parameters.imp.td_weight) / // (clt_parameters.imp.pd_weight + clt_parameters.imp.td_weight); double [] strength_backup = null; if (eq_debug) { // **** Set manually in debugger **** strength_backup = new double [coord_motion[1].length]; for (int i = 0; i < strength_backup.length; i++) if (coord_motion[1][i] != null) { strength_backup[i] = coord_motion[1][i][2]; }else { strength_backup[i] = Double.NaN; } } do { // restore if (strength_backup != null) { for (int i = 0; i < strength_backup.length; i++) if (coord_motion[1][i] != null) { coord_motion[1][i][2] = strength_backup[i]; } } equalizeMotionVectorsWeights( coord_motion, // final double [][][] coord_motion, tilesX, // final int tilesX, eq_stride_hor, // final int stride_hor, eq_stride_vert, // final int stride_vert, eq_min_stile_weight, // final double min_stile_weight, eq_min_stile_number, // final int min_stile_number, eq_min_stile_fraction, // final double min_stile_fraction, eq_min_disparity, // final double min_disparity, eq_max_disparity, // final double max_disparity, eq_weight_add, // final double weight_add, eq_weight_scale, // final double weight_scale) eq_level); // equalize to (log) fraction of average/this strength if (eq_debug) { String [] mvTitles = {"dx", "dy","conf", "conf0", "pX", "pY","Disp","defined"}; // ,"blurX","blurY", "blur"}; double [][] dbg_img = new double [mvTitles.length][tilesX*tilesY]; for (int l = 0; l < dbg_img.length; l++) { Arrays.fill(dbg_img[l], Double.NaN); } for (int nTile = 0; nTile < coord_motion[0].length; nTile++) { if (coord_motion[0][nTile] != null) { for (int i = 0; i <3; i++) { dbg_img[4+i][nTile] = coord_motion[0][nTile][i]; } } dbg_img[3] = strength_backup; if (coord_motion[1][nTile] != null) { for (int i = 0; i <3; i++) { dbg_img[0+i][nTile] = coord_motion[1][nTile][i]; } } dbg_img[7][nTile] = ((coord_motion[0][nTile] != null)?1:0)+((coord_motion[0][nTile] != null)?2:0); } (new ShowDoubleFloatArrays()).showArrays( // out of boundary 15 dbg_img, tilesX, tilesY, true, scene.getImageName()+"-"+ref_scene.getImageName()+"-coord_motion-eq", mvTitles); } } while (eq_debug); } if (mov_en) { String debug_image_name = mov_debug_images ? (scene.getImageName()+"-"+ref_scene.getImageName()+"-movements"): null; boolean [] move_mask = getMovementMask( Loading Loading @@ -12513,6 +12594,8 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad * @param max_disparity maximal disparity of tiles to consider (after filtering) * @param weight_add add to each tile after scaling (if total weight < average) * @param weight_scale scale each tile (if total weight < average) * @param eq_level equalize (log scale) to this ratio between average and this * strength (0.0 - leave as is, equalize weak to average strength * If total new weight of a supertile exceeds average - scale each tile to match. If * lower - keep as is. Only after this step remove tiles (replace with original weight) * that are discarded by the disparity filter. Multiply result by the the window and Loading @@ -12529,7 +12612,8 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad final double min_disparity, final double max_disparity, final double weight_add, final double weight_scale) final double weight_scale, final double eq_level) // equalize to (log) fraction of average/this strength { final int tiles = coord_motion[0].length; final int tilesY = tiles/tilesX; Loading @@ -12539,8 +12623,8 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad double [] wvert = new double [stride_vert]; for (int i = 0; i < stride_hor; i++) whor[i] = 0.5 *(1.0 - Math.cos(Math.PI*(i+0.5)/stride_hor)); for (int i = 0; i < stride_vert; i++) wvert[i] = 0.5 *(1.0 - Math.cos(Math.PI*(i+0.5)/stride_vert)); final int stilesX = (tilesX - 1)/stride_hor; // 9 final int stilesY = (tilesY - 1)/stride_vert; // 7 final int stilesX = (tilesX - 1)/stride_hor + 2; // 10 // 9 final int stilesY = (tilesY - 1)/stride_vert + 2; // 8 // 7 final int stiles = stilesX * stilesY; int indx = 0; final double[] wind = new double[stile_height*stile_width]; Loading Loading @@ -12568,11 +12652,11 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad stile_weight[sTile] = 0.0; int num_tiles = 0; // for partial stiles for (int iy = 0; iy < stile_height;iy++) { int tileY = sTileY * stride_vert + iy; if (tileY >= tilesY) continue; int tileY = (sTileY - 1) * stride_vert + iy; if ((tileY < 0) || (tileY >= tilesY)) continue; for (int ix = 0; ix < stile_width; ix++) { int tileX = sTileX * stride_hor + ix; if (tileX >= tilesX) continue; int tileX = (sTileX - 1) * stride_hor + ix; if ((tileX < 0) || (tileX >= tilesX)) continue; num_tiles++; // for partial stiles int tile = tileX + tilesX*tileY; if ((coord_motion[1][tile] != null) && !Double.isNaN(coord_motion[0][tile][2])) { Loading @@ -12589,16 +12673,6 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad }; } ImageDtt.startAndJoin(threads); /* double avg_tile_str = 0.0; int num_defined = 0; for (int tile = 0; tile < coord_motion[0].length; tile++) { if ((coord_motion[1][tile] != null) && !Double.isNaN(coord_motion[0][tile][2])) { num_defined++; avg_tile_str +=coord_motion[1][tile][2]; } } */ double sum_stile_str = 0.0; int num_stiles_defined = 0; for (int sTile = 0; sTile < stiles; sTile++) { Loading Loading @@ -12646,15 +12720,18 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad if (stile_weight[sTile] >= avg_stile_str) { // already strong enough keep_old = true; } double target_str=Math.exp( eq_level*Math.log(avg_stile_str) + (1.0-eq_level)*stile_weight[sTile]); Arrays.fill(mod_weights,0); double sum_weights = 0.0; int num_tiles = 0; // for partial stiles for (int iy = 0; iy < stile_height;iy++) { int tileY = stileY * stride_vert + iy; if (tileY >= tilesY) continue; int tileY = (stileY - 1) * stride_vert + iy; if ((tileY < 0) || (tileY >= tilesY)) continue; for (int ix = 0; ix < stile_width; ix++) { int tileX = stileX * stride_hor + ix; if (tileX >= tilesX) continue; int tileX = (stileX - 1) * stride_hor + ix; if ((tileX < 0) || (tileX >= tilesX)) continue; int tile = tileX + tilesX*tileY; num_tiles ++; if ((coord_motion[1][tile] != null) && !Double.isNaN(coord_motion[0][tile][2])) { Loading @@ -12668,18 +12745,18 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad } sum_weights *= 1.0 * stile_height * stile_height / num_tiles ; // increase for partial tiles if (!keep_old) { if (sum_weights > avg_stile_str) { // scale back double s = avg_stile_str/sum_weights; if (sum_weights > target_str) { // scale back double s = target_str/sum_weights; for (int ltile = 0; ltile < mod_weights.length; ltile++) { mod_weights[ltile] *= s; } } for (int iy = 0; iy < stile_height;iy++) { int tileY = stileY * stride_vert + iy; if (tileY >= tilesY) continue; int tileY = (stileY - 1) * stride_vert + iy; if ((tileY < 0) || (tileY >= tilesY)) continue; for (int ix = 0; ix < stile_width; ix++) { int tileX = stileX * stride_hor + ix; if (tileX >= tilesX) continue; int tileX = (stileX - 1) * stride_hor + ix; if ((tileX < 0) || (tileX >= tilesX)) continue; int tile = tileX + tilesX*tileY; int ltile = ix + iy * stile_width; // remove out of range disparity Loading @@ -12695,11 +12772,11 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad } // multiply by window and accumulate for (int iy = 0; iy < stile_height;iy++) { int tileY = stileY * stride_vert + iy; if (tileY >= tilesY) continue; int tileY = (stileY - 1) * stride_vert + iy; if ((tileY < 0) || (tileY >= tilesY)) continue; for (int ix = 0; ix < stile_width; ix++) { int tileX = stileX * stride_hor + ix; if (tileX >= tilesX) continue; int tileX = (stileX - 1) * stride_hor + ix; if ((tileX < 0) || (tileX >= tilesX)) continue; int tile = tileX + tilesX*tileY; int ltile = ix + iy * stile_width; // wind Loading Loading @@ -13377,9 +13454,10 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad double[] camera_atr0 = camera_atr.clone(); double [][][] coord_motion = null; boolean show_corr_fpn = debug_level > -1; // -3; *********** Change to debug FPN correleation *** boolean run_equalize = false; // boolean run_equalize = true; // boolean debug_equalize = false; int nlma = 00; int nlma = 0; for (; nlma < clt_parameters.imp.max_cycles; nlma ++) { boolean near_important = nlma > 0; Loading @@ -13403,31 +13481,37 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad System.out.println("adjustPairsLMAInterscene() returned null"); return null; } /* int eq_stride_hor = 8; int eq_stride_vert = 8; double eq_min_stile_weight = 1.0; double eq_min_stile_weight = 0.2; // 1.0; int eq_min_stile_number = 10; double eq_min_stile_fraction = 0.05; double eq_min_stile_fraction = 0.02; // 0.05; double eq_min_disparity = 5; double eq_max_disparity = 100; double eq_weight_add = 0.1; double eq_weight_scale = 10; double eq_level = 0.8; // equalize to (log) fraction of average/this strength if (run_equalize && near_important) { TileProcessor tp = reference_QuadClt.getTileProcessor(); int tilesX = tp.getTilesX(); int tilesY = tp.getTilesY(); // backup coord_motion[1][][2] // strength double [] strength_backup = new double [coord_motion[1].length]; double [] strength_backup = null; if (debug_equalize) { strength_backup = new double [coord_motion[1].length]; for (int i = 0; i < strength_backup.length; i++) if (coord_motion[1][i] != null) { strength_backup[i] = coord_motion[1][i][2]; } } while (run_equalize) { // restore if (strength_backup != null) { for (int i = 0; i < strength_backup.length; i++) if (coord_motion[1][i] != null) { coord_motion[1][i][2] = strength_backup[i]; } } equalizeMotionVectorsWeights( coord_motion, // final double [][][] coord_motion, tilesX, // final int tilesX, Loading @@ -13439,7 +13523,12 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad eq_min_disparity, // final double min_disparity, eq_max_disparity, // final double max_disparity, eq_weight_add, // final double weight_add, eq_weight_scale); // final double weight_scale) eq_weight_scale, // final double weight_scale) eq_level); // equalize to (log) fraction of average/this strength if (!debug_equalize) { break; } String [] mvTitles = {"dx", "dy","conf", "conf0", "pX", "pY","Disp","defined"}; // ,"blurX","blurY", "blur"}; double [][] dbg_img = new double [mvTitles.length][tilesX*tilesY]; for (int l = 0; l < dbg_img.length; l++) { Loading Loading @@ -13469,8 +13558,7 @@ public double[][] correlateIntersceneDebug( // only uses GPU and quad } } */ intersceneLma.prepareLMA( camera_xyz0, // final double [] scene_xyz0, // camera center in world coordinates (or null to use instance)
src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java +0 −7 Original line number Diff line number Diff line Loading @@ -461,13 +461,6 @@ public class QuadCLTCPU { return null; } double [] temp_scales = null; /* double cold_scale = 0.2; // <=1.0. 1.0 - disables temperature dependence double cold_frac = 0.005; // this and lower will scale fom by cold_scale double hot_frac = 0.9; // this and above will scale fom by 1.0 double min_strength = 0.08; int seed_rows = 5; // sky should appear in this top rows */ boolean failure = false; if (avg_val != null) { int num_bins = 1000; Loading