Commit 51fc9a60 authored by Andrey Filippov's avatar Andrey Filippov

Trimming for low disparity difference (far objects) by tone

(temperature).
parent df789de8
......@@ -398,6 +398,12 @@ public class CLTParameters {
public double tex_disp_rdiffj = 0.08; // maximal relative disparity difference for the "jumps".
public double tex_fg_bg = 0.1; // Minimal FG/BG disparity difference (NaN bg if difference from FG < this)
public double tex_disp_over_sky = 0.1; // change extended BS (by tex_max_neib_lev) far tile to BS
public double tex_str_over_sky = 0.7; // change extended BS (by tex_max_neib_lev) weak tile to BS
public boolean tex_require_lma = true; // require strong tile to have LMA
public double tex_distort = 0.8; // Maximal texture distortion to accumulate multiple scenes (0 - any)
public double tex_mb = 1.0; // Reduce texture weight if motion blur exceeds this (as square of MB length)
......@@ -406,6 +412,7 @@ public class CLTParameters {
public int tex_max_neib_lev = 2; // 1 - single tiles layer around, 2 - two layers
public boolean tex_split_textures = false; // (debugLevel > 1000); // false;
public int tex_subdiv_tiles = 4; // subdivide tiles to smaller triangles
public int tex_sky_extra = 2; // additionally grow sky area (in layers) without marking as sky
public int tex_sky_below = 10; // extend sky these tile rows below lowest
// gd.addMessage ("Triangular mesh");
......@@ -511,6 +518,15 @@ public class CLTParameters {
public double lre_weight_neib = 3.0; // 2.0; // 1.0; // weight of same neighbors - add to cost multiplied by num_neib-4
public double lre_weight_bg = 0.9; // 0.8; // 1.0; // 15.0/16; // 1.0; // weight of BG cost relative to the FG one
public double lre_best_dir_frac = 0.6; // for BG - use this fraction of all sensors in the best direction
//"Trimming by temperature (tone)
public boolean lre_use_min_max = true; // when trimming by tone, use min/max of the FG/BG instead of weighted averages
public double lre_temp_radius = 11.5; // How far to look around for FG trimming by temperature
public int lre_temp_min = 2; // Minimal number of each of FG/BG while trimming by temperature
public double lre_temp_weight = 20.0; // Multiply -1.0..+1.0 range of the current pixel between average BG(-1) and FG(+1)
public double lre_min_use_occl = 1.5; // Minimal FG/BG difference to use trimming by occlusions. For lower use only temperature/tone
public double lre_temp_disparity = 3.0; // FG-BG disparity where weight of cost by obscuring equals weight of cost by temp
public double lre_cost_min = 1.0; // minimal absolute value of the total cost to make changes
public int lre_max_trim_iterations = 10;
// for fillOcclusionsNaN:
......@@ -521,6 +537,7 @@ public class CLTParameters {
public boolean lre_show_textures_combo = false; //true;
public boolean lre_show_textures_tiles = false; //true;
public boolean lre_show_sky_textures = false; //true;
public int lre_show_slice_bitmap = -1; // bitmap of slices for which to show images (lre_show_update_alpha_slice, lre_show_textures_slice)
public double pt_super_trust = 1.6; // If strength exceeds ex_strength * super_trust, do not apply ex_nstrength and plate_ds
public boolean pt_keep_raw_fg = true; // Do not replace raw tiles by the plates, if raw is closer (like poles)
......@@ -1504,6 +1521,10 @@ public class CLTParameters {
properties.setProperty(prefix+"tex_disp_rdiffj", this.tex_disp_rdiffj+""); // double
properties.setProperty(prefix+"tex_fg_bg", this.tex_fg_bg+""); // double
properties.setProperty(prefix+"tex_disp_over_sky", this.tex_disp_over_sky+""); // double
properties.setProperty(prefix+"tex_str_over_sky", this.tex_str_over_sky+""); // double
properties.setProperty(prefix+"tex_require_lma", this.tex_require_lma+""); // boolean
properties.setProperty(prefix+"tex_distort", this.tex_distort+""); // double
properties.setProperty(prefix+"tex_mb", this.tex_mb+""); // double
......@@ -1512,6 +1533,7 @@ public class CLTParameters {
properties.setProperty(prefix+"tex_max_neib_lev", this.tex_max_neib_lev+""); // int
properties.setProperty(prefix+"tex_split_textures", this.tex_split_textures+""); // boolean
properties.setProperty(prefix+"tex_subdiv_tiles", this.tex_subdiv_tiles+""); // int
properties.setProperty(prefix+"tex_sky_extra", this.tex_sky_extra+""); // int
properties.setProperty(prefix+"tex_sky_below", this.tex_sky_below+""); // int
properties.setProperty(prefix+"tex_disp_hires_tri", this.tex_disp_hires_tri+""); // boolean
......@@ -1617,6 +1639,14 @@ public class CLTParameters {
properties.setProperty(prefix+"lre_weight_neib", this.lre_weight_neib+""); // double
properties.setProperty(prefix+"lre_weight_bg", this.lre_weight_bg+""); // double
properties.setProperty(prefix+"lre_best_dir_frac", this.lre_best_dir_frac+""); // double
properties.setProperty(prefix+"lre_use_min_max", this.lre_use_min_max+""); // boolean
properties.setProperty(prefix+"lre_temp_radius", this.lre_temp_radius+""); // double
properties.setProperty(prefix+"lre_temp_min", this.lre_temp_min+""); // int
properties.setProperty(prefix+"lre_temp_weight", this.lre_temp_weight+""); // double
properties.setProperty(prefix+"lre_min_use_occl", this.lre_min_use_occl+""); // double
properties.setProperty(prefix+"lre_temp_disparity", this.lre_temp_disparity+""); // double
properties.setProperty(prefix+"lre_cost_min", this.lre_cost_min+""); // double
properties.setProperty(prefix+"lre_max_trim_iterations", this.lre_max_trim_iterations+""); // int
//
......@@ -1626,8 +1656,8 @@ public class CLTParameters {
properties.setProperty(prefix+"lre_show_textures_slice", this.lre_show_textures_slice+""); // boolean
properties.setProperty(prefix+"lre_show_textures_combo", this.lre_show_textures_combo+""); // boolean
properties.setProperty(prefix+"lre_show_textures_tiles", this.lre_show_textures_tiles+""); // boolean
properties.setProperty(prefix+"lre_show_sky_textures", this.lre_show_sky_textures+""); // boolean
properties.setProperty(prefix+"lre_show_slice_bitmap", this.lre_show_slice_bitmap+""); // int
properties.setProperty(prefix+"pt_super_trust", this.pt_super_trust +"");
properties.setProperty(prefix+"pt_keep_raw_fg", this.pt_keep_raw_fg+"");
......@@ -2488,6 +2518,10 @@ public class CLTParameters {
if (properties.getProperty(prefix+"tex_disp_rdiffj")!=null) this.tex_disp_rdiffj=Double.parseDouble(properties.getProperty(prefix+"tex_disp_rdiffj"));
if (properties.getProperty(prefix+"tex_fg_bg")!=null) this.tex_fg_bg=Double.parseDouble(properties.getProperty(prefix+"tex_fg_bg"));
if (properties.getProperty(prefix+"tex_disp_over_sky")!=null) this.tex_disp_over_sky=Double.parseDouble(properties.getProperty(prefix+"tex_disp_over_sky"));
if (properties.getProperty(prefix+"tex_str_over_sky")!=null) this.tex_str_over_sky=Double.parseDouble(properties.getProperty(prefix+"tex_str_over_sky"));
if (properties.getProperty(prefix+"tex_require_lma")!=null) this.tex_require_lma=Boolean.parseBoolean(properties.getProperty(prefix+"tex_require_lma"));
if (properties.getProperty(prefix+"tex_distort")!=null) this.tex_distort=Double.parseDouble(properties.getProperty(prefix+"tex_distort"));
if (properties.getProperty(prefix+"tex_mb")!=null) this.tex_mb=Double.parseDouble(properties.getProperty(prefix+"tex_mb"));
if (properties.getProperty(prefix+"tex_max_disparity_lim")!=null)this.tex_max_disparity_lim=Double.parseDouble(properties.getProperty(prefix+"tex_max_disparity_lim"));
......@@ -2495,6 +2529,7 @@ public class CLTParameters {
if (properties.getProperty(prefix+"tex_max_neib_lev")!=null) this.tex_max_neib_lev=Integer.parseInt(properties.getProperty(prefix+"tex_max_neib_lev"));
if (properties.getProperty(prefix+"tex_split_textures")!=null) this.tex_split_textures=Boolean.parseBoolean(properties.getProperty(prefix+"tex_split_textures"));
if (properties.getProperty(prefix+"tex_subdiv_tiles")!=null) this.tex_subdiv_tiles=Integer.parseInt(properties.getProperty(prefix+"tex_subdiv_tiles"));
if (properties.getProperty(prefix+"tex_sky_extra")!=null) this.tex_sky_extra=Integer.parseInt(properties.getProperty(prefix+"tex_sky_extra"));
if (properties.getProperty(prefix+"tex_sky_below")!=null) this.tex_sky_below=Integer.parseInt(properties.getProperty(prefix+"tex_sky_below"));
if (properties.getProperty(prefix+"tex_disp_hires_tri")!=null) this.tex_disp_hires_tri=Boolean.parseBoolean(properties.getProperty(prefix+"tex_disp_hires_tri"));
......@@ -2600,6 +2635,14 @@ public class CLTParameters {
if (properties.getProperty(prefix+"lre_weight_neib")!=null) this.lre_weight_neib=Double.parseDouble(properties.getProperty(prefix+"lre_weight_neib"));// double
if (properties.getProperty(prefix+"lre_weight_bg")!=null) this.lre_weight_bg=Double.parseDouble(properties.getProperty(prefix+"lre_weight_bg"));// double
if (properties.getProperty(prefix+"lre_best_dir_frac")!=null) this.lre_best_dir_frac=Double.parseDouble(properties.getProperty(prefix+"lre_best_dir_frac"));// double
if (properties.getProperty(prefix+"lre_use_min_max")!=null) this.lre_use_min_max=Boolean.parseBoolean(properties.getProperty(prefix+"lre_use_min_max"));// boolean
if (properties.getProperty(prefix+"lre_temp_radius")!=null) this.lre_temp_radius=Double.parseDouble(properties.getProperty(prefix+"lre_temp_radius"));// double
if (properties.getProperty(prefix+"lre_temp_min")!=null) this.lre_temp_min=Integer.parseInt(properties.getProperty(prefix+"lre_temp_min"));// int
if (properties.getProperty(prefix+"lre_temp_weight")!=null) this.lre_temp_weight=Double.parseDouble(properties.getProperty(prefix+"lre_temp_weight"));// double
if (properties.getProperty(prefix+"lre_min_use_occl")!=null) this.lre_min_use_occl=Double.parseDouble(properties.getProperty(prefix+"lre_min_use_occl"));// double
if (properties.getProperty(prefix+"lre_temp_disparity")!=null) this.lre_temp_disparity=Double.parseDouble(properties.getProperty(prefix+"lre_temp_disparity"));// double
if (properties.getProperty(prefix+"lre_cost_min")!=null) this.lre_cost_min=Double.parseDouble(properties.getProperty(prefix+"lre_cost_min"));// double
if (properties.getProperty(prefix+"lre_max_trim_iterations")!=null) this.lre_max_trim_iterations=Integer.parseInt(properties.getProperty(prefix+"lre_max_trim_iterations"));// int
//
......@@ -2609,8 +2652,8 @@ public class CLTParameters {
if (properties.getProperty(prefix+"lre_show_textures_slice")!=null) this.lre_show_textures_slice=Boolean.parseBoolean(properties.getProperty(prefix+"lre_show_textures_slice"));// boolean
if (properties.getProperty(prefix+"lre_show_textures_combo")!=null) this.lre_show_textures_combo=Boolean.parseBoolean(properties.getProperty(prefix+"lre_show_textures_combo"));// boolean
if (properties.getProperty(prefix+"lre_show_textures_tiles")!=null) this.lre_show_textures_tiles=Boolean.parseBoolean(properties.getProperty(prefix+"lre_show_textures_tiles"));// boolean
if (properties.getProperty(prefix+"lre_show_sky_textures")!=null) this.lre_show_sky_textures=Boolean.parseBoolean(properties.getProperty(prefix+"lre_show_sky_textures"));// boolean
if (properties.getProperty(prefix+"lre_show_slice_bitmap")!=null) this.lre_show_slice_bitmap=Integer.parseInt(properties.getProperty(prefix+"lre_show_slice_bitmap"));
if (properties.getProperty(prefix+"pt_super_trust")!=null) this.pt_super_trust=Double.parseDouble(properties.getProperty(prefix+"pt_super_trust"));
if (properties.getProperty(prefix+"pt_keep_raw_fg")!=null) this.pt_keep_raw_fg=Boolean.parseBoolean(properties.getProperty(prefix+"pt_keep_raw_fg"));
......@@ -3636,6 +3679,15 @@ public class CLTParameters {
gd.addNumericField("Minimal FG/BG disparity separation", this.tex_fg_bg, 5,7,"pix",
"Minimal FG/BG disparity difference (NaN bg if difference from FG < this).");
gd.addMessage ("Remove far/weak tiles near Blue Sky (within 2 tiles)");
gd.addNumericField("Far tiles near sky disparity", this.tex_disp_over_sky, 5,7,"pix",
"Ignore far tiles near BS.");
gd.addNumericField("Weak tiles near sky strength", this.tex_str_over_sky, 5,7,"",
"Ignore weak tiles near BS.");
gd.addCheckbox ("Require LMA", this.tex_require_lma,
"Consider tiles w/o LMA as weak near blue sky.");
gd.addMessage ("Reduce weight of distorted and motion blurred textures in multiscene averaging");
gd.addNumericField("Multiscene texture distortion", this.tex_distort, 5,7,"pix",
"Maximal texture distortion to accumulate multiple scenes (neighbor tile center offset from the uniform grid. 0 - do not filter");
gd.addNumericField("Maximal motion blur to reduce weight",this.tex_mb, 5,7,"pix",
......@@ -3651,7 +3703,9 @@ public class CLTParameters {
"Split combined texture images. False use multi-cluster full size texture images.");
gd.addNumericField("Subdivide tiles to emulate alpha", this.tex_subdiv_tiles, 0,3,"",
"Subdivide tiles to smaller triangles to improve lateral resolution. Best for 1-2-4-8.");
gd.addNumericField("Extend sky area", this.tex_sky_below, 0,3,"tiles",
gd.addNumericField("Extend sky around", this.tex_sky_extra, 0,3,"tiles",
"additionally grow sky area (in layers) without marking it as sky.");
gd.addNumericField("Extend sky area down", this.tex_sky_below, 0,3,"tiles",
"if >=0, extend sky these tile rows below lowest and extend sky up, right and left to full image.");
gd.addMessage ("Triangular mesh");
......@@ -3844,10 +3898,28 @@ public class CLTParameters {
"Weight of BG cost relative to the FG one.");
gd.addNumericField("Best direction fraction", this.lre_best_dir_frac, 5,7,"", // 0.6; // for BG - use this fraction of all sensors in the best direction
"Reduce th BG cost by limiting number of considered sensor (find best consecutive ones) .");
gd.addMessage("Trimming by temperature (tone)");
gd.addCheckbox ("Use min/max instead of averages", this.lre_show_debug, // true
"when trimming by tone, use min/max of the FG/BG instead of weighted averages.");
gd.addNumericField("Trim by temperature radius", this.lre_temp_radius, 5,7,"",
"How far to look around for FG trimming by temperature.");
gd.addNumericField("Min FG and BG neibs within radius", this.lre_temp_min, 0,3,"", // 10
"Minimal number of each of FG/BG while trimming by temperature.");
gd.addNumericField("Cost weight of temperature", this.lre_temp_weight, 5,7,"",
"Multiply -1.0..+1.0 range of the current pixel between average BG(-1) and FG(+1).");
gd.addNumericField("Minimal occlusions FG/BG difference", this.lre_min_use_occl, 5,7,"pix",
"Do not use occlusion costs for small FG/BG separation, only use temperature/tone based one.");
gd.addNumericField("FG/BG disparity difference", this.lre_temp_disparity, 5,7,"pix",
"FG-BG disparity (in excess of the previous parameter) where weight of cost by obscuring equals weight of cost by temp. For lower temperature related cost increases.");
gd.addNumericField("Minimal absolute value of the cost", this.lre_cost_min, 5,7,"", // 1.0; // minimal absolute value of the total cost to make changes
"Minimal absolute value of the total cost to make changes (opaque/transparent).");
gd.addNumericField("Number of the FG update iterations", this.lre_max_trim_iterations, 0,3,"", // 10
"Number of iterations to recalculate FG pixels opaque/transparent state.");
gd.addMessage("Debug images generation");
gd.addCheckbox ("Global debug image enable", this.lre_show_debug, // true
"Global debug image enable (masked by the batch mode state).");
......@@ -3863,6 +3935,8 @@ public class CLTParameters {
"Show all-slices texture debug images with tile resolution (80x64 for Boson 640).");
gd.addCheckbox ("Show sky/backdrop texture expanding", this.lre_show_sky_textures, // false;
"Show how sky/backdrop texture is cut and extrapolated.");
gd.addNumericField("Show slices bitmap", this.lre_show_slice_bitmap, 0,6,"", // 10
"Bitmap of slices to show (-1 - all). Applies to per-slice alpha and per-slice textures.");
gd.addTab ("Plates", "Plates filtering when building initial z-map");
gd.addMessage ("********* Plates filtering when building initial z-map *********");
......@@ -4857,6 +4931,10 @@ public class CLTParameters {
this.tex_disp_rdiffj = gd.getNextNumber();
this.tex_fg_bg = gd.getNextNumber();
this.tex_disp_over_sky = gd.getNextNumber();
this.tex_str_over_sky = gd.getNextNumber();
this.tex_require_lma = gd.getNextBoolean();
this.tex_distort = gd.getNextNumber();
this.tex_mb = gd.getNextNumber();
......@@ -4865,6 +4943,7 @@ public class CLTParameters {
this.tex_max_neib_lev = (int) gd.getNextNumber();
this.tex_split_textures = gd.getNextBoolean();
this.tex_subdiv_tiles = (int) gd.getNextNumber();
this.tex_sky_extra = (int) gd.getNextNumber();
this.tex_sky_below = (int) gd.getNextNumber();
this.tex_disp_hires_tri = gd.getNextBoolean();
......@@ -4968,6 +5047,15 @@ public class CLTParameters {
this.lre_weight_neib= gd.getNextNumber(); // double
this.lre_weight_bg= gd.getNextNumber(); // double
this.lre_best_dir_frac= gd.getNextNumber(); // double
this.lre_use_min_max= gd.getNextBoolean(); // boolean
this.lre_temp_radius= gd.getNextNumber(); // double
this.lre_temp_min= (int) gd.getNextNumber(); // int
this.lre_min_use_occl= gd.getNextNumber(); // double
this.lre_temp_weight= gd.getNextNumber(); // double
this.lre_temp_disparity= gd.getNextNumber(); // double
this.lre_cost_min= gd.getNextNumber(); // double
this.lre_max_trim_iterations=(int) gd.getNextNumber(); // int
......@@ -4978,6 +5066,7 @@ public class CLTParameters {
this.lre_show_textures_combo= gd.getNextBoolean(); // boolean
this.lre_show_textures_tiles= gd.getNextBoolean(); // boolean
this.lre_show_sky_textures= gd.getNextBoolean(); // boolean
this.lre_show_slice_bitmap= (int) gd.getNextNumber();
// end of gd.addtab ("Lateral resolution enhancement");
......
......@@ -7190,6 +7190,7 @@ public class QuadCLTCPU {
public static void umTextures(
final double [][][] textures, // [nslices][nchn][i]
final int width,
final boolean ignore_alpha,
final double um_sigma,
final double um_weight){
if ((textures == null) || (textures.length==0)) {
......@@ -7222,7 +7223,7 @@ public class QuadCLTCPU {
for (int i = 0; i < texture.length; i++) {
texture[i] = texture_orig[i] - um_weight * texture[i];
}
if (has_alpha) {
if (has_alpha && !ignore_alpha) {
for (int i = 0; i < texture.length; i++) if (texture_alpha[i] <= 0.0){
texture[i] = 0.0;
}
......@@ -7323,6 +7324,7 @@ public class QuadCLTCPU {
}
public static void applyTexturesNormHist(
final boolean ignore_alpha,
final double [][][] textures, // [nslices][nchn][i]
final double [] min_max,
final double [] inv_table)
......@@ -7341,7 +7343,7 @@ public class QuadCLTCPU {
threads[ithread] = new Thread() {
public void run() {
for (int npix = ai.getAndIncrement(); npix < texture.length; npix = ai.getAndIncrement()) {
if (!has_alpha || (texture_alpha[npix] > 0.0)) {
if (!Double.isNaN(texture[npix]) && (ignore_alpha || !has_alpha || (texture_alpha[npix] > 0.0))) {
double rel_in = (texture[npix] - min_max[0]) / range;
if (rel_in < 0.0) {
rel_in = 0.0;
......
......@@ -307,7 +307,7 @@ public class TexturedModel {
if (!tn.isBorder(tile)) { // do not start on the border
for (int layer = 0; layer < layers; layer++) {
int n_neibs = NUM_NEIBS_FROM_BITS[num_neibs_dir[tile][layer]];
// if ((ncluster[tile][layer] == CLUSTER_UNASSIGNED) && (n_neibs > nn)) { // not yet assigned and >=0 neibs
// if ((ncluster[tile][layer] == CLUSTER_UNASSIGNED) && (n_neibs > nn)) { // not yet assigned and >=0 neibs
if (!Double.isNaN(disparity_layers[layer][tile]) && (n_neibs > nn)) { // not yet assigned and >=0 neibs
nn = n_neibs;
best_tile = tile;
......@@ -329,28 +329,49 @@ public class TexturedModel {
/**
* Create a "blue sky" tile cluster with flaps, may be disconnected. Should be ran before
* all other clusters are created
* @param cluster_list empty clusters list, if Blue Sky is not empty, it will generate a cluster
* and will be added to the list
* @param disparity_layers [layers][tiles] multi-layer disparity array with NaN
* for non-existing tiles
* for non-existing tiles. This array will be modified to limit disparities
* so they will be closer than a backdrop (blue sky)
* @param strength_layers [layers][tiles] strength array corresponding to disparity_layers
* @param blue_sky per-tile array of the "blue sky" boolean array
* @param blue_sky_layer layer for the "blue sky" data (should be on a single layer)
* @param extra_sky_grow additionally grow blue sky without using disparity array
* @param blue_sky_below (only if is_sky_cluster) if >=0 - extend bounds, if <0 treat blue_sky bounds
* same as regular ones.
* @param max_neib_lev maximal neighbor level of borders used to generate internal int [] neib_lev
* array. Neighbor level 0 corresponds to internal tiles that uses original
* disparity, level 1 - neighbors of level 0 on the border or in conflict with
* level 0. Level 2 - neighbors of 1 or in conflict with level 0, and so all.
* @param min_obj_disparity minimal disparity for non-BS objects (calculated from backdrop distance and
* minimal absolute distance from tyhe backdrop)
* @param str_over_sky maximal strength for extended BS area to remove weak far tiles
* @param disp_over_sky maximal disparity for extended BS area to remove weak far tiles
* @param tex_fg_bg minimal layer disparity separation to keep both layers
* @param tilesX horizontal array dimension
* @param debugLevel debug level - controls generation of images
* @return TileCluster instance generated from the initial source_disparity[] array.
* @return copy of (possibly modified disparity_layers) where tiles, corresponding to BS
* are set to NaN - this array will be used to clusterize remaining disparity tiles.
*/
public static TileCluster buildSkyCluster(
public static double [][] buildSkyCluster(
final ArrayList <TileCluster> cluster_list,
final double [][] disparity_layers, // should not have same tile disparity on multiple layers
final double [][] strength_layers, // should not have same tile disparity on multiple layers
final boolean [] blue_sky, // Do not mix bs/no_bs in the same cluster
final int blue_sky_layer,
final int extra_sky_grow, // 2
final int blue_sky_below,
final int max_neib_lev,
final double min_obj_disparity, // minimal disparity of non-BS tiles (replace)
// filter objects over extended sky
final double str_over_sky,
final double disp_over_sky,
final double tex_fg_bg, // 0.1; // Minimal FG/BG disparity difference (NaN bg if difference from FG < this)
final int tilesX,
final int debugLevel){
final int num_layers = disparity_layers.length;
final int tiles = disparity_layers[0].length;
final int tilesY = tiles/tilesX;
final int [] borders_int = new int[tiles];
......@@ -364,21 +385,98 @@ public class TexturedModel {
public void run() {
for (int tile = ai.getAndIncrement(); tile < tiles; tile = ai.getAndIncrement()) {
if (blue_sky[tile]) {
int tileX = tile % tilesX;
int tileY = tile / tilesX;
anum.getAndIncrement();
borders_int[tile] = 0;
disparity_layers[blue_sky_layer][tile] = Double.NaN;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (anum.get() == 0) {
return null; // no blue sky tiles exist
}
if (anum.get() > 0) {
final boolean [] selection = blue_sky.clone();
AtomicInteger anmod = new AtomicInteger(0);
for (int nlev = 1; nlev <= max_neib_lev; nlev++) {
final int fnlev = nlev;
tn.growSelection(
2, // int grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
selection, // final boolean [] tiles,
null); // null); // final boolean [] prohibit)
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int tile = ai.getAndIncrement(); tile < tiles; tile = ai.getAndIncrement()) {
if (selection[tile] && (borders_int[tile] < 0)) {
borders_int[tile] = fnlev;
// if it is a weak far tile connected to BS area - make it 0
for (int nl = 0; nl <num_layers; nl++ ) {
double disp = disparity_layers[nl][tile];
double str = strength_layers[nl][tile];
// if very low disparity - ok to miss even strong tile
// if weak - ok to miss high disparity (it should be not that weak)
if (!Double.isNaN(disp) && ((disp < disp_over_sky) || (str < str_over_sky))){
for (int dir = 0; dir < TileNeibs.DIRS; dir++) {
int tile1 = tn.getNeibIndex(tile, dir);
if ((tile1 >= 0) && (borders_int[tile1] == 0)) {
disparity_layers[nl][tile] = Double.NaN; // erase
if (nl == blue_sky_layer) {
borders_int[tile] = 0; // blue sky mark as
anmod.getAndIncrement(); // will have to recalculate blue sky and borders
}
break; //dir, other layers continue
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
if (debugLevel > -2) {
System.out.println("buildSkyCluster(): extended Blue Sky over far weak tiles, number of modified tiles = "+anmod.get());
}
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int tile = ai.getAndIncrement(); tile < tiles; tile = ai.getAndIncrement()) {
if (selection[tile]) {
selection[tile] = borders_int[tile] == 0;
if (selection[tile]) {
blue_sky[tile] = true;
} else {
borders_int[tile] = -1; // reset for new expansion
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
// re-calculate borders and extra extend, do not expand blue_sky[]
if (extra_sky_grow > 0) {
tn.growSelection(
2 * extra_sky_grow, // int grow, // grow tile selection by 1 over non-background tiles 1: 4 directions, 2 - 8 directions, 3 - 8 by 1, 4 by 1 more
selection, // final boolean [] tiles,
null); // null); // final boolean [] prohibit)
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int tile = ai.getAndIncrement(); tile < tiles; tile = ai.getAndIncrement()) {
borders_int[tile] = selection[tile]? 0 : -1;
}
}
};
}
ImageDtt.startAndJoin(threads);
}
for (int nlev = 1; nlev <= max_neib_lev; nlev++) {
final int fnlev = nlev;
tn.growSelection(
......@@ -445,6 +543,7 @@ public class TexturedModel {
int tileY = tile_crop / width + bounds.y ;
int tileX = tile_crop % width + bounds.x;
int tile = tileX + tileY * tilesX;
// keep all rectangle as 0 (not NaN) -> KEEP -> mesh
disparity_crop[tile_crop] = (borders_int[tile] >=0) ? 0.0 : Double.NaN;
border_int_crop[tile_crop] = borders_int[tile];
}
......@@ -460,8 +559,72 @@ public class TexturedModel {
max_neib_lev, // int border_int_max, // outer border value
disparity_crop,
true)); // boolean is_sky));
return tileCluster;
cluster_list.add(tileCluster);
} // if (anum.get() > 0) { - Blue Sky exists
// limit all non-BS disparities
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int tile = ai.getAndIncrement(); tile < tiles; tile = ai.getAndIncrement()) {
for (int nl = 0; nl <num_layers; nl++ ) {
double disp = disparity_layers[nl][tile];
if (blue_sky[tile] && (nl == blue_sky_layer)) {
disparity_layers[nl][tile] = 0.0;
} else if (!Double.isNaN(disp) && (disp < min_obj_disparity)) {
disparity_layers[nl][tile] = min_obj_disparity;
}
}
for (int nl = 0; nl <num_layers; nl++ ) {
double disp = disparity_layers[nl][tile];
if (!Double.isNaN(disp)) {
for (int nl1 = nl+1; nl1 <num_layers; nl1++ ) {
double disp1 = disparity_layers[nl1][tile];
if (!Double.isNaN(disp)) {
if (Math.abs(disp1 - disp) < tex_fg_bg) {
if (nl == blue_sky_layer) {
disparity_layers[nl1][tile] = Double.NaN;
} else if (nl1 == blue_sky_layer) {
disparity_layers[nl][tile] = Double.NaN;
break; // go to next nl layer
} else if (strength_layers[nl][tile] > strength_layers[nl][tile]){
disparity_layers[nl1][tile] = Double.NaN;
} else {
disparity_layers[nl][tile] = Double.NaN;
break; // go to next nl layer
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
final double [][] disparity_layers_out = new double [disparity_layers.length][];
for (int i = 0; i < disparity_layers.length; i++) {
disparity_layers_out[i] = disparity_layers[i].clone();
}
// now remove processed BS tiles from disparity_layers_out
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int tile = ai.getAndIncrement(); tile < tiles; tile = ai.getAndIncrement()) if (blue_sky[tile]){
disparity_layers_out[blue_sky_layer][tile] = Double.NaN;
}
}
};
}
ImageDtt.startAndJoin(threads);
return disparity_layers_out;
}
/**
* Create initial cluster of connected tiles without provisions for overlap resolution
......@@ -533,9 +696,9 @@ public class TexturedModel {
double delta_disp_diag = (disp_adiffd + disp * disp_rdiffd) * disp_fof;
for (int dir = 0; dir < TileNeibs.DIRS; dir++) {
int tile1 = tn.getNeibIndex(tile, dir); // should always be > 0 here
// if (tile1 == 2849) {
// System.out.println("buildInitialCluster(): tile1 = "+tile1);
// }
// if (tile1 == 2849) {
// System.out.println("buildInitialCluster(): tile1 = "+tile1);
// }
if (tile1 >= 0) {
double delta_disp = ((dir & 1) == 0)? delta_disp_ortho : delta_disp_diag;
// see if it already has a tile of the same cluster in this direction
......@@ -748,7 +911,7 @@ public class TexturedModel {
}
// final boolean [] disp_mod = new boolean[tiles]; // disparity modified from surce_disparity
// final boolean [] disp_mod = new boolean[tiles]; // disparity modified from surce_disparity
Arrays.fill(neib_lev, -1);
System.arraycopy(source_disparity, 0, disparity, 0, tiles);
final TileNeibs tn = new TileNeibs(tilesX, tilesY);
......@@ -784,7 +947,7 @@ public class TexturedModel {
}
double disp = disparity[tile];
if (!Double.isNaN(disp)) {
// neib_lev[tile] = (seams[tile] > 0) ? (max_neib_lev - seams[tile] + 1) : 0; // 2-> 1; 1 -> 2; 0-> 0;
// neib_lev[tile] = (seams[tile] > 0) ? (max_neib_lev - seams[tile] + 1) : 0; // 2-> 1; 1 -> 2; 0-> 0;
if (seams[tile] > 0) {
neib_lev[tile] = max_neib_lev - seams[tile] + 1;
initial_seam[tile] = true;
......@@ -837,13 +1000,13 @@ public class TexturedModel {
lor_list.ensureCapacity(loc_list.size());
while (!loc_list.isEmpty()) {
int tile = loc_list.remove(0);
// if (((tile >= 4028) && (tile <= 4032)) || ((tile >= 4108) && (tile <= 4112))) {
// System.out.println("buildTileCluster().11: tile="+tile);
// System.out.println();
// }
// if (((tile >= 4028) && (tile <= 4032)) || ((tile >= 4108) && (tile <= 4112))) {
// System.out.println("buildTileCluster().11: tile="+tile);
// System.out.println();
// }
// find highest neighbor of neib_lev < max_neib_lev
// double max_n = Double.NaN;
// int source_neib_level = 0; // maybe find max separately for each neib_level, and assign
// double max_n = Double.NaN;
// int source_neib_level = 0; // maybe find max separately for each neib_level, and assign
// lower disparity but lower neib_level if both conflict?
double [] max_n = new double [max_neib_lev];
Arrays.fill(max_n, Double.NaN);
......@@ -886,10 +1049,10 @@ public class TexturedModel {
// look around, for conflicts, add if was not already there (consider using additional array?)
for (int dir0 = 0; dir0 < 8; dir0++) {
int tile = tn.getNeibIndex(tile0, dir0);
// if (((tile >= 4028) && (tile <= 4032)) || ((tile >= 4108) && (tile <= 4112))) {
// System.out.println("buildTileCluster().12: tile="+tile+", tile0="+tile0);
// System.out.println();
// }
// if (((tile >= 4028) && (tile <= 4032)) || ((tile >= 4108) && (tile <= 4112))) {
// System.out.println("buildTileCluster().12: tile="+tile+", tile0="+tile0);
// System.out.println();
// }
// tries many times as it does not qualify to be added
if ((tile >= 0) && !loc_list.contains(tile)) { // Do not check+add same tile
double disp = disparity[tile];
......@@ -909,10 +1072,10 @@ public class TexturedModel {
}
//
if (!Double.isNaN(max_n)) { // got at least 1 neighbor
// if (((tile >= 4028) && (tile <= 4032)) || ((tile >= 4108) && (tile <= 4112))) {
// System.out.println("buildTileCluster().13: tile="+tile+", tile0="+tile0);
// System.out.println();
// }
// if (((tile >= 4028) && (tile <= 4032)) || ((tile >= 4108) && (tile <= 4112))) {
// System.out.println("buildTileCluster().13: tile="+tile+", tile0="+tile0);
// System.out.println();
// }
if (Double.isNaN(disparity[tile])) {
max_neib[tile] = max_n; // is it needed? Yes, for ordering
loc_list.add(tile);
......@@ -1079,10 +1242,10 @@ public class TexturedModel {
}
ImageDtt.startAndJoin(threads);
final boolean [] dbg_discontinued_full = (debugLevel > 0)? discontinued.clone() : null;
// ai.set(0);
// ai.set(0);
ati.set(0);
// re-create list of conflicts (with max_neib_lev only) of defined tiles with neib_lev[] < max_neib_lev
// loc_multi.clear();
// loc_multi.clear();
for (int ithread = 0; ithread < threads.length; ithread++) {
loc_multi.add(new ArrayList<Integer>());
threads[ithread] = new Thread() {
......@@ -1107,7 +1270,7 @@ public class TexturedModel {
Arrays.fill(discontinued, false);
ati.set(0);
// re-create list of conflicts (with max_neib_lev only) of defined tiles with neib_lev[] < max_neib_lev
// loc_multi.clear();
// loc_multi.clear();
for (int ithread = 0; ithread < threads.length; ithread++) {
loc_multi.add(new ArrayList<Integer>());
threads[ithread] = new Thread() {
......@@ -1132,7 +1295,7 @@ public class TexturedModel {
// filter loc_list from isolated tiles
// boolean [] discontinued = new boolean [neib_lev.length];
// boolean [] discontinued = new boolean [neib_lev.length];
// Temporarily mark loc_list with max_neib_lev+1 to remove them from averaging (later mark again)
/*
for (int tile:loc_list) {
......@@ -1197,10 +1360,10 @@ public class TexturedModel {
break;
}
for (int tile:loc_list) {
// if (tile == 2608) {
// System.out.println("buildTileCluster().31: tile="+tile);
// System.out.println();
// }
// if (tile == 2608) {
// System.out.println("buildTileCluster().31: tile="+tile);
// System.out.println();
// }
neib_lev[tile] = nlev;
// mark new seams:
for (int layer = 0; layer < disparity_layers.length; layer++) {
......@@ -1265,8 +1428,8 @@ public class TexturedModel {
System.out.println("buildTileCluster() BUG - no tiles removed from disparity_layers[] for cluster "+cluster_list.size());
}
// Marking discontinued max_neib_lev with max_neib_lev+1 for building meshes they should not be connected to max_neib_lev
// Maybe there is a more elegant way to do this.
// Marking discontinued max_neib_lev with max_neib_lev+1 for building meshes they should not be connected to max_neib_lev
// Maybe there is a more elegant way to do this.
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
......@@ -1356,9 +1519,9 @@ public class TexturedModel {
System.out.println("buildTileCluster(): splitting textureCluster into "+
num_sub + " connected ones, current cluster before them is "+cluster_list.size());
}
// neib_lev[tile]
// disparity
// border_int
// neib_lev[tile]
// disparity
// border_int
TileCluster [] tileClusters = new TileCluster[pnum_clust[0]];
for (int nsub = 0; nsub < num_sub; nsub++) {
int [] neib_lev_sub = (num_sub > 1) ? (new int [tiles]): neib_lev;
......@@ -1475,9 +1638,10 @@ public class TexturedModel {
* @return array of consolidated (multiple non-overlapping clusters) clusters,
* each having the full frame bounds.
*/
public static TileCluster [] clusterizeFgBg( //
public static TileCluster[] clusterizeFgBg( //
final ArrayList <TileCluster> cluster_list,
final int tilesX,
final double [][] disparity_layers_src, // may have more layers
final double [][] disparity_layers, // _src, // may have more layers
final boolean [] blue_sky, // use to expand background by blurring available data?
final int blue_sky_layer,
final int blue_sky_below,
......@@ -1491,23 +1655,32 @@ public class TexturedModel {
final double disp_adiffj,
final double disp_rdiffj,
final int debugLevel) {
final int tiles = disparity_layers_src[0].length;
final int layers = disparity_layers.length;
// for (int i = 0 ; i < disparity_layers.length; i++) {
// disparity_layers[i] = disparity_layers_src[i].clone();
// }
final int tiles = disparity_layers[0].length;
final int tilesY = tiles/tilesX;
final int layers = disparity_layers_src.length;
final int [][] num_neibs_dir = new int[tiles][layers]; // -1 - none, otherwise - bitmask
// Needed to tell next clusters of the BG seam tiles (shared by >=2 clusters)
final int [][] seams_layers = new int [layers][tiles];
final int [] seams = new int [tiles]; // seams matching disparity[]
//copy original disparity_layers_src to disparity_layers - they will be modified
final double [][] disparity_layers = new double [disparity_layers_src.length][];
for (int i = 0 ; i < disparity_layers.length; i++) {
disparity_layers[i] = disparity_layers_src[i].clone();
}
// maybe ncluster[][] will not be used at all - disparity_layers will be modified to NaN used tiles
// Before initial updateSeeds() - may be simplified as BS is already processed
final ArrayList <TileCluster> cluster_list = new ArrayList<TileCluster>();
// final ArrayList <TileCluster> cluster_list = new ArrayList<TileCluster>();
// build blue sky first
// now it will be able to modify disparity_layers and sky_tiles to improve around blue sky
// make changes to disparity to go back to disparity_layers_src (all that are not new BS)
// make minimal disparity setting inside buildSkyCluster
// move TileCluster blueSkyCluster = buildSkyCluster(... to the caller and pass cluster_list here
// add
// 1. grey BS area (2 layers)
// 2. minimal strength over grey area around BS
// 3. when extending, layer by layer - only extend if it has NaN over previous border level (or is level1)
// 4. Expand BS over NaN in grey area
/*
TileCluster blueSkyCluster = buildSkyCluster(
disparity_layers, // final double [][] disparity_layers, // should not have same tile disparity on multiple layers
blue_sky, // final boolean [] blue_sky, // use to expand background by blurring available data?
......@@ -1522,7 +1695,7 @@ public class TexturedModel {
System.out.println("clusterizeFgBg(): processed sky cluster");
}
}
*/
// calculate initial num_neibs_dir
updateSeeds( // and update num_neibs_dir
num_neibs_dir, // final int [][] num_neibs_dir, // [tile][layer]
......@@ -1623,9 +1796,9 @@ public class TexturedModel {
disp_rdiff, // final double disp_rdiff,
tilesX, // final int tilesX,
debugLevel); // final int debugLevel)
// if (debugLevel > -1000) {
// return null;
// }
// if (debugLevel > -1000) {
// return null;
// }
for (int nsub = 0; nsub < tileClusters.length; nsub++) {
updateSeeds( // and update num_neibs_dir
num_neibs_dir, // final int [][] num_neibs_dir, // [tile][layer]
......@@ -1669,8 +1842,8 @@ public class TexturedModel {
tile_start = next_seed_tile_layer[0];
} // while (true) {
// int [] tile_stat = new int [tiles];
// int [] tile_layer = new int [tiles]; // just to know which layer was used for assigned tiles
// int [] tile_stat = new int [tiles];
// int [] tile_layer = new int [tiles]; // just to know which layer was used for assigned tiles
// consolidate clusters "good enough", use bounding box intersections, add cluster_gap to grow extra tiles by Gaussian
// cluster_gap
int [] comb_clusters = new int [cluster_list.size()];
......@@ -1693,7 +1866,7 @@ public class TexturedModel {
// check to intersection with all prior clusters in this combo
candidate_cluster:
{
// Rectangle new_bounds = cluster_list.get(index_other).getBounds(cluster_gap); // cluster_gap should be 2x
// Rectangle new_bounds = cluster_list.get(index_other).getBounds(cluster_gap); // cluster_gap should be 2x
Rectangle new_bounds = cluster_list.get(index_other).getBounds(); // cluster_gap should be 2x
for (int index_already = index_first; index_already < index_other; index_already++) if (comb_clusters[index_already] == this_combo) {
if (cluster_list.get(index_already).getBounds().intersects(new_bounds)) {
......@@ -1806,16 +1979,22 @@ public class TexturedModel {
final double disp_adiffj = clt_parameters.tex_disp_adiffj;
final double disp_rdiffj = clt_parameters.tex_disp_rdiffj;
final double tex_fg_bg = clt_parameters.tex_fg_bg; // 0.1; // Minimal FG/BG disparity difference (NaN bg if difference from FG < this)
final double disp_over_sky = clt_parameters.tex_disp_over_sky; // 0.1; // Same as double tex_fg_bg?
final double str_over_sky = clt_parameters.tex_str_over_sky; // 0.7; //
final boolean require_lma = clt_parameters.tex_require_lma; // true;
final double max_disparity_lim = clt_parameters.tex_max_disparity_lim; // 100.0; // do not allow stray disparities above this
final double min_trim_disparity =clt_parameters.tex_min_trim_disparity;// 2.0; // do not try to trim texture outlines with lower disparities
final int max_neib_lev = clt_parameters.tex_max_neib_lev; // 2; // 1 - single tiles layer around, 2 - two layers
final boolean split_textures = clt_parameters.tex_split_textures; // (debugLevel > 1000); // false;
final int subdiv_tiles = clt_parameters.tex_subdiv_tiles; // 4; // subdivide tiles to smaller triangles
final int extra_sky_grow = clt_parameters.tex_sky_extra; // 2; // not 4, as it is number of grow by 2
final int sky_below = clt_parameters.tex_sky_below; // 10; // extend sky these tile rows below lowest
final boolean debug_disp_tri = clt_parameters.tex_debug_disp_tri; // !batch_mode && (debugLevel > 0); // TODO: use clt_parameters
// If there is gap between clusters, add extra row of background tiles
int add_bg_tiles = clt_parameters.tex_add_bg_tiles; // 0; // 1;
// int add_bg_tiles = clt_parameters.tex_add_bg_tiles; // 0; // 1;
final boolean save_full_textures=clt_parameters.tex_save_full_textures || !clt_parameters.tex_split_textures; //true; // false; // true;
final double alpha_threshold = clt_parameters.tex_alpha_threshold; // 0.5;
final boolean renormalize = clt_parameters.tex_renormalize; // true; // false - use normalizations from previous scenes to keep consistent colors
......@@ -1825,8 +2004,10 @@ public class TexturedModel {
final boolean showTri = !batch_mode && (debugLevel > -1) && (clt_parameters.show_triangles);
final boolean disp_hires_tri = !batch_mode && clt_parameters.tex_disp_hires_tri;
final int dbg_scale_mesh = clt_parameters.tex_dbg_scale_mesh; // 4; // <=0 - do not show
/// final double min_non_inf = 0.01; // relative to infinity disparity
/// final double min_non_inf = 0.01; // relative to infinity disparity
final boolean show_bs_debug = !batch_mode && clt_parameters.lre_show_sky_textures; // add parameter
// final boolean show_sky_textures = clt_parameters.lre_show_sky_textures && !clt_parameters.multiseq_run;
// final int show_slice_bitmap = clt_parameters.lre_show_slice_bitmap;
final int sky_layer = 0; // source disparity layer that contains "blue sky"
......@@ -1898,6 +2079,9 @@ public class TexturedModel {
scenes[ref_index], // QuadCLT scene,
debugLevel); // int debug_level)
double[][] ds_fg_bg = {ds_fg[0], ds_bg[0].clone()};
double[][] ss_fg_bg = {ds_fg[1], ds_bg[1]};
/*
for (int i = 0; i < dls_bg[0].length; i++) {
if (Math.abs(ds_fg_bg[1][i]-ds_fg_bg[0][i]) < tex_fg_bg) {
ds_fg_bg[1][i] = Double.NaN;
......@@ -1916,12 +2100,12 @@ public class TexturedModel {
}
}
}
*/
if (show_bs_debug) {
String [] dbg_titles = {"FG","BG","BS"};
double [][] dbg_img = {ds_fg_bg[0], ds_fg_bg[1],combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_BLUE_SKY].clone()};
for (int i = 0; i < dbg_img.length; i++) {
dbg_img[2][i] *= 20;
for (int i = 0; i < dbg_img[0].length; i++) {
dbg_img[2][i] = sky_tiles[i]? 20:0; // *= 20;
}
ShowDoubleFloatArrays.showArrays(
dbg_img,
......@@ -1933,10 +2117,69 @@ public class TexturedModel {
}
// Create data for consolidated textures (multiple texture segments combined in same "passes"
TileCluster [] tileClusters = clusterizeFgBg( // wrong result type, not decided
// now it will be able to modify ds_fg_bg and sky_tiles to improve around blue sky
final ArrayList <TileCluster> cluster_list = new ArrayList<TileCluster>();
if (require_lma) { // make non-LMA very weak;
for (int i = 0; i < ss_fg_bg.length; i++) {
ss_fg_bg[i]= ss_fg_bg[i].clone();
}
for (int i = 0; i < ss_fg_bg[0].length; i++) {
if (Double.isNaN(dls_fg[1][i])){
ss_fg_bg[0][i] = 0.0001;
}
if (Double.isNaN(dls_bg[1][i])){
ss_fg_bg[1][i] = 0.0001;
}
}
}
double [][] disparity_layers =buildSkyCluster(
cluster_list, // final ArrayList <TileCluster> cluster_list,
ds_fg_bg, // final double [][] disparity_layers, // should not have same tile disparity on multiple layers
ss_fg_bg, // final double [][] strength_layers, // should not have same tile disparity on multiple layers
sky_tiles, // final boolean [] blue_sky, // Do not mix bs/no_bs in the same cluster
sky_layer, // final int blue_sky_layer,
extra_sky_grow, // final int extra_sky_grow,
sky_below, // final int blue_sky_below,
max_neib_lev, // final int max_neib_lev,
min_obj_disparity, // final double min_obj_disparity, // minimal disparity of non-BS tiles (replace)
// filter objects over extended sky
str_over_sky, // final double str_over_sky,
disp_over_sky, // final double disp_over_sky,
tex_fg_bg, // final double tex_fg_bg, // 0.1; // Minimal FG/BG disparity difference (NaN bg if difference from FG < this)
tilesX, // final int tilesX,
debugLevel); // final int debugLevel)
if (show_bs_debug) {
String [] dbg_titles = {"FG","BG", "SFG", "SBG","BS"};
double [][] dbg_img = new double [dbg_titles.length][];
dbg_img[0] = disparity_layers[0];
dbg_img[1] = disparity_layers[1];
dbg_img[2] = ss_fg_bg[0];
dbg_img[3] = ss_fg_bg[1];
dbg_img[4] = new double [sky_tiles.length];
for (int i = 0; i < sky_tiles.length; i++) {
dbg_img[4][i] = sky_tiles[i]? 20: 0;
}
ShowDoubleFloatArrays.showArrays(
dbg_img,
tilesX,
dbg_img[0].length/tilesX,
true,
ref_scene.getImageName()+"-disparity_layers_after_sky",
dbg_titles);
}
TileCluster [] tileClusters =
clusterizeFgBg( // wrong result type, not decided
cluster_list, // final ArrayList <TileCluster> cluster_list,
tilesX, // final int tilesX,
ds_fg_bg, // final double [][] disparities, // may have more layers
sky_tiles, // final boolean blue_sky, // use to expand background by blurring available data?
disparity_layers, // ds_fg_bg, // final double [][] disparities, // may have more layers
sky_tiles, // final boolean [] blue_sky, // use to expand background by blurring available data?
sky_layer, // final int sky_layer,
sky_below, // final int blue_sky_below,
max_neib_lev, // final int max_neib_lev,
......@@ -1949,7 +2192,7 @@ public class TexturedModel {
disp_adiffj, // final double disp_adiffj,
disp_rdiffj, // final double disp_rdiffj,
debugLevel); //1); // 2); // final int debugLevel)
/*
/*
// Debugging up to here:
// if (debugLevel > -1000) {
// return false;
......@@ -1959,7 +2202,7 @@ public class TexturedModel {
System.out.println("Temporary exit after clusterizeFgBg()");
return false;
}
*/
*/
boolean [] scenes_sel = new boolean[scenes.length];
// for (int i = scenes.length - 10; i < scenes.length; i++) { // start with just one (reference) scene
......@@ -2145,7 +2388,7 @@ public class TexturedModel {
}
continue;
}
// String texturePath = imp_texture_cluster.getTitle()+".png";
// String texturePath = imp_texture_cluster.getTitle()+".png";
String texturePath = imp_texture_cluster.getOriginalFileInfo().fileName;
double [] scan_disparity = tileClusters[nslice].getSubDisparity(sub_i); // limited to cluster bounds
......@@ -3773,19 +4016,59 @@ public class TexturedModel {
return masked_textures;
}
/**
* Set disparity for extended (full rectangle normally) Blue Sky disparity for its
* slice to all zeros, overwriting NaN. Results will be used to generate full mesh
* over extended Sky - triangulation method uses NaN as transparency.
* @param tileClusters list if tile clusters
* @param slice_disparities per-slice (per texture image) disparity array
* that will be modified. Disparity should be for the full image
* array (80x64 for Flir Boson).
* @param tilesX number of tiles in a row
*/
public static void setBlueSkyDisparity(
final TileCluster [] tileClusters,
final double [][] slice_disparities,
final int tilesX)
{
int sky_slice = -1;
int sky_subindex = -1;
for (int i = 0; i < tileClusters.length; i++) {
sky_subindex = tileClusters[i].getSkyClusterIndex(); // finds first sky only!
if (sky_subindex >=0) {
sky_slice = i;
break;
}
}
if (sky_slice >= 0) {
Rectangle sky_tiles_bounds = tileClusters[sky_slice].getSubBounds(sky_subindex);
double [] sky_full_disparity = new double [sky_tiles_bounds.width * sky_tiles_bounds.height]; // all zeros
TileNeibs.setDoubleWindow(
sky_tiles_bounds, // Rectangle window,
sky_full_disparity, // double [] window_data,
slice_disparities[sky_slice], // double [] data,
tilesX); // int data_width)
}
}
/**
* Fill undefined sky texture tiles to its cluster full bounds
* @param tileClusters array of tile clusters - one may have "blue sky" sub-cluster
* @param faded_textures [slice]{texture, alpha}[pixel]
* @param tileClusters array of tile clusters - one may have "blue sky"
* sub-cluster - it will be updated
* @param textures_occluded [slice][pixel] textures that have NaN-s to be filled (read only)
* @param alphas [slice][pixel] alpha values, will be modified for BS cluster
* @param textures_final [slice][pixel] final textures, will be modified for BS cluster
* @param shrink_sky_tiles shrink (currently 4 - 2 rows) defined sky tiles before filling
* undefined pixels
* @param width image width (640 for Flir Boson)
* @param transform_size CLT transform size (==8)
* @param dbg_prefix null or debug image name prefix
*/
public static void extendBlueSKy(
final TileCluster [] tileClusters,
final double [][][] faded_textures,
final double [][] textures_occluded,
final double [][] alphas,
final double [][] textures_final,
final int shrink_sky_tiles,
final int width,
final int transform_size,
......@@ -3819,7 +4102,7 @@ public class TexturedModel {
final boolean [] reliable_sky = sky_sel.clone();
final double [] sky_pixels = TileNeibs.getDoubleWindow(
sky_pixels_bounds, // Rectangle window,
faded_textures[sky_slice][0], // double [] data,
textures_occluded[sky_slice], // double [] data,
width); // int data_width)
final String [] dbg_titles = {"source","shrank", "hinted", "filled"};
final String [] dbg_tile_titles = {"start", "filled"};
......@@ -3932,14 +4215,14 @@ public class TexturedModel {
TileNeibs.setDoubleWindow(
sky_pixels_bounds, // Rectangle window,
sky_pixels_filled, // double [] window_data,
faded_textures[sky_slice][0], // double [] data,
textures_final[sky_slice], // double [] data,
width); // int data_width)
double [] sky_alpha = new double [sky_pixels.length];
Arrays.fill(sky_alpha, 1.0);
TileNeibs.setDoubleWindow(
sky_pixels_bounds, // Rectangle window,
sky_alpha, // double [] window_data,
faded_textures[sky_slice][1], // double [] data,
alphas[sky_slice], // double [] data,
width); // int data_width)
if ((dbg_prefix != null) && (dbg_img != null)) {
ShowDoubleFloatArrays.showArrays(
......@@ -3955,6 +4238,8 @@ public class TexturedModel {
return;
}
/**
* Fix alpha for the same disparity - version with analog alpha
* @param tileClusters array of TileCluster instances, each may consist of multiple
......@@ -4431,6 +4716,7 @@ public class TexturedModel {
* @param occluded_map bitmap of blocked by FG sensors [slice][pixel]
* @param min_sensors minimal usable number of sensors visible from the FG pixel
* @param slice_disparities [slice][tile] disparity
* @param slice_clusters [slice][tile] index of cluster, do not mix different indices
* @param tile_keep [slice][tile] tiles that have at least one opaque pixel
* @param tile_stitch [slice][tile] stitch tiles - tiles that have the same disparity in other slice
* @param trim_tiles [slice][tile] trim tiles - tiles that have trimmable pixels
......@@ -4445,6 +4731,16 @@ public class TexturedModel {
* @param weight_bg weight of BG cost relative to the FG one
* @param best_dir_frac for BG - use this fraction of all sensors in the best direction
* @param cost_min minimal absolute value of the total cost to make changes
*
* @param use_min_max when trimming by tone, use min/max of the FG/BG instead of weighted averages
* @param temp_radius how far to look around for FG trimming by temperature
* @param temp_min minimal number of each of FG/BG while trimming by temperature
* @param temp_weight multiply -1.0..+1.0 range of the current pixel between average BG(-1) and FG(+1)
* @param min_use_occl minimal FG/BG difference to use trimming by occlusions. For lower
* use only temperature/tone
* @param temp_disparity FG-BG disparity difference (in excess min_use_occl) for which weight
* of cost by obscuring equals weight of cost by temp (for higher differences
* tone cost diminishes and occlusion-based grows towards 1.0
* @param debug_costs if not null, should be double [nslices][] - will return costs/NaN
* @param debug_stats if not null, should be int [nslices][] - will return number of added/removed
* opaque pixels per slice
......@@ -4460,6 +4756,7 @@ public class TexturedModel {
final int [][] occluded_map,
final int min_sensors,
final double [][] slice_disparities,
final int [][] slice_clusters,
final boolean [][] tile_keep,
final boolean [][] tile_stitch,
final boolean [][] trim_tiles,
......@@ -4474,12 +4771,20 @@ public class TexturedModel {
final double weight_bg,
final double best_dir_frac,
final double cost_min,
//"Trimming by temperature (tone)
final boolean use_min_max, // when trimming by tone, use min/max of the FG/BG instead of weighted averages
final double temp_radius, // = 11.5; // How far to look around for FG trimming by temperature
final int temp_min, // = 2; // Minimal number of each of FG/BG while trimming by temperature
final double temp_weight, // = 20.0; // Multiply -1.0..+1.0 range of the current pixel between average BG(-1) and FG(+1)
final double min_use_occl,// = 1.5; // Minimal FG/BG difference to use trimming by occlusions. For lower use only
final double temp_disparity, // = 3.0; // FG-BG disparity where weight of cost by obscuring equals weight of cost by temp
// debug arrays
final double [][][] debug_costs,
final int [][] debug_stats,
final int width,
final int transform_size){
// final double min_use_occl = 0.5 * temp_disparity; // add a separate parameter
final int min_sensors_bg = min_sensors; // maybe reduce? *=best_dir_frac?
final int num_slices = alpha_pix.length;
final int img_size = alpha_pix[0].length;
......@@ -4487,21 +4792,32 @@ public class TexturedModel {
final int tilesX = width/transform_size;
final int tilesY = img_size/width/transform_size;
final int tiles = tilesX * tilesY;
final int dbg_tile = -1; // 4123;
final int dbg_slice = 0;
final int dbg_tile = 1820; // -1; // 4123;
final int dbg_slice = 3; //0;
final int iradius = (int) Math.floor(temp_radius); // 1 - 3x3, 2 - 5x5
final double [][] rad_weights = new double [2 * iradius + 1][2 * iradius + 1];
for (int dY = -iradius; dY <= iradius; dY ++) {
for (int dX = -iradius; dX <= iradius; dX ++) {
rad_weights[dY + iradius][dX + iradius] =
Math.cos(0.5 * Math.PI * dY / temp_radius) *
Math.cos(0.5 * Math.PI * dX / temp_radius);
}
}
final Thread[] threads = ImageDtt.newThreadArray(THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
final AtomicInteger aplus = new AtomicInteger(0); // number of added opaque pixels
final AtomicInteger aminus = new AtomicInteger(0); // number of removed opaque pixels
final TileNeibs pn = new TileNeibs(width,height);
int num_modified_pixels = 0;
final int dbg_pix = -168170;
final int dbg_pix = 115680;
final boolean [][] new_alpha = new boolean[num_slices][img_size];
for (int nslice = 0; nslice < num_slices; nslice++) {
int fnslice = nslice;
System.arraycopy(alpha_pix[fnslice], 0, new_alpha[fnslice], 0, img_size);
if (debug_costs != null) {
debug_costs[fnslice] = new double [3][img_size]; // {cost, cost_fg, cost_bg}
debug_costs[fnslice] = new double [4][img_size]; // {cost, cost_fg, cost_bg, cost_temp}
for (int i = 0; i < debug_costs[fnslice].length; i++) {
Arrays.fill(debug_costs[fnslice][i], Double.NaN);
}
......@@ -4518,6 +4834,8 @@ public class TexturedModel {
if ((fnslice == dbg_slice) && (tile == dbg_tile )) {
System.out.println("updateFgAlpha().1 nslice="+fnslice+", tile="+tile);
}
double disparity_fg = slice_disparities[fnslice][tile];
double disparity_bg = Double.NaN;
if ( trim_tiles [fnslice][tile] &&
!tile_stitch[fnslice][tile]) {
int tileX = tile % tilesX;
......@@ -4531,8 +4849,8 @@ public class TexturedModel {
if ((ns != fnslice) &&
tile_keep[ns][tile] &&
!tile_stitch[fnslice][tile] && // ***
(slice_disparities[ns][tile] < slice_disparities[fnslice][tile]) &&
((slice_disparities[fnslice][tile] - slice_disparities[ns][tile]) > min_disp_diff )) {
(slice_disparities[ns][tile] < disparity_fg) &&
((disparity_fg - slice_disparities[ns][tile]) > min_disp_diff )) {
double [][] offs_bg = channel_pixel_offsets[ns][tile];
double [][] pixel_offs = new double [num_sens][2];
for (int nsens = 0; nsens < num_sens; nsens++) {
......@@ -4547,7 +4865,7 @@ public class TexturedModel {
for (int dx = 0; dx < transform_size; dx++) {
int px0 = tileX * transform_size + dx;
int pix = pix1 + dx;
if (pix==dbg_pix) {
if ((pix==dbg_pix) && (fnslice == dbg_slice)) {
System.out.println("updateFgAlpha().1 pix="+pix+", ns="+ns+", dx="+dx+", dy="+dy+
", disp_fg="+slice_disparities[fnslice][tile]+", disp_bg="+slice_disparities[ns][tile]);
}
......@@ -4595,11 +4913,14 @@ public class TexturedModel {
if (alpha_pix[ns][bg_pix] && !Double.isNaN(textures[ns][bg_pix])) { // null pointer
if (!(bg_disparity[dy][dx][nsens] >= slice_disparities[ns][tile])) { // was NaN -> true
bg_disparity[dy][dx][nsens] = slice_disparities[ns][tile];
if (!(disparity_bg <= bg_disparity[dy][dx][nsens])) {
disparity_bg = bg_disparity[dy][dx][nsens];
}
bg_value[dy][dx][nsens] = textures[ns][bg_pix];
if (pix==dbg_pix) {
if ((pix==dbg_pix) && (fnslice == dbg_slice)) {
System.out.println(String.format(
"%2d: bg_pix=%6d ibgx=%3d ibgy=%3d bg_value=%8.2f",
nsens, bg_pix, ibgx, ibgy, bg_value[dy][dx][nsens]));
"%2d: bg_pix=%6d ibgx=%3d ibgy=%3d", // bg_value=%8.2f bg_disparity=%8.2f",
nsens, bg_pix, ibgx, ibgy)); // , bg_value[dy][dx][nsens], bg_disparity[dy][dx]));
}
}
}
......@@ -4616,11 +4937,12 @@ public class TexturedModel {
// use bg_value[][][], bg_disparity[][][] to calculate bg weighths,
// calculate FG weights (same as VAR_INTER)
// add num neibs - 4 weight and make decisions
int this_clust = slice_clusters[fnslice][tile];
for (int dy = 0; dy < transform_size; dy++) {
int pix1 = pix0 + dy * width;
for (int dx = 0; dx < transform_size; dx++) {
int pix = pix1 + dx;
if (pix==dbg_pix) {
if ((pix==dbg_pix) && (fnslice == dbg_slice)) {
System.out.println("updateFgAlpha().2 pix="+pix);
}
if (trim_pix[fnslice][pix]) { // assign for all trim_pix
......@@ -4644,7 +4966,7 @@ public class TexturedModel {
int num_bg=0;
double s2_bg = 0;
for (int nsens = 0; nsens < (best_dir_number-1); nsens++ ) {
if (pix==dbg_pix) {
if ((pix==dbg_pix) && (fnslice == dbg_slice)) {
System.out.println(String.format(
"%2d: fg_value= %8.2f bg_value=%8.2f diff=%8.2f",
nsens,
......@@ -4652,13 +4974,16 @@ public class TexturedModel {
bg_value[dy][dx][nsens],
sensor_texture[fnslice][nsens][pix] - bg_value[dy][dx][nsens]));
}
if (((smask & (1 << nsens)) == 0) && (bg_disparity[dy][dx] != null) && !Double.isNaN(bg_disparity[dy][dx][nsens])) {
if ( ((smask & (1 << nsens)) == 0) &&
(bg_disparity[dy][dx] != null) &&
!Double.isNaN(bg_disparity[dy][dx][nsens])) {
double db = sensor_texture[fnslice][nsens][pix] - bg_value[dy][dx][nsens];
s2_bg += db * db;
num_bg ++;
}
}
double best_cost_bg = Double.NaN;
if (valid_bg) {
for (int i = 0; i < num_sens; i++ ) {
int nsens_plus = (best_dir_number + i - 1) % num_sens;
int nsens_minus = i;
......@@ -4699,6 +5024,71 @@ public class TexturedModel {
}
}
}
}
// calculate cost_temp
double cost_temp = Double.NaN;
double ddisp = disparity_fg - disparity_bg; // FG disparity minus largest BG one;
if ((iradius > 0) && !Double.isNaN(disparity_bg)) {
double sw_bg = 0.0, swd_bg = 0.0, sw_fg = 0.0, swd_fg = 0.0;
int num_tfg = 0, num_tbg=0; // number of defined
double fg_min = Double.NaN, fg_max = Double.NaN;
double bg_min = Double.NaN, bg_max = Double.NaN;
for (int tdy = -iradius; tdy <= iradius; tdy++) {
// skip center
for (int tdx = -iradius; tdx <= iradius; tdx++) if ((tdy != 0) || (tdx != 0)){
int tpix = pn.getNeibIndex(pix, tdx, tdy);
if ((tpix >= 0) && !Double.isNaN(textures[fnslice][tpix])){
// check it is the same cluster
int ttileX = (tpix % width) / transform_size;
int ttileY = (tpix / width) / transform_size;
if (slice_clusters[fnslice][ttileX + ttileY * tilesX] != this_clust) {
continue;
}
double w = rad_weights[tdy + iradius][tdx + iradius];
double d = textures[fnslice][tpix];
if (alpha_pix[fnslice][tpix]) {
sw_fg += w;
swd_fg += w * d;
num_tfg ++;
if (!(d <= fg_max)) fg_max = d;
if (!(d >= fg_min)) fg_min = d;
} else {
sw_bg += w;
swd_bg += w * d;
num_tbg ++;
if (!(d <= bg_max)) bg_max = d;
if (!(d >= bg_min)) bg_min = d;
}
}
}
} // for (int tdy = -iradius; tdy <= iradius; tdy++)
if ((num_tfg < temp_min) || (num_tbg < temp_min)) {
continue; // too few pixels to calculate
}
double avg_fg = swd_fg / sw_fg; // weighted average of the foreground neighbors
double avg_bg = swd_bg / sw_bg; // weighted average of the background neighbors
if (use_min_max) {
if (avg_fg > avg_bg) {
avg_fg = fg_max;
avg_bg = bg_min;
} else {
avg_fg = fg_min;
avg_bg = bg_max;
}
}
if (avg_bg == avg_fg) {
continue; // all the same pixels?
}
//
cost_temp = 2* (textures[fnslice][pix] - avg_bg)/(avg_fg - avg_bg) - 1; // -1..+1
}
// calculate costs
// maybe multiple backgrounds? Then combine them all
// each sensor - single BG - common array of 16?
......@@ -4725,11 +5115,28 @@ public class TexturedModel {
// positive for more opaque, negative - for more transparent
double cost_neibs = weight_neib * (n_opaque - 0.5* n_neibs);
double cost = Double.NaN;
if (Double.isNaN(cost_bg)) {
new_opaque = true;
double cost_occl = Double.NaN;
double scale_occl = (ddisp >= min_use_occl) ? ((ddisp - min_use_occl)/(ddisp - min_use_occl + temp_disparity )) : 0.0;
if (!Double.isNaN(cost_bg) &&
!Double.isNaN(cost_fg) &&
(ddisp >= min_use_occl)) {
cost_occl = weight_bg*cost_bg - cost_fg;
}
// for sufficient disparity differences - keep old method
// with no BG -> opaque.
if (Double.isNaN(cost_bg)) { // && (scale_occl > 0)) {
new_opaque = true; // there is no BG layer at all
} else {
// cost > 0 -> opaque, cost < 0 -> transparent
cost = weight_bg*cost_bg - cost_fg + cost_neibs;
cost = (scale_occl > 0) ? cost_occl: 0.0; // could be NaN
if (iradius > 0) {
cost *= scale_occl;
// ddisp
if (!Double.isNaN(cost_temp)) {
cost += temp_weight * cost_temp * (1.0 - scale_occl);
}
}
cost += cost_neibs;
if (Math.abs(cost) > cost_min) {
new_opaque = cost > 0;
new_transparent = cost < 0;
......@@ -4739,13 +5146,13 @@ public class TexturedModel {
debug_costs[fnslice][0][pix] = cost;
debug_costs[fnslice][1][pix] = cost_fg;
debug_costs[fnslice][2][pix] = cost_bg;
debug_costs[fnslice][3][pix] = cost_temp;
if (pix==dbg_pix) {
System.out.println(String.format(
"cost= %8.2f cost_neibs=%8.2f cost_fg=%8.2f cost_bg=%8.2f",
cost, cost_neibs, cost_fg, cost_bg));
"cost= %8.2f cost_neibs=%8.2f cost_fg=%8.2f cost_bg=%8.2f f cost_temp=%8.2f",
cost, cost_neibs, cost_fg, cost_bg, cost_temp));
}
}
} // if (num_vis >= min_sensors) {
}
} else { // if (!transparent[fnslice][indx] && !opaque[fnslice][indx]) {
......@@ -5179,6 +5586,7 @@ public class TexturedModel {
* layer of tiles around defined, 3 - stitch tiles closest
* to the edge of the cluster that has additional stitched
* ones
* @param slice_clusters [slice][tile] cluster indices, undefined are -1
* @param border_int_max maximal border level (currently ==2)
* @param sensor_texture [slice][sensor][pixel] - texture from the GPU output
* @param combo_texture_in [slice][pixel] - combined texture from all sensors. If null
......@@ -5199,6 +5607,7 @@ public class TexturedModel {
final int tilesX,
final double [][] slice_disparities,
final int [][] slice_border_int,
final int [][] slice_clusters,
final int border_int_max,
final double [][][] sensor_texture,
final double [][] combo_texture_in,
......@@ -5207,7 +5616,7 @@ public class TexturedModel {
final double min_trim_disparity, // = 2.0;
final TpTask[][][] tp_tasks_ref, // reference tasks for each slice to get offsets
final String dbg_prefix_in) {
// clt_parameters.batch_run
// clt_parameters.batch_run
final int max_neib_lev = clt_parameters.tex_max_neib_lev; // 2; // 1 - single tiles layer around, 2 - two layers
final double var_radius = clt_parameters.lre_var_radius; // 1.5; // 3.5; // for variance filter of the combo disparity
final double seed_inter = clt_parameters.lre_seed_inter; // 150; // 120; // 150;
......@@ -5245,6 +5654,16 @@ public class TexturedModel {
final double weight_bg = clt_parameters.lre_weight_bg; // 0.9; // 0.8; // 1.0; // 15.0/16; // 1.0; // weight of BG cost relative to the FG one
final double best_dir_frac = clt_parameters.lre_best_dir_frac; // 0.6; // for BG - use this fraction of all sensors in the best direction
final double cost_min = clt_parameters.lre_cost_min; // 1.0; // minimal absolute value of the total cost to make changes
//"Trimming by temperature (tone)
final boolean temp_use_min_max = clt_parameters.lre_use_min_max; // = true; // when trimming by tone, use min/max of the FG/BG instead of weighted averages
final double temp_radius = clt_parameters.lre_temp_radius; // 11.5; // How far to look around for FG trimming by temperature
final int temp_min = clt_parameters.lre_temp_min; // 2; // Minimal number of each of FG/BG while trimming by temperature
final double temp_weight = clt_parameters.lre_temp_weight; //20.0; // Multiply -1.0..+1.0 range of the current pixel between average BG(-1) and FG(+1)
final double min_use_occl= clt_parameters.lre_min_use_occl; // 1.5; // Minimal FG/BG difference to use trimming by occlusions. For lower use only
final double temp_disparity= clt_parameters.lre_temp_disparity;// 3.0; // FG-BG disparity where weight of cost by obscuring equals weight of cost by temp
final int max_trim_iterations = clt_parameters.lre_max_trim_iterations; // 10;
// debug images
final boolean show_debug = clt_parameters.lre_show_debug && !clt_parameters.multiseq_run; // true;
......@@ -5253,6 +5672,7 @@ public class TexturedModel {
final boolean show_textures_slice = clt_parameters.lre_show_textures_slice; // false; //true;
final boolean show_textures_combo = clt_parameters.lre_show_textures_combo; // false; //true;
final boolean show_textures_tiles = clt_parameters.lre_show_textures_tiles; // false; //true;
final int show_slice_bitmap = clt_parameters.lre_show_slice_bitmap;
final String dbg_prefix = show_debug ? dbg_prefix_in : null;
......@@ -5372,7 +5792,7 @@ public class TexturedModel {
seed_fom, // final double seed_fom, // minimal value of vars_inter/sqrt(vars_same)
seed_inter, // final double seed_inter, // = 150;
width); // final int width)
// copy unbound_alpha here for debug
// copy unbound_alpha here for debug
final boolean [][] trim_seeds = (dbg_prefix != null)? new boolean [num_slices][] : null;
if (dbg_prefix != null) {
......@@ -5494,7 +5914,7 @@ public class TexturedModel {
width, // final int width,
transform_size); // final int transform_size)
// Processing BG and FG trim
// Processing BG and FG trim
int [][] occluded_map = null;
int [][] occluded_map_enh = null;
double [][] dbg_occluded_map = null;
......@@ -5586,6 +6006,7 @@ public class TexturedModel {
}
}
// pass cluste indices
updated_tiles = updateFgAlpha(
channel_pixel_offsets, // final double [][][][] channel_pixel_offsets,
occluded_filled_textures, // final double [][] textures,
......@@ -5594,6 +6015,7 @@ public class TexturedModel {
occluded_map,// occluded_map_enh // final int [][] occluded_map, // bitmap of blocked by FG sensors
min_sensors, // final int min_sensors, // minimal number of sensors visible from the FG pixel
slice_disparities, // final double [][] slice_disparities,
slice_clusters, // final int [][] slice_clusters,// [slice][tile] index of cluster, do not mix different indices
tile_booleans[TILE_KEEP], // final boolean [][] tile_keep, // tiles that have at least one pixel
tile_booleans[TILE_STITCH], // final boolean [][] tile_stitch, // tiles that have at least one pixel
trim_tiles, // final boolean [][] trim_tiles, // tiles that have at least one pixel
......@@ -5608,6 +6030,13 @@ public class TexturedModel {
weight_bg, // final double weight_bg, // weight of BG cost relative to the FG one
best_dir_frac, // final double best_dir_frac, // for BG - use this fraction of all sensors in the best direction
cost_min, // final double cost_min, // minimal absolute value of the total cost to make changes
//"Trimming by temperature (tone)
temp_use_min_max, // final boolean use_min_max, // when trimming by tone, use min/max of the FG/BG instead of weighted averages
temp_radius, // final double temp_radius, // = 5.0; // How far to look around for FG trimming by temperature
temp_min, // final int temp_min, // = 2; // Minimal number of each of FG/BG while trimming by temperature
temp_weight, // final double temp_weight, // = 5.0; // Multiply -1.0..+1.0 range of the current pixel between average BG(-1) and FG(+1)
min_use_occl, // final double min_use_occl,// = 1.5; // Minimal FG/BG difference to use trimming by occlusions. For lower use only
temp_disparity, // final double temp_disparity, // = 3.0; // FG-BG disparity where weight of cost by obscuring equals weight of cost by temp
debug_costs, // final double [][] debug_cost, // if not null, should be double [nslices][] - will return costs/NaN
debug_stats, // final int [][] debug_stats, // if not null, should be int [nslices][] - will return number of added/removed per slice
width, // final int width,
......@@ -5628,32 +6057,43 @@ public class TexturedModel {
System.out.println (String.format("#%02d: %5d added, %5d removed (total %5d) opaque FG pixels",
nslice, debug_stats[nslice][0], debug_stats[nslice][1], debug_stats[nslice][0]+debug_stats[nslice][1]));
}
boolean [] dbg_this_slice = new boolean[num_slices];
int num_show_slices = 0;
for (int nslice = 0; nslice< num_slices; nslice++) {
if ((show_slice_bitmap & (1 << nslice)) != 0) {
num_show_slices++;
dbg_this_slice[nslice] = true;
}
}
if (num_show_slices > 0) {
String [] dbg_titles0 = {"sure","before","after", "cost", "cost_fg",
"cost_bg", "combo", "occluded-filed", "occluded"};
"cost_bg", "cost_temp", "combo", "occluded-filed", "occluded"};
int dbg_len = width * height;
int sublen = dbg_titles0.length;
String [] dbg_titles = new String [sublen * num_slices];
String [] dbg_titles = new String [sublen * num_show_slices];
double [][] dbg_img = new double [dbg_titles.length][];
for (int nslice = 0; nslice< num_slices; nslice++) {
int indx_slice = 0;
for (int nslice = 0; nslice< num_slices; nslice++) if (dbg_this_slice[nslice]){
for (int i = 0; i < dbg_titles0.length; i++) {
dbg_titles[nslice * sublen + i] = dbg_titles0[i]+"-"+nslice;
dbg_titles[indx_slice * sublen + i] = dbg_titles0[i]+"-"+nslice;
}
dbg_img[nslice * sublen + 0] = new double [dbg_len];
dbg_img[nslice * sublen + 1] = new double [dbg_len];
dbg_img[nslice * sublen + 2] = new double [dbg_len];
dbg_img[indx_slice * sublen + 0] = new double [dbg_len];
dbg_img[indx_slice * sublen + 1] = new double [dbg_len];
dbg_img[indx_slice * sublen + 2] = new double [dbg_len];
for (int i = 0; i < dbg_len; i++) {
dbg_img[nslice * sublen + 0][i] =
dbg_img[indx_slice * sublen + 0][i] =
(sure_transparent[nslice][i]? 0 : 1) + (sure_opaque[nslice][i]? 2 : 0);
dbg_img[nslice * sublen + 1][i] = (debug_alpha[nslice][i]? 3 : 0);
dbg_img[nslice * sublen + 2][i] = (unbound_alpha[nslice][i]? 3 : 0);
}
dbg_img[nslice * sublen + 3] = debug_costs[nslice][0];
dbg_img[nslice * sublen + 4] = debug_costs[nslice][1];
dbg_img[nslice * sublen + 5] = debug_costs[nslice][2];
dbg_img[nslice * sublen + 6] = gcombo_texture[nslice];
dbg_img[nslice * sublen + 7] = occluded_filled_textures[nslice];
dbg_img[nslice * sublen + 8] = occluded_textures[nslice];
dbg_img[indx_slice * sublen + 1][i] = (debug_alpha[nslice][i]? 3 : 0);
dbg_img[indx_slice * sublen + 2][i] = (unbound_alpha[nslice][i]? 3 : 0);
}
dbg_img[indx_slice * sublen + 3] = debug_costs[nslice][0];
dbg_img[indx_slice * sublen + 4] = debug_costs[nslice][1];
dbg_img[indx_slice * sublen + 5] = debug_costs[nslice][2];
dbg_img[indx_slice * sublen + 6] = debug_costs[nslice][3];
dbg_img[indx_slice * sublen + 7] = gcombo_texture[nslice];
dbg_img[indx_slice * sublen + 8] = occluded_filled_textures[nslice];
dbg_img[indx_slice * sublen + 9] = occluded_textures[nslice];
indx_slice++;
}
ShowDoubleFloatArrays.showArrays(
dbg_img,
......@@ -5662,9 +6102,33 @@ public class TexturedModel {
true,
dbg_prefix+"-update_fg-"+niter, // +nslice,
dbg_titles);
}
System.out.println("updateFgAlpha() -> "+updated_tiles);
}
}
double [][] alphas = new double[num_slices][];
for (int nslice = 0; nslice < num_slices; nslice++) {
// replace old alpha with the new binary one
alphas[nslice] = new double [unbound_alpha[nslice].length];
for (int i = 0; i < unbound_alpha[nslice].length; i++) {
alphas[nslice][i] = unbound_alpha[nslice][i] ? 1.0 : 0.0;
}
}
final int shrink_sky_tiles = 2 * (2 +clt_parameters.tex_sky_extra); // 4; // 2; sum of 2 +bg extend
final boolean grow_sky = true;
if (grow_sky) {
// occluded_filled_textures
extendBlueSKy(
tileClusters, // final TileCluster [] tileClusters,
occluded_textures, // final double [][][] textures_occluded,
alphas, // final double [][] alphas,
occluded_filled_textures, // final double [][][] textures_final,
shrink_sky_tiles, // final int shrink_sky_tiles,
width, // final int width,
transform_size, // final int transform_size);
dbg_prefix); // dbg_prefix); // final String dbg_prefix)
}
if (dbg_alpha_mods != null) {
// TODO:
......@@ -5689,7 +6153,7 @@ public class TexturedModel {
dbg_prefix+"-update_fg-alpha", // +nslice,
dbg_titles);
}
/*
double [][] alphas = new double[num_slices][];
for (int nslice = 0; nslice < num_slices; nslice++) {
// replace old alpha with the new binary one
......@@ -5698,9 +6162,10 @@ public class TexturedModel {
alphas[nslice][i] = unbound_alpha[nslice][i] ? 1.0 : 0.0;
}
}
*/
if ((dbg_prefix != null) && show_textures_slice) {
for (int nslice = 0; nslice < num_slices; nslice++) {
for (int nslice = 0; nslice < num_slices; nslice++) if ((show_slice_bitmap & (1 << nslice))!= 0) {
final double [] vars_ratio = new double [img_size];
final double [] vars_fom = new double [img_size]; // inter/sqrt(same)
final double [] half_pix = new double [img_size];
......@@ -5877,16 +6342,22 @@ public class TexturedModel {
double [][][] textures_alphas = new double [num_slices][][];
for (int nslice = 0; nslice < num_slices; nslice++) {
alphas[nslice] = new double [unbound_alpha[nslice].length];
for (int i = 0; i < unbound_alpha[nslice].length; i++) {
alphas[nslice][i] = unbound_alpha[nslice][i] ? 1.0 : 0.0;
}
// alphas[nslice] = new double [unbound_alpha[nslice].length];
// for (int i = 0; i < unbound_alpha[nslice].length; i++) {
// alphas[nslice][i] = unbound_alpha[nslice][i] ? 1.0 : 0.0;
// }
textures_alphas[nslice] = new double [][] {occluded_filled_textures[nslice], alphas[nslice]};
}
// set slice_disparities to NaN for unselected tiles - it will update tileClusters
setMeshTileSelection(
slice_disparities, // final double [][] slice_disparities,
tile_booleans[TILE_KEEP]); //final boolean [][] keep_tiles)
setBlueSkyDisparity( // to be used during triangulation
tileClusters, // final TileCluster [] tileClusters,
slice_disparities, // final double [][] slice_disparities,
tilesX); // final int tilesX)
String dbg_prefix1 = (dbg_prefix==null)? null: (dbg_prefix+"-masked");
if ((dbg_prefix1!=null) && show_textures_tiles) {
showDebugDisparities( // nop if dbg_prefix== null
......@@ -5963,9 +6434,10 @@ public class TexturedModel {
final int tex_hist_bins = clt_parameters.tex_hist_bins; // 1024 ;
final int tex_hist_segments = clt_parameters.tex_hist_segments; // 32 ;
final boolean show_sky_textures = clt_parameters.lre_show_sky_textures && !clt_parameters.multiseq_run;
final int shrink_sky_tiles = 4; // 2; sum of 2 +bg extend
final boolean grow_sky = true;
// final boolean show_sky_textures = clt_parameters.lre_show_sky_textures && !clt_parameters.multiseq_run;
// final int show_slice_bitmap = clt_parameters.lre_show_slice_bitmap;
// final int shrink_sky_tiles = 2 * (2 +clt_parameters.tex_sky_extra); // 4; // 2; sum of 2 +bg extend
// final boolean grow_sky = true;
final boolean alphaOverlapFix = true; // if multiple tiles have the same (+/-?) disparity, make alpha max of them
final double alphaOverlapTolerance = 0.0; // compare same disparity with tolerance (relative to disparity? make absolute meters?)
ImageDtt image_dtt;
......@@ -6209,10 +6681,13 @@ public class TexturedModel {
} // for (int nslice = 0; nslice < num_slices; nslice++) {
final double [][] slice_disparities = new double [num_slices][];
final int [][] slice_border_int = new int [num_slices][];
final int [][] slice_border_int = new int [num_slices][]; // final int [][] slice_clusters,
final int [][] slice_clusters = new int [num_slices][];
for (int nslice = 0; nslice < num_slices; nslice++) {
slice_disparities[nslice] = tileClusters[nslice].getDisparity(); // disparity in the reference view tiles (Double.NaN - invalid)
slice_border_int[nslice] = tileClusters[nslice].getBorderInt();
slice_clusters[nslice] = tileClusters[nslice].getClusterIndex();
}
int border_int_max = tileClusters[0].getBorderIntMax();
double [][][] faded_textures = processTexture( //[slice]{texture, alpha}
......@@ -6220,6 +6695,7 @@ public class TexturedModel {
tilesX, // final int tilesX,
slice_disparities, // final double [][] slice_disparities,
slice_border_int, // final int [][] slice_border_int,
slice_clusters, // final int [][] slice_clusters,
border_int_max, // final int border_int_max,
sensor_textures, // final double [][] sensor_texture, // per-sensor texture value
null, // combo_textures, // null, // final double [] combo_texture_in, // average texture value
......@@ -6249,7 +6725,8 @@ public class TexturedModel {
dbg_titles);
}
// Grow sky
// Grow sky - moved to processTexture()
/*
if (grow_sky) {
String dbg_prefix = show_sky_textures ? ref_scene.getImageName() : null;
......@@ -6261,6 +6738,7 @@ public class TexturedModel {
transform_size, // final int transform_size);
dbg_prefix); // dbg_prefix); // final String dbg_prefix)
}
*/
// fix alpha
if (alphaOverlapFix) {
fixAlphaSameDisparity(
......@@ -6271,7 +6749,8 @@ public class TexturedModel {
transform_size); // final int transform_size)
}
// Is it needed here? Or move to processTexture()? - Slow
// Is it needed here? Or move to processTexture()?
// it is needed before Gaussian blur which extends NaN
for (int nslice = 0; nslice < faded_textures.length; nslice++) {
faded_textures[nslice][0] = TileProcessor.fillNaNs(
faded_textures[nslice][0], // final double [] data,
......@@ -6280,11 +6759,11 @@ public class TexturedModel {
16, // final int grow,
0.7, // double diagonal_weight, // relative to ortho
100, // int num_passes,
0.01, // final double max_rchange, // = 0.01
0.03, // final double max_rchange, // = 0.01 - does not need to be accurate
THREADS_MAX); // final int threadsMax) // maximal number of threads to launch
}
if (debugLevel > -1) {
if (debugLevel > -2) {
double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length];
String [] dbg_titles = new String[dbg_textures.length];
String [] dbg_subtitles = new String [faded_textures[0].length];
......@@ -6307,15 +6786,18 @@ public class TexturedModel {
}
// Optionally apply UM (before auto/manual range)
final boolean um_ignore_alpha = true;
final boolean hist_ignore_alpha = true;
if (tex_um) {
QuadCLTCPU.umTextures(
faded_textures, // final double [][][] textures, // [nslices][nchn][i]
tilesX * transform_size, // final int width,
um_ignore_alpha, // final boolean ignore_alpha,
tex_um_sigma, // final double um_sigma,
tex_um_weight); // final double um_weight)
}
if (debugLevel > -1) {
if (debugLevel > -2) {
double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length];
String [] dbg_titles = new String[dbg_textures.length];
String [] dbg_subtitles = new String [faded_textures[0].length];
......@@ -6403,13 +6885,14 @@ public class TexturedModel {
norm_table, // double [] direct_table, // last is <1.0, first > 0
tex_hist_bins); // int num_bins)
QuadCLTCPU.applyTexturesNormHist(
hist_ignore_alpha, // final boolean ignore_alpha
faded_textures, // final double [][][] textures, // [nslices][nchn][i]
cold_hot, // final double [] min_max,
inverted_table); // final double [] inv_table)
}
if (debugLevel > -1) {
if (debugLevel > -2) {
double [][] dbg_textures = new double [faded_textures.length * faded_textures[0].length][faded_textures[0][0].length];
String [] dbg_titles = new String[dbg_textures.length];
String [] dbg_subtitles = new String [faded_textures[0].length];
......@@ -6466,6 +6949,9 @@ public class TexturedModel {
int transform_size,
int debugLevel)
{
if (debugLevel > -2) {
System.out.println("getInterCombinedTextures()m no_alpha=" + no_alpha); // true
}
final boolean tex_color = clt_parameters.tex_color; // true;
final int tex_palette = clt_parameters.tex_palette; // 2 ;
int num_slices = faded_textures.length;
......@@ -6542,7 +7028,7 @@ public class TexturedModel {
int cluster_index = indices[i];
String title=String.format("%s-img%04d-texture",basename, cluster_index);
tex_clusters[cluster_index] = new ImagePlus(title, sub_stack);
// tex_clusters[cluster_index].getProcessor().resetMinAndMax(); // probably not needed for png
// tex_clusters[cluster_index].getProcessor().resetMinAndMax(); // probably not needed for png
}
}
return tex_clusters;
......
......@@ -269,7 +269,7 @@ class TileCluster{
return sub_indices;
}
}
public void resetClusterIndex() { // to rebuild cluster index from disparity
public void resetClusterIndex() { // to rebuild cluster index from disparity NOT USED
this.cluster_index = null;
}
public int [] getClusterIndex() { // (Now not) just a debug feature, no need to optimize?
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment