Commit 440719d9 authored by Andrey Filippov's avatar Andrey Filippov

Working snapshot, will add selective disabling of terrain, vegetatio,

alpha adjustment
parent e72b18ee
......@@ -742,6 +742,14 @@ min_str_neib_fpn 0.35
public int terr_min_total_scenes = 2;
public int terr_min_pixels = 10;
public boolean terr_warm_veget = true; // start with vegetation warmer than terrain
public double terr_warmest = 90.0; // above - vegetation. below - terrain
public double terr_initial_split = 0.1; // initial alpha: terrain 0.0+, vegetation 1.0-
public double terr_min_split_frac = 0.15; // minimal modality fraction to use split by temperature
public double terr_difference = 100.0; // vegetation is 100 warmer (target)
public double terr_pull_cold = 0.001; // pull vegetations to warm, terrain to cold
public double terr_alpha_dflt = 0.5;
public double terr_alpha_loss = 100.0;
public double terr_alpha_offset = 0.0;
......@@ -761,6 +769,7 @@ min_str_neib_fpn 0.35
// LMA parameters
public double terr_boost_parallax = 3.0; //
public double terr_max_parallax = 10.0; // parallax limit when evaluating boost parallax
public double terr_hifreq_weight = 10.0; // 22.5; // 0 - do not use high-freq. Relative weight of laplacian components differfences to the DC ones
public double terr_reg_weights = 0.25; // fraction of the total weight used for regularization
public double terr_lambda = 5.0; //
public double terr_lambda_scale_good = 0.5;
......@@ -1980,6 +1989,12 @@ min_str_neib_fpn 0.35
gd.addNumericField("Minimal samples/scene",terr_min_samples_scene, 0,3,"","Minimal samples per scene used for fitting (skip scene if less).");
gd.addNumericField("Minimum scenes used", terr_min_total_scenes, 0,3,"", "Minimal total number of scenes used (skip segment if less).");
gd.addNumericField("Minimal pixels fitted",terr_min_pixels, 0,3,"", "Minimal number of terrain and vegetation pixels used for fitting in this segment(skip segment if less).");
gd.addCheckbox ("Start by temperature", terr_warm_veget, "Start with vegetation warmer than terrain.");
gd.addNumericField("Warmest terrain", terr_warmest, 5,7,"", "Above - vegetation. below - terrain.");
gd.addNumericField("Initial split", terr_initial_split, 5,7,"", "Initial alpha: terrain 0.0+, vegetation 1.0-.");
gd.addNumericField("Min. split fraction", terr_min_split_frac, 5,7,"", "minimal modality fraction to use split by temperature (otherwise use default alpha).");
gd.addNumericField("Vegetation warmer", terr_difference, 5,7,"", "Pull vegetation to be this warmer.");
gd.addNumericField("Pull terrain cold", terr_pull_cold, 5,7,"", "Pull vegetations to warm, terrain to cold.");
gd.addNumericField("Defalt alpha", terr_alpha_dflt, 5,7,"", "Default vegetation alpha.");
gd.addNumericField("Alpha loss", terr_alpha_loss, 5,7,"", "Alpha quadratic growing loss for when out of [0,1] range");
gd.addNumericField("Alpha offset", terr_alpha_offset, 5,7,"", "Start alpha losses above 0.0 and below 1.0 by this value.");
......@@ -1999,6 +2014,8 @@ min_str_neib_fpn 0.35
gd.addMessage ("LMA parameters");
gd.addNumericField("Boost parallax", terr_boost_parallax, 5,7,"", "Increase weight of scenes that have high parallax to the reference one.");
gd.addNumericField("Limit parallax", terr_max_parallax, 5,7,"", "Parallax limit when evaluating boost parallax.");
gd.addNumericField("High freq. weight", terr_hifreq_weight, 5,7,"", "Relative weight of laplacian components differfences to the DC ones (0 - do not use).");
gd.addNumericField("Losses weight", terr_reg_weights, 5,7,"", "Fraction of other losses compared to the RMSE.");
gd.addNumericField("Initial lambda", terr_lambda, 5,7,"", "Initial LMA lambda.");
gd.addNumericField("Lambda scale on good", terr_lambda_scale_good, 5,7,"","Scale lambda if RMSE improved.");
......@@ -2663,7 +2680,12 @@ min_str_neib_fpn 0.35
terr_min_samples_scene=(int) gd.getNextNumber();// int
terr_min_total_scenes=(int) gd.getNextNumber();// int
terr_min_pixels = (int) gd.getNextNumber();// int
terr_warm_veget = gd.getNextBoolean();// boolean
terr_warmest = gd.getNextNumber();// double
terr_initial_split = gd.getNextNumber();// double
terr_min_split_frac = gd.getNextNumber();// double
terr_difference = gd.getNextNumber();// double
terr_pull_cold = gd.getNextNumber();// double
terr_alpha_dflt = gd.getNextNumber();// double
terr_alpha_loss = gd.getNextNumber();// double
terr_alpha_offset = gd.getNextNumber();// double
......@@ -2683,6 +2705,7 @@ min_str_neib_fpn 0.35
terr_boost_parallax = gd.getNextNumber();// double
terr_max_parallax = gd.getNextNumber();// double
terr_hifreq_weight = gd.getNextNumber();// double
terr_reg_weights = gd.getNextNumber();// double
terr_lambda = gd.getNextNumber();// double
terr_lambda_scale_good = gd.getNextNumber();// double
......@@ -3316,6 +3339,13 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"terr_min_samples_scene", terr_min_samples_scene+""); // int
properties.setProperty(prefix+"terr_min_total_scenes", terr_min_total_scenes+""); // int
properties.setProperty(prefix+"terr_min_pixels", terr_min_pixels+""); // int
properties.setProperty(prefix+"terr_warm_veget", terr_warm_veget+""); // boolean
properties.setProperty(prefix+"terr_warmest", terr_warmest+""); // double
properties.setProperty(prefix+"terr_initial_split", terr_initial_split+""); // double
properties.setProperty(prefix+"terr_min_split_frac", terr_min_split_frac+""); // double
properties.setProperty(prefix+"terr_difference", terr_difference+""); // double
properties.setProperty(prefix+"terr_pull_cold", terr_pull_cold+""); // double
properties.setProperty(prefix+"terr_alpha_dflt", terr_alpha_dflt+""); // double
properties.setProperty(prefix+"terr_alpha_loss", terr_alpha_loss+""); // double
properties.setProperty(prefix+"terr_alpha_offset", terr_alpha_offset+""); // double
......@@ -3333,6 +3363,7 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"terr_boost_parallax", terr_boost_parallax+""); // double
properties.setProperty(prefix+"terr_max_parallax", terr_max_parallax+""); // double
properties.setProperty(prefix+"terr_hifreq_weight", terr_hifreq_weight+""); // double
properties.setProperty(prefix+"terr_reg_weights", terr_reg_weights+""); // double
properties.setProperty(prefix+"terr_lambda", terr_lambda+""); // double
properties.setProperty(prefix+"terr_lambda_scale_good", terr_lambda_scale_good+""); // double
......@@ -3989,6 +4020,13 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"terr_min_samples_scene")!= null) terr_min_samples_scene=Integer.parseInt(properties.getProperty(prefix+"terr_min_samples_scene"));
if (properties.getProperty(prefix+"terr_min_total_scenes")!= null) terr_min_total_scenes=Integer.parseInt(properties.getProperty(prefix+"terr_min_total_scenes"));
if (properties.getProperty(prefix+"terr_min_pixels")!= null) terr_min_pixels=Integer.parseInt(properties.getProperty(prefix+"terr_min_pixels"));
if (properties.getProperty(prefix+"terr_warm_veget")!= null) terr_warm_veget=Boolean.parseBoolean(properties.getProperty(prefix+"terr_warm_veget"));
if (properties.getProperty(prefix+"terr_warmest")!= null) terr_warmest=Double.parseDouble(properties.getProperty(prefix+"terr_warmest"));
if (properties.getProperty(prefix+"terr_initial_split")!= null) terr_initial_split=Double.parseDouble(properties.getProperty(prefix+"terr_initial_split"));
if (properties.getProperty(prefix+"terr_min_split_frac")!= null) terr_min_split_frac=Double.parseDouble(properties.getProperty(prefix+"terr_min_split_frac"));
if (properties.getProperty(prefix+"terr_difference")!= null) terr_difference=Double.parseDouble(properties.getProperty(prefix+"terr_difference"));
if (properties.getProperty(prefix+"terr_pull_cold")!= null) terr_pull_cold=Double.parseDouble(properties.getProperty(prefix+"terr_pull_cold"));
if (properties.getProperty(prefix+"terr_alpha_dflt")!= null) terr_alpha_dflt=Double.parseDouble(properties.getProperty(prefix+"terr_alpha_dflt"));
if (properties.getProperty(prefix+"terr_alpha_loss")!= null) terr_alpha_loss=Double.parseDouble(properties.getProperty(prefix+"terr_alpha_loss"));
if (properties.getProperty(prefix+"terr_alpha_offset")!= null) terr_alpha_offset=Double.parseDouble(properties.getProperty(prefix+"terr_alpha_offset"));
......@@ -4007,6 +4045,8 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"terr_boost_parallax")!= null) terr_boost_parallax=Double.parseDouble(properties.getProperty(prefix+"terr_boost_parallax"));
if (properties.getProperty(prefix+"terr_max_parallax")!= null) terr_max_parallax=Double.parseDouble(properties.getProperty(prefix+"terr_max_parallax"));
//
if (properties.getProperty(prefix+"terr_hifreq_weight")!= null) terr_hifreq_weight=Double.parseDouble(properties.getProperty(prefix+"terr_hifreq_weight"));
if (properties.getProperty(prefix+"terr_reg_weights")!= null) terr_reg_weights=Double.parseDouble(properties.getProperty(prefix+"terr_reg_weights"));
if (properties.getProperty(prefix+"terr_lambda")!= null) terr_lambda=Double.parseDouble(properties.getProperty(prefix+"terr_lambda"));
if (properties.getProperty(prefix+"terr_lambda_scale_good")!= null) terr_lambda_scale_good=Double.parseDouble(properties.getProperty(prefix+"terr_lambda_scale_good"));
......@@ -4630,6 +4670,12 @@ min_str_neib_fpn 0.35
imp.terr_min_samples_scene = this.terr_min_samples_scene;
imp.terr_min_total_scenes = this.terr_min_total_scenes;
imp.terr_min_pixels = this.terr_min_pixels;
imp.terr_warm_veget = this.terr_warm_veget;
imp.terr_warmest = this.terr_warmest;
imp.terr_initial_split = this.terr_initial_split;
imp.terr_min_split_frac = this.terr_min_split_frac;
imp.terr_difference = this.terr_difference;
imp.terr_pull_cold = this.terr_pull_cold;
imp.terr_alpha_dflt = this.terr_alpha_dflt;
imp.terr_alpha_loss = this.terr_alpha_loss;
imp.terr_alpha_offset = this.terr_alpha_offset;
......@@ -4647,7 +4693,8 @@ min_str_neib_fpn 0.35
imp.terr_veget_pull0 = this.terr_veget_pull0;
imp.terr_boost_parallax = this.terr_boost_parallax;
imp.terr_max_parallax = this.terr_max_parallax;
imp.terr_max_parallax = this.terr_max_parallax;
imp.terr_hifreq_weight = this.terr_hifreq_weight;
imp.terr_reg_weights = this.terr_reg_weights;
imp.terr_lambda = this.terr_lambda;
imp.terr_lambda_scale_good = this.terr_lambda_scale_good;
......
......@@ -602,9 +602,9 @@ public class OpticalFlow {
* @param tolerance_relative Relative to the average disparity part of the disparity filtering.
* @param scene_macrotile_occupancy Skip scene macrotile if less than this fraction of all tiles in a macrotile remain
* after filtering.
* @param num_laplassian Number of Laplassian passes while replacing undefined (NaN) tiles from neighbors for reference and scene
* @param num_laplacian Number of Laplacian passes while replacing undefined (NaN) tiles from neighbors for reference and scene
* macrotiles.
* @param change_laplassian Break the loop of Laplassian passes if the maximal absolute value of the last pass changes falls below
* @param change_laplacian Break the loop of Laplacian passes if the maximal absolute value of the last pass changes falls below
* this threshold.
* @param chn_weights A 4-element array of the correlation weights for strength, red, blue and green channels
* @param corr_sigma A low-pass sigma for the 2-d correlation (in tiles)
......@@ -644,8 +644,8 @@ public class OpticalFlow {
final double tolerance_absolute, // absolute disparity half-range in each tile
final double tolerance_relative, // relative disparity half-range in each tile
final double scene_macrotile_occupancy, // fraction of remaining tiles (<1.0)
final int num_laplassian,
final double change_laplassian,
final int num_laplacian,
final double change_laplacian,
// for correlate2DSceneToReference ()
final double [] chn_weights, // absolute, starting from strength (strength,r,b,g)
final double corr_sigma,
......@@ -693,8 +693,8 @@ public class OpticalFlow {
fillTilesNans(
reference_tiles, // final double [][][] nan_tiles,
reference_QuadClt, // final QuadCLT qthis,
num_laplassian, // final int num_passes,
change_laplassian, // final double max_change,
num_laplacian, // final int num_passes,
change_laplacian, // final double max_change,
-1); //-1); // 2); // final int debug_level)
if (reference_tiles_macro != null) {
double [][] macro_centers = getMacroPxPyDisp(
......@@ -729,8 +729,8 @@ public class OpticalFlow {
tolerance_absolute, // final double tolerance_absolute, // absolute disparity half-range in each tile
tolerance_absolute, // final double tolerance_relative, // relative disparity half-range in each tile
tolerance_relative, // final double occupancy, // fraction of remaining tiles (<1.0)
num_laplassian, // final int num_passes,
change_laplassian, // final double max_change,
num_laplacian, // final int num_passes,
change_laplacian, // final double max_change,
-1); //-1); // 1); // 2); // final int debug_level)
// undefine tiles in flowXY that are never used
if (ntry == 0) {
......@@ -1579,7 +1579,7 @@ public class OpticalFlow {
* @param tolerance_relative Additional component of the disparity tolerance proportional to the reference macrotile disparity.
* @param occupancy Skip scene macrotiles having less remaining tiles fraction of all tiles.
* @param num_passes Number of Laplacian passes to fill filtered by disparity tiles.
* @param max_change Break the loop of Laplassian passes if the maximal absolute value of the last pass changes falls below
* @param max_change Break the loop of Laplacian passes if the maximal absolute value of the last pass changes falls below
* this threshold.
* @param debug_level Debug level.
* @return Scene macrotiles - double array [number_of_macrotiles][number_of_channels][numer_of_tiles_per_macrotile], typically
......@@ -5766,7 +5766,7 @@ public class OpticalFlow {
disparity_bg = ds_bg[0]; // combo_dsn_final[COMBO_DSN_INDX_DISP_FG];
strength_bg = ds_bg[1];
// for now using disparity for just standard size (90x64), later may use full size and at
// minimum fill peripheral areas with Laplassian?
// minimum fill peripheral areas with Laplacian?
double [][] dxyzatr_dt = new double [quadCLTs.length][];
int [][] min_max_vel = getERSStats(
clt_parameters, // CLTParameters clt_parameters,
......@@ -13167,8 +13167,8 @@ public class OpticalFlow {
clt_parameters.ofp.tolerance_absolute_inter, // final double tolerance_absolute, // absolute disparity half-range in each tile
clt_parameters.ofp.tolerance_relative_inter, // final double tolerance_relative, // relative disparity half-range in each tile
clt_parameters.ofp.occupancy_inter, // final double occupancy, // fraction of remaining tiles (<1.0)
clt_parameters.ofp.num_laplassian, // final int num_passes,
clt_parameters.ofp.change_laplassian, // final double max_change,
clt_parameters.ofp.num_laplacian, // final int num_passes,
clt_parameters.ofp.change_laplacian, // final double max_change,
// for correlate2DSceneToReference ()
clt_parameters.ofp.chn_weights, // final double [] chn_weights, // absolute, starting from strength (strength,r,b,g)
clt_parameters.ofp.corr_sigma, // final double corr_sigma,
......@@ -13656,8 +13656,8 @@ public class OpticalFlow {
clt_parameters.ofp.tolerance_absolute_inter, // final double tolerance_absolute, // absolute disparity half-range in each tile
clt_parameters.ofp.tolerance_relative_inter, // final double tolerance_relative, // relative disparity half-range in each tile
clt_parameters.ofp.occupancy_inter, // final double occupancy, // fraction of remaining tiles (<1.0)
clt_parameters.ofp.num_laplassian, // final int num_passes,
clt_parameters.ofp.change_laplassian, // final double max_change,
clt_parameters.ofp.num_laplacian, // final int num_passes,
clt_parameters.ofp.change_laplacian, // final double max_change,
// for correlate2DSceneToReference ()
clt_parameters.ofp.chn_weights, // final double [] chn_weights, // absolute, starting from strength (strength,r,b,g)
clt_parameters.ofp.corr_sigma, // final double corr_sigma,
......@@ -13950,8 +13950,8 @@ public class OpticalFlow {
clt_parameters.ofp.tolerance_absolute_inter, // final double tolerance_absolute, // absolute disparity half-range in each tile
clt_parameters.ofp.tolerance_relative_inter, // final double tolerance_relative, // relative disparity half-range in each tile
clt_parameters.ofp.occupancy_inter, // final double occupancy, // fraction of remaining tiles (<1.0)
clt_parameters.ofp.num_laplassian, // final int num_passes,
clt_parameters.ofp.change_laplassian, // final double max_change,
clt_parameters.ofp.num_laplacian, // final int num_passes,
clt_parameters.ofp.change_laplacian, // final double max_change,
// for correlate2DSceneToReference ()
clt_parameters.ofp.chn_weights, // final double [] chn_weights, // absolute, starting from strength (strength,r,b,g)
clt_parameters.ofp.corr_sigma, // final double corr_sigma,
......@@ -13992,8 +13992,8 @@ public class OpticalFlow {
fillTilesNans(
reference_tiles, // final double [][][] nan_tiles,
reference_QuadCLT, // final QuadCLT qthis,
clt_parameters.ofp.num_laplassian, // num_passes, // final int num_passes,
clt_parameters.ofp.change_laplassian, // max_change, // final double max_change,
clt_parameters.ofp.num_laplacian, // num_passes, // final int num_passes,
clt_parameters.ofp.change_laplacian, // max_change, // final double max_change,
-1); //-1); // 2); // final int debug_level)
......@@ -14009,8 +14009,8 @@ public class OpticalFlow {
clt_parameters.ofp.tolerance_absolute_inter, // final double tolerance_absolute, // absolute disparity half-range in each tile
clt_parameters.ofp.tolerance_relative_inter, // final double tolerance_relative, // relative disparity half-range in each tile
clt_parameters.ofp.occupancy_inter, // final double occupancy, // fraction of remaining tiles (<1.0)
clt_parameters.ofp.num_laplassian, // num_passes, // final int num_passes,
clt_parameters.ofp.change_laplassian, // max_change, // final double max_change,
clt_parameters.ofp.num_laplacian, // num_passes, // final int num_passes,
clt_parameters.ofp.change_laplacian, // max_change, // final double max_change,
-1); //-1); // 1); // 2); // final int debug_level)
String dbg_title = "flowXY_frac-"+scene_QuadCLT.getImageName()+"-"+reference_QuadCLT.getImageName();
......@@ -14129,8 +14129,8 @@ public class OpticalFlow {
clt_parameters.ofp.tolerance_absolute_inter, // final double tolerance_absolute, // absolute disparity half-range in each tile
clt_parameters.ofp.tolerance_relative_inter, // final double tolerance_relative, // relative disparity half-range in each tile
clt_parameters.ofp.occupancy_inter, // final double occupancy, // fraction of remaining tiles (<1.0)
clt_parameters.ofp.num_laplassian, // num_passes, // final int num_passes,
clt_parameters.ofp.change_laplassian, // max_change, // final double max_change,
clt_parameters.ofp.num_laplacian, // num_passes, // final int num_passes,
clt_parameters.ofp.change_laplacian, // max_change, // final double max_change,
1); //-1); // 1); // 2); // final int debug_level)
// single, late
......@@ -14212,8 +14212,8 @@ public class OpticalFlow {
clt_parameters.ofp.tolerance_absolute_inter, // final double tolerance_absolute, // absolute disparity half-range in each tile
clt_parameters.ofp.tolerance_relative_inter, // final double tolerance_relative, // relative disparity half-range in each tile
clt_parameters.ofp.occupancy_inter, // final double occupancy, // fraction of remaining tiles (<1.0)
clt_parameters.ofp.num_laplassian, // num_passes, // final int num_passes,
clt_parameters.ofp.change_laplassian, // max_change, // final double max_change,
clt_parameters.ofp.num_laplacian, // num_passes, // final int num_passes,
clt_parameters.ofp.change_laplacian, // max_change, // final double max_change,
1); //-1); // 1); // 2); // final int debug_level)
}
......
......@@ -34,8 +34,8 @@ public class OpticalFlowParameters {
public double tolerance_absolute_ref = 0.25; // absolute disparity half-range in each tile
public double tolerance_relative_ref = 0.2; // relative disparity half-range in each tile
public double center_occupancy_ref = 0.25; // fraction of remaining tiles in the center 8x8 area (<1.0)
public int num_laplassian = 100;
public double change_laplassian = 0.005 ;
public int num_laplacian = 100;
public double change_laplacian = 0.005 ;
public double tolerance_absolute_inter = 0.25; // absolute disparity half-range in each tile
public double tolerance_relative_inter = 0.2; // relative disparity half-range in each tile
public double occupancy_inter = 0.25; // fraction of remaining tiles in the center 8x8 area (<1.0)
......@@ -99,9 +99,9 @@ public class OpticalFlowParameters {
"Filter reference scene tiles in a macrotile by disparity (relative to disparity)");
gd.addNumericField("Minimal fraction of disparity-compliant tiles in the reference center", this.center_occupancy_ref, 4,6,"",
"Discard reference macrotile with less fraction of remaining tiles after filtering by the same disparity in the center 8x8 of the 16x16 macrotile");
gd.addNumericField("Number of replace-NaN Laplassian passes", this.num_laplassian, 0,4,"",
gd.addNumericField("Number of replace-NaN Laplacian passes", this.num_laplacian, 0,4,"",
"Maximal number of repetitions replacing the removed by disparity filtered tiles by weighted average of the 8 neighbors");
gd.addNumericField("Maximal change threshold for Laplassian NaN replacement", this.change_laplassian, 5,8,"",
gd.addNumericField("Maximal change threshold for Laplacian NaN replacement", this.change_laplacian, 5,8,"",
"Exit replacement passes when maximal change falls below this threshold");
gd.addNumericField("Absolute disparity interscene tolerance", this.tolerance_absolute_inter, 3,6,"pix",
"Filter scene tiles in a macrotile by interscene disparity comparison (absolute term)");
......@@ -207,8 +207,8 @@ public class OpticalFlowParameters {
this.tolerance_absolute_ref = gd.getNextNumber();
this.tolerance_relative_ref = gd.getNextNumber();
this.center_occupancy_ref = gd.getNextNumber();
this.num_laplassian = (int) gd.getNextNumber();
this.change_laplassian = gd.getNextNumber();
this.num_laplacian = (int) gd.getNextNumber();
this.change_laplacian = gd.getNextNumber();
this.tolerance_absolute_inter = gd.getNextNumber();
this.tolerance_relative_inter = gd.getNextNumber();
this.occupancy_inter = gd.getNextNumber();
......@@ -265,8 +265,8 @@ public class OpticalFlowParameters {
properties.setProperty(prefix+"tolerance_absolute_ref", this.tolerance_absolute_ref+"");
properties.setProperty(prefix+"tolerance_relative_ref", this.tolerance_relative_ref+"");
properties.setProperty(prefix+"center_occupancy_ref", this.center_occupancy_ref+"");
properties.setProperty(prefix+"num_laplassian", this.num_laplassian+"");
properties.setProperty(prefix+"change_laplassian", this.change_laplassian+"");
properties.setProperty(prefix+"num_laplacian", this.num_laplacian+"");
properties.setProperty(prefix+"change_laplacian", this.change_laplacian+"");
properties.setProperty(prefix+"tolerance_absolute_inter", this.tolerance_absolute_inter+"");
properties.setProperty(prefix+"tolerance_relative_inter", this.tolerance_relative_inter+"");
properties.setProperty(prefix+"occupancy_inter", this.occupancy_inter+"");
......@@ -320,8 +320,8 @@ public class OpticalFlowParameters {
if (properties.getProperty(prefix+"tolerance_absolute_ref")!=null) this.tolerance_absolute_ref=Double.parseDouble(properties.getProperty(prefix+"tolerance_absolute_ref"));
if (properties.getProperty(prefix+"tolerance_relative_ref")!=null) this.tolerance_relative_ref=Double.parseDouble(properties.getProperty(prefix+"tolerance_relative_ref"));
if (properties.getProperty(prefix+"center_occupancy_ref")!=null) this.center_occupancy_ref=Double.parseDouble(properties.getProperty(prefix+"center_occupancy_ref"));
if (properties.getProperty(prefix+"num_laplassian")!=null) this.num_laplassian=Integer.parseInt(properties.getProperty(prefix+"num_laplassian"));
if (properties.getProperty(prefix+"change_laplassian")!=null) this.change_laplassian=Double.parseDouble(properties.getProperty(prefix+"change_laplassian"));
if (properties.getProperty(prefix+"num_laplacian")!=null) this.num_laplacian=Integer.parseInt(properties.getProperty(prefix+"num_laplacian"));
if (properties.getProperty(prefix+"change_laplacian")!=null) this.change_laplacian=Double.parseDouble(properties.getProperty(prefix+"change_laplacian"));
if (properties.getProperty(prefix+"tolerance_absolute_inter")!=null) this.tolerance_absolute_inter=Double.parseDouble(properties.getProperty(prefix+"tolerance_absolute_inter"));
if (properties.getProperty(prefix+"tolerance_relative_inter")!=null) this.tolerance_relative_inter=Double.parseDouble(properties.getProperty(prefix+"tolerance_relative_inter"));
if (properties.getProperty(prefix+"occupancy_inter")!=null) this.occupancy_inter=Double.parseDouble(properties.getProperty(prefix+"occupancy_inter"));
......@@ -378,8 +378,8 @@ public class OpticalFlowParameters {
ofp.tolerance_absolute_ref = this.tolerance_absolute_ref;
ofp.tolerance_relative_ref = this.tolerance_relative_ref;
ofp.center_occupancy_ref = this.center_occupancy_ref;
ofp.num_laplassian = this.num_laplassian;
ofp.change_laplassian = this.change_laplassian;
ofp.num_laplacian = this.num_laplacian;
ofp.change_laplacian = this.change_laplacian;
ofp.tolerance_absolute_inter = this.tolerance_absolute_inter;
ofp.tolerance_relative_inter = this.tolerance_relative_inter;
ofp.occupancy_inter = this.occupancy_inter;
......
......@@ -6875,7 +6875,7 @@ public class TexturedModel {
/**
* Fill NaN pixel by averaging from neighbors (Laplassian == 0)
* Fill NaN pixel by averaging from neighbors (Laplacian == 0)
* @param combo_texture [slice][pixel] combined texture from all sensors, pixels that
* are NaN in this array will not be filled
* @param combo_occluded_texture [slice][pixel] texture from occluded sensors. Only pixels that
......
......@@ -989,6 +989,9 @@ public class TileNeibs{
final boolean [] tiles,
final boolean [] prohibit)
{
if (grow <= 0) {
return;
}
// if it is not in multithreaded mode - run multithreaded version instead;
if (isMainThread()) {
growSelectionMulti (
......
......@@ -8693,7 +8693,7 @@ ImageDtt.startAndJoin(threads);
}
/**
* Generate a hint for a final replacing NaN with averaging neighbors (Laplassian). Replace all
* Generate a hint for a final replacing NaN with averaging neighbors (Laplacian). Replace all
* NaN in input data[] with the corresponding values from the matching low-res data_scaled[].
* @param data full resolution input data containing NaN values to be replaced. This array
* is MODIFIED by this method
......@@ -8772,7 +8772,7 @@ ImageDtt.startAndJoin(threads);
}
/**
* Fill NaN values in 2D array from neighbors using Laplassian==0
* Fill NaN values in 2D array from neighbors using Laplacian==0
* @param data data array (in line-scan order) with NaN values to be filled,
* non-NaN values will not be modified.
* @param prohibit optional (may be null) boolean array of the same size specifying
......@@ -8809,7 +8809,7 @@ ImageDtt.startAndJoin(threads);
}
/**
* Fill NaN values in 2D array from neighbors using Laplassian==0
* Fill NaN values in 2D array from neighbors using Laplacian==0
* @param data data array (in line-scan order) with NaN values to be filled,
* non-NaN values will not be modified.
* @param data_nan optional "original" data with NaN values to be replaced. If null,
......
......@@ -27,18 +27,31 @@ public class VegetationLMA {
public static final int TVAO_VEGETATION_ALPHA = 2;
public static final int TVAO_SCENE_OFFSET = 3;
public static final String PAR_EXT = ".par-tiff";
public static final int DATA_SOURCE_HEAD = 0; // header row with { scene, full_indx, terr_indx, scale_indx}, always present
public static final int DATA_SOURCE_CORN_VEGET =1; // [4]/null Z-shape 4 corners vegetation, either >= as parameter index or -1 - (x + image_width*y) of the unmodified full index
public static final int DATA_SOURCE_CORN_ALPHA =2; // [4]/null Z-shape 4 corners vegetation alpha, either >= as parameter index or -1 - (x + image_width*y) of the unmodified full index
public static final int DATA_SOURCE_NEIB = 3; // [4]/null or 4 neighbors (CW), either y_vector index or -1 -(x + image_width*y) of the unmodified terrain
public static final int DATA_SOURCE_HEAD_SCENE = 0; // header row scene's subindex
public static final int DATA_SOURCE_HEAD_FINDEX =1; // header row full frame index's subindex
public static final int DATA_SOURCE_HEAD_TINDEX =2; // header row texture parameter subindex
public static final int DATA_SOURCE_HEAD_SINDEX =3; // header row frame offset subindex
public static final int DATA_SOURCE_ITEMS = DATA_SOURCE_NEIB + 1; // == 4 number or rows in data source element
public static final int DATA_SOURCE_HEAD_SIZE = DATA_SOURCE_HEAD_SINDEX+1;
public final Rectangle full;
public final int image_length;
public final int num_scenes;
public Rectangle woi = null;
public double [] vegetation_average; // full image average vegetation (with nulls)
public double [] vegetation_average; // full image average vegetation (with nulls)
public double [] vegetation_filtered; // same as vegetation_average, but has more NaN to be used to select initial terrain
public double [] terrain_average; // full image average terrain (no nulls)
public double [][] terrain_rendered; // terrain rendered for scenes (has nulls)
public double [][] terrain_rendered; // terrain rendered for scenes (has nulls)
public double [][] terrain_rendered_hf; // terrain rendered for scenes (has nulls)
public double [][][] vegetation_offsets; // [num_scenes][pixle]{dx,dy} differential offsets of vegetation to terrain grid
public boolean diff_offsets;
// next 3 arrays are full [image_width*image_height], but will be modified only inside woi
public double [][] tvao; // [0][image_length] - terrain, [1][image_length] - vegetation,
// public double [][] tva_hf; // [0][image_length] - terrain, [1][image_length] - vegetation, - laplacian
public VegetationModel vegetationModel = null;
/*
......@@ -64,10 +77,11 @@ public class VegetationLMA {
private int ind_pars_vegetation_alpha; // index of the first alpha parameter
private int ind_pars_scenes; // index of the first scene parameter
private int num_pars_scenes;
private int [][][] data_source; // [index][windx][3]:
private int [][][] data_source; // [index][windx][DATA_SOURCE_ITEMS]:
// 0:{ scene, full_indx, terr_indx, scale_indx} - always present as parameters
// 1: [4]/null Z-shape 4 corners vegetation, either >= as parameter index or -1 - (x + image_width*y) of the unmodified full index
// 2: [4]/null Z-shape 4 corners vegetation alpha, either >= as parameter index or -1 - (x + image_width*y) of the unmodified full index
// 3: [4]/null or 4 neighbors (CW), either y_vector index or -1 -(x + image_width*y) of the unmodified terrain
private double [][] corners_weights; // matches data_source, non-nulls specify Z-shape 4 corners of vegetation/alpha weights
// private int num_used_scenes; // -> num_par_scenes
......@@ -80,6 +94,18 @@ public class VegetationLMA {
private double [] y_vector = null;
private double weight_pure = 0;
private double [] weights; // normalized so sum is 1.0 for all - samples and extra regularization
public boolean start_warm_veget = true; // start with vegetation warmer than terrain
public double terrain_warmest = 90; // pull vegetations to warm, terrain to cold
public double initial_split = 0.1; // pull vegetations to warm, terrain to cold
public double min_split_frac = 0.15; // minimal modality fraction to use split by temperature
public double terr_difference = 100; // pull vegetation to be this warmer
public double terr_pull_cold = 0; // pull vegetations to warm, terrain to cold
// next two just for saving?
public double hifreq_weight; // 22.5 0 - do not use high-freq. Relative weight of laplacian components
public double reg_weights; // fraction of the total weight used for regularization
public double alpha_loss = 0; // not used with cosine alpha
public double alpha_offset = 0; // if >0, start losses above 0.0 and below 1.0;
public double alpha_lpf = 0;
......@@ -156,14 +182,16 @@ public class VegetationLMA {
tvao[TVAO_VEGETATION] = this.vegetation_average.clone();
tvao[TVAO_VEGETATION_ALPHA] = new double [image_length]; // 0 - use terrain
tvao[TVAO_SCENE_OFFSET] = new double [num_scenes];
setupLaplacians(0.0); // double weight_diag)
}
public VegetationLMA (VegetationModel vegetationModel) {
full = vegetationModel.full;
image_length = full.width * full.height;
num_scenes = vegetationModel.terrain_scenes_render.length;
vegetation_average =vegetationModel.vegetation_average_render;
terrain_average = vegetationModel.terrain_average_render;
vegetation_average =vegetationModel.vegetation_full; // vegetation_average_render;
vegetation_filtered=vegetationModel.vegetation_filtered; // same with more NaNs for initial selection
terrain_average = vegetationModel.terrain_filled; // terrain_average_render;
terrain_rendered = vegetationModel.terrain_scenes_render;
vegetation_offsets =vegetationModel.vegetation_warp;
tvao = new double[4][];
......@@ -171,11 +199,24 @@ public class VegetationLMA {
tvao[TVAO_VEGETATION] = this.vegetation_average.clone();
tvao[TVAO_VEGETATION_ALPHA] = new double [image_length]; // 0 - use terrain
tvao[TVAO_SCENE_OFFSET] = new double [num_scenes];
setupLaplacians(0.0); // double weight_diag)
diff_offsets = vegetationModel.diff_mode;
this.vegetationModel = vegetationModel; // to access scene names, directories, reference index
return;
}
private void setupLaplacians(double weight_diag) {
terrain_rendered_hf = new double [terrain_rendered.length][];
for (int nscene = 0; nscene <terrain_rendered_hf.length; nscene++) {
terrain_rendered_hf[nscene] = laplacian(
false, // final boolean gaussian,
terrain_rendered[nscene], // final double [] data_in,
full.width, // final int width,
weight_diag); // final double weight_diag)
}
}
public int prepareLMA(
final boolean keep_parameters,
......@@ -184,7 +225,17 @@ public class VegetationLMA {
final int min_total_scenes,
final int min_samples_scene, // 10
final int min_valid_pixels,
final boolean start_warm_veget, // start with vegetation warmer than terrain -> USED now by vegetation_filtered
final double terrain_warmest, // warmest terrain (above is initially vegetation) NOT USED
final double initial_split, // initial alpha: terrain 0.0+, vegetation 1.0-. USED
final double min_split_frac, // minimal modality fraction to use split by temperature NOT USED?
final double terr_difference, // pull vegetation to be this warmer
final double terr_pull_cold, // pull vegetation to warm, terrain to cold
final double default_alpha,
final double hifreq_weight, // 22.5 0 - do not use high-freq. Relative weight of laplacian components
final double reg_weights, // fraction of the total weight used for regularization
final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0
final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0
......@@ -207,6 +258,16 @@ public class VegetationLMA {
String parameters_read_path,
final int debugLevel) {
this.woi = woi;
this.start_warm_veget = start_warm_veget;
this.terrain_warmest = terrain_warmest;
this.initial_split = initial_split;
this.min_split_frac = min_split_frac;
this.terr_difference = terr_difference;
this.terr_pull_cold = terr_pull_cold;
this.hifreq_weight = hifreq_weight; // 22.5 0 - do not use high-freq. Relative weight of laplacian components
this.reg_weights = reg_weights; // fraction of the total weight used for regularization
this.alpha_loss = alpha_loss;
this.alpha_offset = alpha_offset;
this.alpha_lpf = alpha_lpf;
......@@ -257,7 +318,6 @@ public class VegetationLMA {
setupParametersIndices(valid_woi); // needs to know number of used scenes // all but scenes
// alpha_neibs = getAlphaNeighbors();
alpha_neibs = getNeighbors(
TVAO_VEGETATION_ALPHA, // final int tvao, // TVAO_VEGETATION_ALPHA
ind_pars_vegetation_alpha, // final int ind_samples, // ind_pars_vegetation_alpha
......@@ -272,7 +332,9 @@ public class VegetationLMA {
num_pars_vegetation); // final int num_samples); // num_pars_vegetation_alpha
setupDataSource(
(hifreq_weight > 0), // final boolean use_hf,
min_samples_scene); // int min_samples_scene); // condensed
finishParametersIndices(); // scene-related parameters
if (num_pars_scenes < min_total_scenes) {
......@@ -280,9 +342,13 @@ public class VegetationLMA {
return -1;
}
if (!keep_parameters) {
setupParametersVector (default_alpha); // areas where both terrain and vegetation are available
setupParametersVector (
start_warm_veget,// final boolean start_warm_veget,// start with vegetation warmer than terrain
terrain_warmest, // final double terrain_warmest, // warmest terrain (above is initially vegetation)
initial_split, // final double initial_split, // initial alpha: terrain 0.0+, vegetation 1.0-.
min_split_frac, // final double min_frac, // minimal modality fraction to use split by temperature
default_alpha); // final double default_alpha // use in areas where both terrain and vegetation are available
}
from_file = false;
if (parameters_read_path != null) {
......@@ -292,12 +358,12 @@ public class VegetationLMA {
1) ;// int gap)
}
// setupDataSource(
// min_samples_scene); // int min_samples_scene); // condensed
setupYVector();
setupYVector(
(hifreq_weight > 0)); // boolean use_hf);
setupWeights( // after setupParametersIndices
scene_weights,
reg_weights); // final double reg_weights);
reg_weights, // final double reg_weights,
hifreq_weight ); // final double hifreq_weight );
last_jt = new double [parameters_vector.length][];
return weights.length;
}
......@@ -365,6 +431,9 @@ public class VegetationLMA {
for (int n = ai.getAndIncrement(); n < y_vector.length; n = ai.getAndIncrement()) {
double d = y_vector[n] - fx[n]; // - fx[n]; // +y_vector[i]
double wd = d * weights[n];
if (Double.isNaN(wd)) {
System.out.println("wd=NaN, n="+n);
}
wymfw[n] = wd;
swd2[nthread] += d * wd;
}
......@@ -403,6 +472,9 @@ public class VegetationLMA {
for (int n = 0; n < swd2.length; n++) {
s_rms += swd2[n];
}
if (Double.isNaN(s_rms)) {
System.out.println("s_rms = NaN");
}
if (rms_fp != null) {
rms_fp[0] = Math.sqrt(s_rms);
......@@ -689,9 +761,11 @@ public class VegetationLMA {
public String getParametersDebugTitle() {
// alpha_en_holes -> alpha_mm_hole = NaN;
// hifreq_weight
String debug_title = "parameters_vector-x"+woi.x+"-y"+woi.y+"-w"+woi.width+"-h"+woi.height;
debug_title += "-hf"+hifreq_weight;
debug_title += "-al"+alpha_loss+"-alo"+alpha_offset+"-alp"+alpha_lpf+"-als"+alpha_scale_avg+(alpha_piece_linear?"-alin":"-acos");
debug_title += "-ap"+alpha_push+"-apn"+alpha_push_neutral+"-apc"+alpha_push_center+"-amm"+alpha_mm_hole;
debug_title += "-ap"+alpha_push+"-apn"+alpha_push_neutral+"-apc"+alpha_push_center+(alpha_en_holes?("-amm"+alpha_mm_hole):"");
debug_title += "-tl"+terr_lpf+"-vl"+veget_lpf+"-tp"+terr_pull0+"-vp"+veget_pull0;
debug_title += "-bp"+boost_parallax;
debug_title += from_file?"-file":"-new";
......@@ -745,6 +819,7 @@ public class VegetationLMA {
}
if (save_all) {
String file_path = save_dir+title_all+".tiff";
(new File(save_dir)).mkdirs();
ImageStack imageStack = ShowDoubleFloatArrays.makeStack(dbg_img, wh[0], wh[1], titles);
ImagePlus imp = new ImagePlus( title, imageStack);
FileSaver fs=new FileSaver(imp);
......@@ -906,6 +981,7 @@ public class VegetationLMA {
final double [] data_in,
final int width,
final double weight_diag) {
final boolean zero_missing = true; // set no-neighbor to 0, not NaN
final int height = data_in.length/width;
final double [] data_out = new double [data_in.length];
Arrays.fill(data_out, Double.NaN);
......@@ -917,7 +993,7 @@ public class VegetationLMA {
for (int i = 2; i < 8;i++) {
weights8[i] = weights8[i % 2];
}
final int dir_step = (weight_diag > 0) ? 1 : 2;
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
......@@ -925,7 +1001,7 @@ public class VegetationLMA {
TileNeibs tn = new TileNeibs(width,height);
for (int nPix = ai.getAndIncrement(); nPix < data_in.length; nPix = ai.getAndIncrement()) if(!Double.isNaN(data_in[nPix])){
double sw = 0, swd = 0;
for (int dir = 0; dir < 8; dir++) {
for (int dir = 0; dir < 8; dir += dir_step) {
int nPix1= tn.getNeibIndex(nPix, dir);
if ((nPix1 >= 0) && !Double.isNaN(data_in[nPix1])) {
sw += weights8[dir];
......@@ -935,6 +1011,8 @@ public class VegetationLMA {
if (sw != 0) {
swd /= sw;
data_out[nPix] = gaussian? swd : (data_in[nPix] - swd);
} else if (zero_missing) { // so each source non-NaN will have non-NaN Laplacian
data_out[nPix] = 0;
}
}
}
......@@ -1022,6 +1100,7 @@ public class VegetationLMA {
final double [] vector,
final double [][] jt, // should be null or initialized with [vector.length][]
final int debug_level) {
final boolean use_hf = y_vector.length > data_source.length; // twice longer
// using 0.5*(1-cos(alpha/2pi) instead of alpha. alpha < 0 -> 0, alpha > 1 -> 1. Depends on other terms for stability
double [] fX = new double [weights.length]; // num_pairs + vector.length];
if (jt != null) {
......@@ -1037,7 +1116,8 @@ public class VegetationLMA {
public void run() {
double [] vegetation = new double [4];
double [] alpha = new double [4];
for (int n = ai.getAndIncrement(); n < y_vector.length; n = ai.getAndIncrement()) {
// for (int n = ai.getAndIncrement(); n < y_vector.length; n = ai.getAndIncrement()) {
for (int n = ai.getAndIncrement(); n < data_source.length; n = ai.getAndIncrement()) { // low-frequency
if (n == dbg_n) {
System.out.println("getFxDerivs(): n="+n);
}
......@@ -1089,11 +1169,15 @@ public class VegetationLMA {
jt[data_source[n][0][2]][n] = 1; // d/dterrain
}
}
if (data_source[n][0][3] >= 0) {
double scene_offs = vector[data_source[n][0][3]];
if (data_source[n][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SINDEX] >= 0) {
double scene_offs = vector[data_source[n][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SINDEX]];
fX[n] = d + scene_offs;
if (Double.isNaN(fX[n])) {
System.out.println("fX["+n+"]= NaN");
}
if (jt != null) {
jt[data_source[n][0][3]][n] = 1;
jt[data_source[n][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SINDEX]][n] = 1;
}
}
}
......@@ -1101,6 +1185,89 @@ public class VegetationLMA {
};
}
ImageDtt.startAndJoin(threads);
if (use_hf) {
final int ind_next = data_source.length;
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// double [] vegetation = new double [4];
// double [] alpha = new double [4];
for (int n_lf = ai.getAndIncrement(); n_lf < data_source.length; n_lf = ai.getAndIncrement()) {
if (n_lf == dbg_n) {
System.out.println("getFxDerivs(): n_lf="+n_lf);
}
int n_hf = n_lf + ind_next;
int [] neibs = data_source[n_lf][DATA_SOURCE_NEIB];
if (neibs != null) { // nothing to do if null
double d_lf = fX[n_lf]; // center value
// int nscene = data_source[n_lf][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE];
double swd = 0, sw=0;
for (int dir = 0; dir < 4; dir++) {
int nindx = neibs[dir];
if (nindx != -1) {
double d_hf;
if (nindx >= 0) {
d_hf = fX[neibs[dir]]; // neighbor value
} else {
d_hf = tvao[TVAO_TERRAIN][-2-nindx];
// add same scene offset as is added to all fX[] values so it will not influence differences
if (data_source[n_lf][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SINDEX] >= 0) {
double scene_offs = vector[data_source[n_lf][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SINDEX]];
d_hf += scene_offs;
}
}
swd += d_hf;
sw += 1;
}
}
if (sw > 0) { // nothing to do if 0
swd /= sw;
fX[n_hf] = d_lf - swd;
if (jt != null) {
// center derivative same as _lf with respect to all it depends on except scene offset
int pindx =data_source[n_lf][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_TINDEX];
if (pindx >= 0) jt [pindx][n_hf] = jt[pindx][n_lf]; // d/dterrain always?
for (int i = 0; i < 4; i++ ){
if ( data_source[n_lf][DATA_SOURCE_CORN_VEGET] != null) {
pindx = data_source[n_lf][DATA_SOURCE_CORN_VEGET][i];
if (pindx >= 0) jt[pindx][n_hf] = jt[pindx][n_lf]; // d/dvegetation[i]
}
if ( data_source[n_lf][DATA_SOURCE_CORN_ALPHA] != null) {
pindx = data_source[n_lf][DATA_SOURCE_CORN_ALPHA][i];
if (pindx >= 0) jt[pindx][n_hf] = jt[pindx][n_lf]; // d/dalpha[i]
}
}
// scale/negate derivatives of all neighbors; -1.0/sw
for (int neib:neibs) if (neib >=0) { // neib - index in data_source
pindx =data_source[neib][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_TINDEX];
if (pindx >= 0) jt [pindx][n_hf] -= jt[pindx][neib]/sw; // d/dterrain always?
for (int i = 0; i < 4; i++ ){
if ( data_source[neib][DATA_SOURCE_CORN_VEGET] != null) {
pindx = data_source[neib][DATA_SOURCE_CORN_VEGET][i];
if (pindx >= 0) jt[pindx][n_hf] -= jt[pindx][neib]/sw; // d/dvegetation[i]
}
if ( data_source[neib][DATA_SOURCE_CORN_ALPHA] != null) {
pindx = data_source[neib][DATA_SOURCE_CORN_ALPHA][i];
if (pindx >= 0) jt[pindx][n_hf] -= jt[pindx][neib]/sw; // d/dalpha[i]
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
// TODO: calculate high-frequency (laplacians)
// regularization weights and derivatives
// splitting alpha_lpf from alpha_loss+alpha_push
int ind_next = y_vector.length;
......@@ -1343,11 +1510,10 @@ public class VegetationLMA {
}
ImageDtt.startAndJoin(threads);
}
if (veget_lpf >= 0) {
if (veget_lpf >= 0) { // should be positive for pull0 and terr_pull_cold (difference between vegetation and terrain)
final int ind_y_veget = ind_next;
ind_next += num_pars_vegetation;
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
......@@ -1381,7 +1547,20 @@ public class VegetationLMA {
jt[di][nx] -= veget_lpf/nn;
}
}
}
}
if (terr_pull_cold > 0) {
// find corresponding terrain
int findx = par_rindex[np][1];
int tindx = par_index[TVAO_TERRAIN][findx];
if (tindx >= 0) { // only if both terrain and vegetation exist for this pixel
int ntp = ind_pars_terrain + tindx; // index in vector[]
fX[nx] += terr_pull_cold * (vector[np] - vector[ntp] - terr_difference);
if (jt != null) {
jt[np][nx] += terr_pull_cold;
jt[ntp][nx] -= terr_pull_cold;
}
}
}
}
}
}
......@@ -1448,7 +1627,10 @@ public class VegetationLMA {
if (vector == null) {
vector = parameters_vector;
}
double [][][] img_data = new double [3][num_scenes][woi.width*woi.height];
final boolean use_hf = y_vector.length > data_source.length; // twice longer
double [][][] img_data = new double [use_hf? 6 : 3][num_scenes][woi.width*woi.height];
String [] top_titles = use_hf? (new String[]{"Y_lf", "fX_lf", "Ylf-fXlf","Y_hf", "fX_hf", "Yhf-fXhf"}): new String[]{"Y", "fX", "Y-fX"};
for (int n = 0; n < img_data.length; n++) {
for (int nscene = 0; nscene < num_scenes; nscene++) {
Arrays.fill(img_data[n][nscene], Double.NaN);
......@@ -1463,21 +1645,26 @@ public class VegetationLMA {
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int ny = ai.getAndIncrement(); ny < data_source.length; ny = ai.getAndIncrement()) {
int nscene = data_source[ny][0][0];
int indx = data_source[ny][0][1];
for (int n_lf = ai.getAndIncrement(); n_lf < data_source.length; n_lf = ai.getAndIncrement()) {
int n_hf = n_lf+data_source.length;
int nscene = data_source[n_lf][0][0];
int indx = data_source[n_lf][0][1];
int wx = (indx % full.width) - woi.x;
int wy = (indx / full.width) - woi.y;
int windx = wx + wy * woi.width;
img_data[0][nscene][windx] = y_vector[ny];
img_data[1][nscene][windx] = fX[ny];
img_data[2][nscene][windx] = y_vector[ny]-fX[ny];
img_data[0][nscene][windx] = y_vector[n_lf];
img_data[1][nscene][windx] = fX[n_lf];
img_data[2][nscene][windx] = y_vector[n_lf]-fX[n_lf];
if (img_data.length > 3) {
img_data[3][nscene][windx] = hifreq_weight * y_vector[n_hf];
img_data[4][nscene][windx] = hifreq_weight * fX[n_hf];
img_data[5][nscene][windx] = hifreq_weight * (y_vector[n_hf] - fX[n_hf]);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
String [] top_titles = {"Y", "fX", "Y-fX"};
String [] scene_titles = new String[num_scenes];
for (int i = 0; i < num_scenes; i++) {
scene_titles[i] = ""+i;
......@@ -1489,7 +1676,6 @@ public class VegetationLMA {
scene_titles, // String [] titles, // all slices*frames titles or just slice titles or null
top_titles, // String [] frame_titles, // frame titles or null
true); // boolean show)
return;
}
......@@ -1616,6 +1802,9 @@ public class VegetationLMA {
imp.setProperty("IND_PARS_VEGETATION_ALPHA", ""+ind_pars_vegetation_alpha);
imp.setProperty("IND_PARS_SCENES", ""+ind_pars_scenes);
imp.setProperty("HIGHFREQ_WEIGHT", ""+hifreq_weight);
imp.setProperty("REG_WEIGHTS", ""+reg_weights);
imp.setProperty("ALPHA_LOSS", ""+alpha_loss);
imp.setProperty("ALPHA_OFFSET", ""+alpha_offset);
imp.setProperty("ALPHA_LPF", ""+alpha_lpf);
......@@ -1741,6 +1930,10 @@ public class VegetationLMA {
ind_pars_vegetation = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_VEGETATION"));
ind_pars_vegetation_alpha = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_VEGETATION_ALPHA"));
ind_pars_scenes = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_SCENES"));
if (imp_pars.getProperty("HIGHFREQ_WEIGHT") != null) hifreq_weight = Double.parseDouble((String) imp_pars.getProperty("HIGHFREQ_WEIGHT"));
if (imp_pars.getProperty("REG_WEIGHTS") != null) reg_weights = Double.parseDouble((String) imp_pars.getProperty("REG_WEIGHTS"));
alpha_loss = Double.parseDouble((String) imp_pars.getProperty("ALPHA_LOSS"));
alpha_offset = Double.parseDouble((String) imp_pars.getProperty("ALPHA_OFFSET"));
alpha_lpf = Double.parseDouble((String) imp_pars.getProperty("ALPHA_LPF"));
......@@ -1751,6 +1944,7 @@ public class VegetationLMA {
if (imp_pars.getProperty("ALPHA_EN_HOLES") != null) alpha_en_holes = Boolean.parseBoolean((String) imp_pars.getProperty("ALPHA_EN_HOLES"));
alpha_mm_hole = Double.parseDouble((String) imp_pars.getProperty("ALPHA_MM_HOLE"));
alpha_diff_hole = Double.parseDouble((String) imp_pars.getProperty("ALPHA_DIFF_HOLE"));
terr_lpf = Double.parseDouble((String) imp_pars.getProperty("TERR_LPF"));
......@@ -2025,7 +2219,7 @@ public class VegetationLMA {
final int full_length = full.width*full.height;
final double [][] tva = vegetationModel.getTVA();
final double [] terrain_dflt = vegetationModel.terrain_average_render;
final double [] vegetation_dflt = vegetationModel.vegetation_average_render;
final double [] vegetation_dflt = vegetationModel.vegetation_full; // vegetation_average_render;
final int INDX_TERR = 0, INDX_VEG=1;
final double [][][] synthetic = new double [2][num_scenes][full_length];
for (int t = 0; t < synthetic.length; t++) {
......@@ -2361,8 +2555,11 @@ public class VegetationLMA {
private void setupWeights( // after setupParametersIndices
final double [] scene_weights,
final double reg_weights) {
final double reg_weights,
final double hifreq_weight) {
boolean use_hf = (hifreq_weight > 0);
// int extra_samples = num_pars_vegetation_alpha; // in the future may be more regularization
// int hf_samples = use_hf ? data_source.length : 0;
int extra_samples = 0;
// using >=0 no use 0 as NOP but reserve space, <0 - do not reserve space
......@@ -2372,18 +2569,25 @@ public class VegetationLMA {
if (terr_lpf >= 0) extra_samples+= num_pars_terrain;
if (veget_lpf >= 0) extra_samples+= num_pars_vegetation;
double reg_sample_weight = reg_weights/extra_samples; // weight of each regularization sample
final double [] sw = (scene_weights != null) ? scene_weights : new double [num_scenes];
if (scene_weights == null) {
Arrays.fill (sw, 1.0);
}
weights = new double [data_source.length + extra_samples];
// weights = new double [data_source.length + extra_samples];
weights = new double [y_vector.length + extra_samples];
double s = 0;
for (int ny = 0; ny < data_source.length; ny++) {
int nscene = data_source[ny][0][0];
// int indx = data_source[ny][0][1];
int nscene = data_source[ny][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE];
s += sw[nscene];
}
if (use_hf) { // second pass, repeating for possible future modifications
for (int ny = 0; ny < data_source.length; ny++) {
int nscene = data_source[ny][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE];
s += sw[nscene] * hifreq_weight ;
}
}
final double s0 = s;
s *= (1+ reg_weights);
final double k = 1.0/s;
......@@ -2397,35 +2601,70 @@ public class VegetationLMA {
threads[ithread] = new Thread() {
public void run() {
for (int nw = ai.getAndIncrement(); nw < weights.length; nw = ai.getAndIncrement()) {
if (nw < data_source.length) {
weights[nw] = sw[data_source[nw][0][0]] * k;
if (nw < data_source.length) { // DC differences
weights[nw] = sw[data_source[nw][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE]] * k;
if (Double.isNaN(weights[nw])) {
System.out.println("weights["+nw+"]=NaN");
}
} else if (nw < y_vector.length) { // HF differences if exist
weights[nw] = sw[data_source[nw-data_source.length][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE]] * k * hifreq_weight;
if (Double.isNaN(weights[nw])) {
System.out.println("weights["+nw+"]=NaN");
}
} else {
weights[nw] = reg_sample_weight;
if (Double.isNaN(weights[nw])) {
System.out.println("weights["+nw+"]=NaN");
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return;
}
private void setupYVector() {
// double []
y_vector = new double [data_source.length];
private void setupYVector(boolean use_hf) {
int ds_length = (use_hf? 2 : 1) * data_source.length;
y_vector = new double [ds_length];
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int ny = ai.getAndIncrement(); ny < data_source.length; ny = ai.getAndIncrement()) {
int nscene = data_source[ny][0][0];
int indx = data_source[ny][0][1];
int nscene = data_source[ny][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE];
int indx = data_source[ny][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_FINDEX];
y_vector[ny] = terrain_rendered[nscene][indx];
if (Double.isNaN(y_vector[ny])) {
System.out.println("y_vector["+ny+"]=NaN");
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (use_hf) {
ai.set(0);
final int hf_offset = data_source.length;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int ny = ai.getAndIncrement(); ny < data_source.length; ny = ai.getAndIncrement()) {
int nscene = data_source[ny][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE];
int indx = data_source[ny][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_FINDEX];
y_vector[hf_offset + ny] = terrain_rendered_hf[nscene][indx];
if (Double.isNaN(y_vector[hf_offset + ny])) {
System.out.println("y_vector["+(hf_offset + ny)+"]=NaN");
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
return;
}
......@@ -2501,8 +2740,11 @@ public class VegetationLMA {
private void setupDataSource(int min_samples_scene) {
private void setupDataSource(
final boolean use_hf,
final int min_samples_scene) {
final int woi_length = woi.width*woi.height;
final int full_length = full.width*full.height;
final int [][][][] data_src = new int [num_scenes][woi_length][][];
final double [][][] corn_w = new double [num_scenes][woi_length][]; // null where no vegetation
final int [] scene_samples = new int [num_scenes];
......@@ -2520,13 +2762,20 @@ public class VegetationLMA {
int indx = row*full.width + col;
if (!Double.isNaN(terrain_rendered[nScene][indx]) && (par_index[TVAO_TERRAIN][indx] >= 0)) { //
scene_samples[nScene]++;
data_src[nScene][windx] = new int[3][];
data_src[nScene][windx] = new int[DATA_SOURCE_ITEMS][];
// maybe use windx instead of indx below?
// data_src[nScene][windx][0] = new int [] {nScene, indx, par_index[TVAO_TERRAIN][indx],par_index[TVAO_SCENE_OFFSET][nScene]};
data_src[nScene][windx][0] = new int [] {nScene, indx, par_index[TVAO_TERRAIN][indx],nScene};
// next 3 not needed - they are already nulls
data_src[nScene][windx][1] = null;
data_src[nScene][windx][2] = null;
// data_src[nScene][windx][0] = new int [] {nScene, indx, par_index[TVAO_TERRAIN][indx],nScene};
data_src[nScene][windx][DATA_SOURCE_HEAD] = new int [DATA_SOURCE_HEAD_SIZE];
data_src[nScene][windx][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE] = nScene;
data_src[nScene][windx][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_FINDEX] = indx;
data_src[nScene][windx][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_TINDEX] = par_index[TVAO_TERRAIN][indx];
data_src[nScene][windx][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SINDEX] = nScene;
// next 4 not needed - they are already nulls
// data_src[nScene][windx][1] = null;
// data_src[nScene][windx][2] = null;
data_src[nScene][windx][DATA_SOURCE_CORN_VEGET] = null;
data_src[nScene][windx][DATA_SOURCE_CORN_ALPHA] = null;
data_src[nScene][windx][DATA_SOURCE_NEIB] = null;
corn_w[nScene][windx] = null;
double [] veg_xy = vegetation_offsets[nScene][indx];
if (veg_xy != null) {
......@@ -2545,15 +2794,22 @@ public class VegetationLMA {
double fx = veg_xy[0] - x0;
double fy = veg_xy[1] - y0;
corn_w[nScene][windx] = new double []{(1-fx)*(1-fy), fx*(1-fy), (1-fx)*fy, fx*fy};
data_src[nScene][windx][1] = new int [4];
data_src[nScene][windx][2] = new int [4];
// data_src[nScene][windx][1] = new int [4];
// data_src[nScene][windx][2] = new int [4];
data_src[nScene][windx][DATA_SOURCE_CORN_VEGET] = new int [4];
data_src[nScene][windx][DATA_SOURCE_CORN_ALPHA] = new int [4];
int veg_indx = x0+full.width*y0;
int [] veg_indx4 = {veg_indx, veg_indx+1, veg_indx+full.width, veg_indx+full.width+1};
for (int i = 0; i < 4; i++ ) {
data_src[nScene][windx][1][i] = (par_index[TVAO_VEGETATION][veg_indx4[i]] >= 0)?
// data_src[nScene][windx][1][i] = (par_index[TVAO_VEGETATION][veg_indx4[i]] >= 0)?
// par_index[TVAO_VEGETATION][veg_indx4[i]] : (-1-veg_indx4[i]);
// data_src[nScene][windx][2][i] = (par_index[TVAO_VEGETATION_ALPHA][veg_indx4[i]] >= 0)?
// par_index[TVAO_VEGETATION_ALPHA][veg_indx4[i]] : (-1-veg_indx4[i]);
data_src[nScene][windx][DATA_SOURCE_CORN_VEGET][i] = (par_index[TVAO_VEGETATION][veg_indx4[i]] >= 0)?
par_index[TVAO_VEGETATION][veg_indx4[i]] : (-1-veg_indx4[i]);
data_src[nScene][windx][2][i] = (par_index[TVAO_VEGETATION_ALPHA][veg_indx4[i]] >= 0)?
data_src[nScene][windx][DATA_SOURCE_CORN_ALPHA][i] = (par_index[TVAO_VEGETATION_ALPHA][veg_indx4[i]] >= 0)?
par_index[TVAO_VEGETATION_ALPHA][veg_indx4[i]] : (-1-veg_indx4[i]);
}
}
......@@ -2583,16 +2839,6 @@ public class VegetationLMA {
}
}
/*
*
used_scenes_indices = new int [num_used_scenes];
int indx = 0;
for (int nscene = 0; nscene < num_scenes; nscene++) {
if (used_scenes[nscene]) {
used_scenes_indices[indx++] = nscene;
}
}
*/
data_source = new int [num_samples][][];
corners_weights = new double[num_samples][];
ai.set(0);
......@@ -2605,7 +2851,8 @@ public class VegetationLMA {
if (data_src[nScene][windx] != null) {
corners_weights[out_indx] = corn_w[nScene][windx];
int [][] dsrc = data_src[nScene][windx];
dsrc[0][3] = ind_pars_scenes + used_scene_indices[dsrc[0][3]]; // replace scene number with the corresponding parameter index
// dsrc[0][3] = ind_pars_scenes + used_scene_indices[dsrc[0][3]]; // replace scene number with the corresponding parameter index
dsrc[DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SINDEX] = ind_pars_scenes + used_scene_indices[dsrc[DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SINDEX]]; // replace scene number with the corresponding parameter index
data_source [out_indx++] = dsrc; // data_src[nScene][windx];
}
}
......@@ -2614,36 +2861,137 @@ public class VegetationLMA {
};
}
ImageDtt.startAndJoin(threads);
if (use_hf) { // fill out fX neighbor indices
final int [][] y_indices = new int[num_scenes][full_length];
for (int nscene = 0; nscene < num_scenes; nscene++) {
Arrays.fill(y_indices[nscene], -1);
}
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int dsi = ai.getAndIncrement(); dsi < data_source.length; dsi = ai.getAndIncrement()){
int nscene = data_source[dsi][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE];
int indx = data_source[dsi][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_FINDEX];
y_indices[nscene][indx] = dsi;
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
TileNeibs tn = new TileNeibs(full.width, full.height);
for (int dsi = ai.getAndIncrement(); dsi < data_source.length; dsi = ai.getAndIncrement()){
int nscene = data_source[dsi][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_SCENE];
int indx = data_source[dsi][DATA_SOURCE_HEAD][DATA_SOURCE_HEAD_FINDEX];
data_source[dsi][DATA_SOURCE_NEIB] = new int [4];
for (int dir4 = 0; dir4 < 4; dir4++) {
int indx1 = tn.getNeibIndex(indx, 2* dir4);
if (indx1 >= 0){
if (y_indices[nscene][indx1] >=0){ // has y_vector/fX data
data_source[dsi][DATA_SOURCE_NEIB][dir4] = y_indices[nscene][indx1]; // index in first part of y_vector
} else {
data_source[dsi][DATA_SOURCE_NEIB][dir4] = -2 - indx1; // index in the full window to get unmodified texture from
}
} else {
data_source[dsi][DATA_SOURCE_NEIB][dir4] = -1; // out of bounds
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
return;
}
private void setupParametersVector(
double default_alpha) { // areas where both terrain and vegetation are available
final boolean start_warm_veget,// start with vegetation warmer than terrain
final double terrain_warmest, // warmest terrain (above is initially vegetation)
final double initial_split, // initial alpha: terrain 0.0+, vegetation 1.0-.
final double min_frac, // minimal modality fraction to use split by temperature
final double default_alpha) { // areas where both terrain and vegetation are available
for (int i = 0; i < tvao[TVAO_VEGETATION_ALPHA].length; i++) {
if (!Double.isNaN(tvao[TVAO_VEGETATION][i])) {
tvao[TVAO_VEGETATION_ALPHA][i] = default_alpha;
}
}
boolean split = false;
if (start_warm_veget) {
int num_veg=0, num_terr=0;
for (int drow = 0; drow < woi.height; drow++) {
int row = woi.y + drow;
for (int dcol = 0; dcol < woi.width; dcol++) {
int col = woi.x + dcol;
int indx = row*full.width + col;
if (par_index[TVAO_VEGETATION_ALPHA][indx] >= 0) {
if (par_index[TVAO_VEGETATION][indx] >= 0) {
if (!Double.isNaN(vegetation_filtered[indx])) {
/// if (tvao[TVAO_VEGETATION][indx] > terrain_warmest) {
num_veg++;
} else {
num_terr++;
}
}
}
}
}
double frac_terr = 1.0*num_terr/(num_terr+num_veg);
System.out.println("setupParametersVector(): num_terr="+num_terr+", num_veg="+num_veg+" frac_terr ="+frac_terr+" (min_frac="+min_frac);
if ((frac_terr >= min_frac) && (frac_terr <= (1.0 -min_frac))) {
split = true;
System.out.println("Using initial split alpha by temperature");
} else {
System.out.println("Using initial default alpha");
}
}
for (int drow = 0; drow < woi.height; drow++) {
int row = woi.y + drow;
for (int dcol = 0; dcol < woi.width; dcol++) {
int col = woi.x + dcol;
// int windx =dcol + drow * woi.width;
int indx = row*full.width + col;
if (par_index[TVAO_TERRAIN][indx] >= 0) {
parameters_vector[par_index[TVAO_TERRAIN][indx]] = tvao[TVAO_TERRAIN][indx];
if (Double.isNaN(parameters_vector[par_index[TVAO_TERRAIN][indx]])) {
System.out.println("parameters_vector[par_index["+TVAO_TERRAIN+"]["+indx+"]]=NaN");
}
}
if (par_index[TVAO_VEGETATION][indx] >= 0) {
parameters_vector[par_index[TVAO_VEGETATION][indx]] = tvao[TVAO_VEGETATION][indx];
if (Double.isNaN(parameters_vector[par_index[TVAO_VEGETATION][indx]])) {
System.out.println("parameters_vector[par_index["+TVAO_VEGETATION+"]["+indx+"]]=NaN");
}
}
if (par_index[TVAO_VEGETATION_ALPHA][indx] >= 0) {
parameters_vector[par_index[TVAO_VEGETATION_ALPHA][indx]] = default_alpha;
if (split && (par_index[TVAO_VEGETATION][indx] >= 0)) {
/// if (tvao[TVAO_VEGETATION][indx] > terrain_warmest) {
if (!Double.isNaN(vegetation_filtered[indx])) {
parameters_vector[par_index[TVAO_VEGETATION_ALPHA][indx]] = 1.0 - initial_split;
} else {
parameters_vector[par_index[TVAO_VEGETATION_ALPHA][indx]] = initial_split;
}
} else {
parameters_vector[par_index[TVAO_VEGETATION_ALPHA][indx]] = default_alpha;
}
if (Double.isNaN(parameters_vector[par_index[TVAO_VEGETATION_ALPHA][indx]])) {
System.out.println("parameters_vector[par_index["+TVAO_VEGETATION_ALPHA+"]["+indx+"]]=NaN");
}
}
}
}
for (int i = 0; i < par_index[TVAO_SCENE_OFFSET].length; i++) if (par_index[TVAO_SCENE_OFFSET][i] >= 0){
parameters_vector[par_index[TVAO_SCENE_OFFSET][i]]= tvao[TVAO_SCENE_OFFSET][i];
if (Double.isNaN(parameters_vector[par_index[TVAO_SCENE_OFFSET][i]])) {
System.out.println("parameters_vector[par_index["+TVAO_SCENE_OFFSET+"]["+i+"]]");
}
}
return;
}
......
......@@ -54,6 +54,12 @@ public class VegetationModel {
public double [][] terrain_scenes_render = null;
public double [] terrain_average_render = null;
public double [] vegetation_average_render = null;
public double [] terrain_filled = null;
public double [] vegetation_full = null; // ~same as vegetation_average_render
public double [] vegetation_filtered = null; // more NaNs than in vegetation_average_render
public double [][][] vegetation_warp = null;
public String [] scene_names = null; // TODO: Implement!
public boolean diff_mode = true;
......@@ -1291,7 +1297,16 @@ public class VegetationModel {
String segments_dir = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/debug/vegetation/segments";
int min_scenes = 1; // 10; // for new scenes only, for old ones use 10
boolean start_warm_veget = clt_parameters.imp.terr_warm_veget; // start with vegetation warmer than terrain
double terrain_warmest = clt_parameters.imp.terr_warmest; // pull vegetations to warm, terrain to cold
double initial_split = clt_parameters.imp.terr_initial_split; // pull vegetations to warm, terrain to cold
double min_split_frac = clt_parameters.imp.terr_min_split_frac;// 0.15;
double terr_difference = clt_parameters.imp.terr_difference; // Pull vegetation to be this warmer
double terr_pull_cold = clt_parameters.imp.terr_pull_cold; // pull vegetations to warm, terrain to cold
double default_alpha = 0.5; // 0.8;
double hifreq_weight = 22.5; // 0 - do not use high-freq. Relative weight of laplacian components
double reg_weights = 0.25; // fraction of the total weight used for regularization
double alpha_loss = 100.0; // 10.0; /// 100.0; // 10.0; // 10000.0; // 1000.0; // 100.; // 10.0; // quadratic loss when alpha reaches -1.0 or 2.0
double alpha_offset = 0.0; // 0.02; // 0.03; // if >0, start losses above 0.0 and below 1.0;
......@@ -1351,7 +1366,7 @@ public class VegetationModel {
int min_samples_scene = 10;
int min_pixels = 10;
boolean show_final_result = true;
// boolean exit_loop = debugLevel < 1000;
......@@ -1473,12 +1488,17 @@ public class VegetationModel {
false, // final boolean keep_parameters,
woi, // final Rectangle woi,
min_scenes, // final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence
min_total_scenes, // final int min_total_scenes,
min_samples_scene, //final int min_samples_scene, // 10
min_pixels, // final int min_pixels,
default_alpha, // final double default_alpha,
start_warm_veget, // final boolean start_warm_veget, // start with vegetation warmer than terrain
terrain_warmest, // final double terrain_warmest, // warmest terrain (above is initially vegetation)
initial_split, // final double initial_split, // initial alpha: terrain 0.0+, vegetation 1.0-.
min_split_frac, // final double min_frac, // minimal modality fraction to use split by temperature
terr_difference, // final double terr_difference, // pull vegetation to be this warmer
terr_pull_cold, // final double terr_pull_cold, // pull vegetations to warm, terrain to cold
default_alpha, // final double default_alpha,
hifreq_weight, //final double hifreq_weight, // 22.5 0 - do not use high-freq. Relative weight of laplacian components
reg_weights, // final double reg_weights, // fraction of the total weight used for regularization
alpha_loss, // final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0
alpha_offset, // final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0
......@@ -1572,17 +1592,16 @@ public class VegetationModel {
null); // double [] vector)
// continue;
}
if (show_final_result) {
vegetationLMA.showYfX(
null, // double [] vector,
"reconstructed_model_adjusted"); // String title)
}
}
/*
if (debugLevel >-2) {
vegetationLMA.showYfX(
null, // double [] vector,
"reconstructed_model_adjusted"); // String title)
}
*/
return; //
}
......@@ -1617,6 +1636,13 @@ public class VegetationModel {
int min_total_scenes = clt_parameters.imp.terr_min_total_scenes; // 2;
int min_pixels = clt_parameters.imp.terr_min_pixels; //10;
boolean start_warm_veget = clt_parameters.imp.terr_warm_veget; // start with vegetation warmer than terrain
double terrain_warmest = clt_parameters.imp.terr_warmest; // pull vegetations to warm, terrain to cold
double initial_split = clt_parameters.imp.terr_initial_split; // pull vegetations to warm, terrain to cold
double min_split_frac = clt_parameters.imp.terr_min_split_frac;// 0.15;
double terr_difference = clt_parameters.imp.terr_difference; // Pull vegetation to be this warmer
double terr_pull_cold = clt_parameters.imp.terr_pull_cold; // pull vegetations to warm, terrain to cold
double default_alpha = clt_parameters.imp.terr_alpha_dflt; // 0.5; // 0.8;
double alpha_loss = clt_parameters.imp.terr_alpha_loss; //100.0; // 10.0; /// 100.0; // 10.0; // 10000.0; // 1000.0; // 100.; // 10.0; // quadratic loss when alpha reaches -1.0 or 2.0
double alpha_offset = clt_parameters.imp.terr_alpha_offset; // 0.0; // 0.02; // 0.03; // if >0, start losses above 0.0 and below 1.0;
......@@ -1635,7 +1661,8 @@ public class VegetationModel {
// LMA parameters
double boost_parallax = clt_parameters.imp.terr_boost_parallax; // 3.0; /// 1.0; /////// 5.0; /// 1.0; // 5;
double max_parallax = clt_parameters.imp.terr_max_parallax; //10;
double max_parallax = clt_parameters.imp.terr_max_parallax; // 10;
double hifreq_weight = clt_parameters.imp.terr_hifreq_weight; // 22.5; // 0 - do not use high-freq. Relative weight of laplacian components double reg_weights = 0.25; // fraction of the total weight used for regularization
double reg_weights = clt_parameters.imp.terr_reg_weights; // 0.25; // fraction of the total weight used for regularization
double lambda = clt_parameters.imp.terr_lambda; // 5.0; // 0.1;
double lambda_scale_good = clt_parameters.imp.terr_lambda_scale_good; // 0.5;
......@@ -1664,6 +1691,9 @@ public class VegetationModel {
Rectangle woi_last_done = continue_woi ? woi_last : null; // new Rectangle(150, 270, 20, 20); // null; // to be able to continue
boolean show_final_result = !tile_woi; // true; (maybe make saving results in tiled mode?
//clt_parameters.imp.; //
......@@ -1692,45 +1722,86 @@ public class VegetationModel {
boolean last_run = false;
double [][] laplacian_in = new double [2 + terrain_scenes_render.length][];
double [][] laplacian_all = new double [2 + terrain_scenes_render.length][];
String [] titles_laplacian = new String[laplacian_in.length];
System.arraycopy(terrain_scenes_render, 0, laplacian_in, 0, terrain_scenes_render.length);
laplacian_in[terrain_scenes_render.length + 0] = terrain_average_render;
laplacian_in[terrain_scenes_render.length + 1] = vegetation_average_render;
titles_laplacian[terrain_scenes_render.length + 0] = "terrain_average";
titles_laplacian[terrain_scenes_render.length + 1] = "vegetation_average";
double weight_diag = .7;
for (int n = 0; n < laplacian_all.length; n++) {
if (n < terrain_scenes_render.length) {
titles_laplacian[n]=scene_names[n];
boolean test_laplacian = false;
int nan_grow_render = nan_grow;
int shrink_veget = nan_grow; // same
int filter_vegetation = nan_grow;
double vegetation_over_terrain = 35;
if (test_laplacian) {
double [][] laplacian_in = new double [2 + terrain_scenes_render.length][];
double [][] laplacian_all = new double [2 + terrain_scenes_render.length][];
String [] titles_laplacian = new String[laplacian_in.length];
System.arraycopy(terrain_scenes_render, 0, laplacian_in, 0, terrain_scenes_render.length);
laplacian_in[terrain_scenes_render.length + 0] = terrain_average_render;
laplacian_in[terrain_scenes_render.length + 1] = vegetation_average_render;
titles_laplacian[terrain_scenes_render.length + 0] = "terrain_average";
titles_laplacian[terrain_scenes_render.length + 1] = "vegetation_average";
double weight_diag = .7;
for (int n = 0; n < laplacian_all.length; n++) {
if (n < terrain_scenes_render.length) {
titles_laplacian[n]=scene_names[n];
}
laplacian_in[n] = laplacian_in[n].clone(); // isolate from UM
zerosToNans (
laplacian_in[n], // final double [][] data,
full.width, // final int width,
0.0, // nan_tolerance, // final double tolerance, 0 OK if no UM !
false, // negative_nan, // final boolean negative_nan,
nan_grow); // final int grow)
laplacian_all[n] = VegetationLMA.laplacian(
false, // final boolean gaussian,
laplacian_in[n], // final double [] data_in,
full.width, // final int width,
weight_diag); // final double weight_diag);
ShowDoubleFloatArrays.showArraysHyperstack(
new double [][][]{laplacian_in, laplacian_all}, // double[][][] pixels,
full.width, // int width,
reference_scene+"-laplacian-"+weight_diag+".tiff", // String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
titles_laplacian, // String [] titles, // all slices*frames titles or just slice titles or null
new String[] {"source","laplacian"}, // String [] frame_titles, // frame titles or null
true); // boolean show)
}
laplacian_in[n] = laplacian_in[n].clone(); // isolate from UM
zerosToNans (
laplacian_in[n], // final double [][] data,
full.width, // final int width,
nan_tolerance, // final double tolerance,
nan_grow); // final int grow)
laplacian_all[n] = VegetationLMA.laplacian(
false, // final boolean gaussian,
laplacian_in[n], // final double [] data_in,
full.width, // final int width,
weight_diag); // final double weight_diag);
}
double [][] initial_terrain_vegetation = getInitialTerrainVegetation(
terrain_average_render, // double [] terrain_average_zeros,
vegetation_average_render, // double [] vegetation_average_zeros,
vegetation_warp, // final double [][][] vegetation_warp, // to count all pixels used
full.width, // int width,
shrink_veget, // int shrink_veget,
nan_grow + shrink_veget, // int shrink_terrain) {
vegetation_over_terrain, // double vegetation_over_terrain, // trust vegetation that is hotter than filled terrain
filter_vegetation); //int filter_vegetation) // shrink+grow filtered vegetation to remove small clusters
if (debugLevel > -2){
ShowDoubleFloatArrays.showArraysHyperstack(
new double [][][]{laplacian_in, laplacian_all}, // double[][][] pixels,
full.width, // int width,
reference_scene+"-laplacian-"+weight_diag+".tiff", // String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
titles_laplacian, // String [] titles, // all slices*frames titles or just slice titles or null
new String[] {"source","laplacian"}, // String [] frame_titles, // frame titles or null
true); // boolean show)
ShowDoubleFloatArrays.showArrays(
initial_terrain_vegetation,
full.width,
full.height,
true,
reference_scene+"-terrain_vegetation_conditioned.tiff",
new String[] {"terrain_filled", "vegetation_fiull", "vegetation_filtered"});
}
if (um_en) {
terrain_filled = initial_terrain_vegetation[0];
vegetation_full = initial_terrain_vegetation[1];
vegetation_filtered = initial_terrain_vegetation[2];
zerosToNans (
terrain_scenes_render, // final double [][] data,
full.width, // final int width,
nan_tolerance, // final double tolerance,
false, // final boolean negative_nan,
nan_grow_render); // final int grow)
// maybe it is better to set NaN before UM and then use UM with fillNaN
if (um_en) { // not used anymore
double [][] um_data = new double [terrain_scenes_render.length+2][];
System.arraycopy(terrain_scenes_render, 0, um_data, 0, terrain_scenes_render.length);
um_data[terrain_scenes_render.length + 0] = terrain_average_render;
......@@ -1741,16 +1812,6 @@ public class VegetationModel {
um_sigma, // final double um_sigma,
um_weight); // final double um_weight)
}
// maybe it is better to set NaN before UM and then use UM with fillNaN
zerosToNans (
terrain_scenes_render, // final double [][] data,
full.width, // final int width,
nan_tolerance, // final double tolerance,
nan_grow); // final int grow)
if ((debugLevel > 3) || um_en) {
......@@ -1796,6 +1857,9 @@ public class VegetationModel {
reference_scene+"-terrain_vegetation_averages.tiff",
new String[] {"terrain","vegetation"});
}
VegetationLMA vegetationLMA = new VegetationLMA (this);
......@@ -1838,12 +1902,17 @@ public class VegetationModel {
false, // final boolean keep_parameters,
woi, // final Rectangle woi,
min_scenes, // final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence
min_total_scenes, // final int min_total_scenes,
min_samples_scene, //final int min_samples_scene, // 10
min_pixels, // final int min_pixels,
start_warm_veget, // final boolean start_warm_veget, // start with vegetation warmer than terrain
terrain_warmest, // final double terrain_warmest, // warmest terrain (above is initially vegetation)
initial_split, // final double initial_split, // initial alpha: terrain 0.0+, vegetation 1.0-.
min_split_frac, // final double min_frac, // minimal modality fraction to use split by temperature
terr_difference, // final double terr_difference, // pull vegetation to be this warmer
terr_pull_cold, // final double terr_pull_cold, // pull vegetations to warm, terrain to cold
default_alpha, // final double default_alpha,
hifreq_weight, //final double hifreq_weight, // 22.5 0 - do not use high-freq. Relative weight of laplacian components
reg_weights, // final double reg_weights, // fraction of the total weight used for regularization
alpha_loss, // final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0
alpha_offset, // final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0
......@@ -1897,6 +1966,14 @@ public class VegetationModel {
}
}
if ((show_final_result) && (debugLevel > 0)) {
String reconstructed_title = reference_scene+"-reconstructed-initial";
vegetationLMA.showYfX(
null, // double [] vector,
reconstructed_title); // String title)
}
if (debugLevel > 0) { // make save w/o showing?
vegetationLMA.showYfX(
......@@ -1934,8 +2011,12 @@ public class VegetationModel {
null); // double [] vector)
// continue;
}
if (show_final_result) {
String reconstructed_title = reference_scene+"-reconstructed-"+vegetationLMA.getParametersDebugTitle();
vegetationLMA.showYfX(
null, // double [] vector,
reconstructed_title); // String title)
}
}
return; //
......@@ -2930,6 +3011,7 @@ public class VegetationModel {
final double [][] data,
final int width,
final double tolerance,
final boolean negative_nan,
final int grow) {
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
......@@ -2941,6 +3023,7 @@ public class VegetationModel {
data[n], // double [] data,
width, // int width,
tolerance, // double tolerance,
negative_nan, //final boolean negative_nan,
grow); //int grow)
}
}
......@@ -2950,19 +3033,24 @@ public class VegetationModel {
}
public static void zerosToNans ( // not threaded to be used by threads
double [] data,
int width,
double tolerance,
int grow) {
final double [] data,
final int width,
final double tolerance,
final boolean negative_nan,
final int grow) {
int length = data.length;
int height = length/width;
TileNeibs tn = new TileNeibs(width,height);
boolean [] zeros = new boolean[length];
for (int pix = 0; pix < length; pix++) if (Math.abs(data[pix]) <= tolerance){
int dbg_pix = -(195+130*width);
for (int pix = 0; pix < length; pix++) if ((Math.abs(data[pix]) <= tolerance) || (negative_nan && (data[pix] < 0))){
if (pix == dbg_pix) {
System.out.println("zerosToNans(): pix="+pix);
}
check_zero: {
for (int dir = 0; dir < TileNeibs.DIRS; dir++) { //
int pix1 = tn.getNeibIndex(pix, dir);
if ((pix1 >=0) && (Math.abs(data[pix1]) > tolerance)) {
if ((pix1 >=0) && ((data[pix1] > tolerance) || (!negative_nan && (data[pix1] < -tolerance)))) {
break check_zero;
}
}
......@@ -2978,6 +3066,111 @@ public class VegetationModel {
}
return;
}
public static double [][] getInitialTerrainVegetation(
final double [] terrain_average_zeros,
final double [] vegetation_average_zeros,
final double [][][] vegetation_warp, // to count all pixels used
final int width,
final int shrink_veget,
final int shrink_terrain,
final double vegetation_over_terrain, // trust vegetation that is hotter than filled terrain
final int filter_vegetation) { // shrink+grow filtered vegetation to remove small clusters
boolean debug_img = false; // true;
double [] terrain_filled = terrain_average_zeros.clone();
double [] vegetation_holes = vegetation_average_zeros.clone();
zerosToNans (
vegetation_holes, // final double [][] data,
width, // final int width,
0.0, // nan_tolerance, // final double tolerance, 0 OK if no UM !
true, // negative_nan, // final boolean negative_nan,
shrink_veget); // final int grow)
boolean [] terrain_nan = new boolean [vegetation_holes.length];
for (int i = 0; i < terrain_filled.length; i++){
terrain_nan[i] = !Double.isNaN(vegetation_holes[i]);
}
TileNeibs tn = new TileNeibs(width, terrain_filled.length/width);
tn.growSelection(
shrink_terrain, // 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
terrain_nan, // final boolean [] tiles,
null); // final boolean [] prohibit)
for (int i = 0; i < terrain_filled.length; i++) if (terrain_nan[i]){
terrain_filled[i] = Double.NaN;
}
double [] terrain_dbg = debug_img? terrain_filled.clone() : null;
/*
OrthoMap.fillNaNs(
terrain_holes, // double [] data,
tn, // TileNeibs tn,
3); // int min_neibs)
*/
terrain_filled = TileProcessor.fillNaNs(
terrain_filled, // final double [] data,
null, // final boolean [] prohibit,
width, // int width,
// CAREFUL ! Remaining NaN is grown by unsharp mask filter ************* !
2* width, // 100, // 2*width, // 16, // final int grow,
0.7, // double diagonal_weight, // relative to ortho
100, // int num_passes,
0.03, // final double max_rchange, // = 0.01 - does not need to be accurate
ImageDtt.THREADS_MAX); // final int threadsMax) // maximal number of threads to launch
if (debug_img) {
String [] titles = {"terrain","vegetation","vegetation_nan","terrain_nan","terrain_filled"};
double [][] dbg_img = {terrain_average_zeros,vegetation_average_zeros,vegetation_holes,terrain_dbg,terrain_filled};
ShowDoubleFloatArrays.showArrays(
dbg_img,
width,
terrain_filled.length/width,
true,
"terrain_with_patched_holes",
titles);
}
final double [] vegetation_full = vegetation_average_zeros.clone();
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) { // first sum for pairs
threads[ithread] = new Thread() {
public void run() {
for (int nPix = ai.getAndIncrement(); nPix < vegetation_full.length; nPix = ai.getAndIncrement()) {
check_defined: {
for (int nscene = 0; nscene < vegetation_warp.length; nscene++) {
if (vegetation_warp[nscene][nPix] != null) {
break check_defined;
}
}
vegetation_full[nPix] = Double.NaN;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
double [] vegetation_filtered = vegetation_holes.clone();
boolean [] vegetation_mask = new boolean [vegetation_holes.length];
for (int i = 0; i < vegetation_mask.length; i++) {
vegetation_mask[i] = (vegetation_holes[i] - terrain_filled[i]) >= vegetation_over_terrain;
}
tn.shrinkSelection(
filter_vegetation, // int shrink
vegetation_mask, // final boolean [] tiles,
null); // final boolean [] prohibit)
tn.growSelection(
filter_vegetation, // 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
vegetation_mask, // final boolean [] tiles,
null); // final boolean [] prohibit)
for (int i = 0; i < vegetation_mask.length; i++) if (!vegetation_mask[i]){
vegetation_filtered[i] = Double.NaN;
}
double [][] result = {terrain_filled, vegetation_full, vegetation_filtered} ;
return result;
}
......
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