Commit ada7257a authored by Andrey Filippov's avatar Andrey Filippov

Added full image model rendering

parent 8facfc7c
......@@ -137,6 +137,7 @@ import com.elphel.imagej.tileprocessor.TwoQuadCLT;
import com.elphel.imagej.tileprocessor.lwoc.LwirWorld;
import com.elphel.imagej.vegetation.VegetationModel;
//import com.elphel.imagej.vegetation.VegetationSegment;
import com.elphel.imagej.vegetation.VegetationSynthesis;
import ij.CompositeImage;
import ij.IJ;
......@@ -871,6 +872,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
addButton("Process Merged", panelOrange, color_process);
addButton("Vegetation LMA", panelOrange, color_process);
addButton("Combine LMA Segments", panelOrange, color_process);
addButton("Render synthetic", panelOrange, color_process);
addButton("Generate LWIR target", panelOrange, color_process);
// addButton("Test LDLT Cholesky", panelOrange, color_process);
addButton("Test LLT Cholesky", panelOrange, color_process);
......@@ -5820,6 +5822,11 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
SYNC_COMMAND, // // SyncCommand SYNC_COMMAND,
CLT_PARAMETERS, //CLTParameters clt_parameters,
true); //boolean combine_segments);
} else if (label.equals("Render synthetic")) {
VegetationSynthesis.testSynthetic(
SYNC_COMMAND, // // SyncCommand SYNC_COMMAND,
CLT_PARAMETERS, // CLTParameters clt_parameters,
DEBUG_LEVEL); // final int debugLevel
/*
} else if (label.equals("Test LDLT Cholesky")) {
ImagePlus imp_sel = WindowManager.getCurrentImage();
......
......@@ -256,13 +256,13 @@ public class CorrectionFPN {
for (int nsens = ai.getAndIncrement(); nsens < num_sens; nsens = ai.getAndIncrement()) {
for (int nscene = 0; nscene < num_scenes; nscene++) {
System.arraycopy(
rowcol_data2[2 * nsens + 0],
rowcol_data2[nsens + 0],
nscene*img_width,
rows[nscene][nsens], // data[0][nsens],
0,
width);
System.arraycopy(
rowcol_data2[2 * nsens + 1],
rowcol_data2[nsens + num_sens],
nscene*img_width,
cols[nscene][nsens], // data[1][nsens],
0,
......
......@@ -690,10 +690,21 @@ min_str_neib_fpn 0.35
public double cuas_w_outliers = 0.0001; // Assign weights to outliers to avoid NaNs in bad areas
public double cuas_w_blur = 1.0; // blur thresholded squared values to smooth transitions.
// filters for intersceneExport
public boolean cuas_dsi_parent = false; // Ignore this scene sequence DSI, use parent's
public double cuas_fg_strength = 0.65; // minimal FG strenth to limit disparity with lower Y
public double cuas_disp_add = 0.015; // allow BG (sky) disparity to be slightly higher
public int cuas_skip_bottom = 2; // skip bottom lines while looking for FG
public double cuas_multi_strength = 0.45; // maximal strength to use multi-tile DSI
public boolean cuas_debug = false; // save debug images (and show them if not in batch mode)
public boolean cuas_step_debug = false; // save debug images during per-step cuas recalculation (and show them if not in batch mode)
public boolean cuas_overwrite = false; // overwrite num_orient and num_accum
public int cuas_num_orient = 2; // initial value for num_orient
public int cuas_num_accum = 1; // initial value for num_accum
// TODO: move next parameters elsewhere - they are not the motion blur ones.
public int mb_gain_index_pose = 5; // pose readjust pass to switch to full mb_max_gain from mb_max_gain_inter
public int mb_gain_index_depth = 5; // depth map refine pass (SfM) to switch to full mb_max_gain from mb_max_gain_inter
......@@ -974,6 +985,13 @@ min_str_neib_fpn 0.35
public boolean terr_debug_improved = true; // Save debug data if LMA step improved
public boolean terr_debug_worsened = true; // Save debug data if LMA step improved
// synthesis
public String synth_directory = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/restore_foliage/01/";
public String synth_scene = "1697877490_630338";
public String synth_model = "-preview_segments-0-0-640-512-ACCUM.tiff";
// public String synth_source = "_warps.tiff";
public String synth_render = "_synth-render.tiff";
public boolean synth_crop_real = true; // crop synthetic by real
// public String ter_rendered_path = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/debug/vegetation/essential/1697877491_613999-terrain_vegetation_render.tiff";
......@@ -2068,12 +2086,35 @@ min_str_neib_fpn 0.35
gd.addNumericField("Blur weights", this.cuas_w_blur, 5,7,"pix",
"Blur thresholded squared values to smooth transitions.");
gd.addMessage("=== Sky filters for intersceneExport() ===");
gd.addCheckbox ("Use parent's DSI", this.cuas_dsi_parent,
"Ignore this scene sequence DSI, use parent'se.");
gd.addNumericField("Minimal FG strength", this.cuas_fg_strength, 5,7,"",
"All higher (lower Y) than strong FG should have lower disparity.");
gd.addNumericField("Disparity allowance", this.cuas_disp_add, 5,7,"pix",
"Allow disparity for lower Y to be slightly higher than limit from the strong FG objects.");
gd.addNumericField("Skip bottom rows", this.cuas_skip_bottom, 0,3,"pix",
"Skip bottom rows when determining FG.");
gd.addNumericField("Multi-tile DSI strength", this.cuas_multi_strength, 5,7,"",
"Maximal strength to use multi-tile DSI.");
gd.addMessage("=== Debug ===");
gd.addCheckbox ("Save/show debug images", this.cuas_debug,
"Save CUAS-related debug images and show them in non-batch mode.");
gd.addCheckbox ("Save/show debug images for each tuning step",this.cuas_step_debug,
"Save CUAS-related debug images during per-step cuas recalculation and show them in non-batch mode.");
gd.addCheckbox ("Overwrite number of performed adjustments", this.cuas_overwrite,
"Debug feature: overwrite actual number of performed orientation and disparity refinements to re-run them.");
gd.addNumericField("Value to overwrote num_orient", this.cuas_num_orient, 0,3,"",
"Overwrite value (when Overwrite... is checked).");
gd.addNumericField("Value to overwrote num_accum", this.cuas_num_accum, 0,3,"",
"Overwrite value (when Overwrite... is checked).");
gd.addTab("LMA sequence","Interscene LMA sequence control");
gd.addMessage("Parameters for control of the LMA pose adjustment sequence");
gd.addNumericField("Pose readjust number for full mb_gain", this.mb_gain_index_pose, 0,3,"",
......@@ -2446,7 +2487,13 @@ min_str_neib_fpn 0.35
gd.addCheckbox ("Debug improved", terr_debug_improved, "Save debug image after successful LMA step.");
gd.addCheckbox ("Debug worsened", terr_debug_worsened, "Save debug image after unsuccessful LMA step.");
gd.addTab("Synthesis","Synthesising Terrain/Foloage vies from the model");
gd.addStringField ("Synthesis directory", synth_directory, 120, "Directory with the terrain/foliage model generation files.");
gd.addStringField ("Scene name", synth_scene, 40, "Name (timestamp) of the model.");
gd.addStringField ("Model suffix", synth_model, 120, "File name suffix for the model.");
// gd.addStringField ("Source suffix", synth_source, 120, "File name suffix for the camera images, warps and scales.");
gd.addStringField ("Rendered suffix", synth_render, 120, "Result file name suffix for the rendered synthetic images.");
gd.addCheckbox ("Crop by real", synth_crop_real, "Crop synthetic by real.");
}
public void dialogAnswers(GenericJTabbedDialog gd) {
......@@ -2994,9 +3041,20 @@ min_str_neib_fpn 0.35
this.cuas_w_outliers = gd.getNextNumber();
this.cuas_w_blur = gd.getNextNumber();
this.cuas_dsi_parent = gd.getNextBoolean();
this.cuas_fg_strength = gd.getNextNumber();
this.cuas_disp_add = gd.getNextNumber();
this.cuas_skip_bottom = (int) gd.getNextNumber();
this.cuas_multi_strength = gd.getNextNumber();
this.cuas_debug = gd.getNextBoolean();
this.cuas_step_debug = gd.getNextBoolean();
this.cuas_overwrite = gd.getNextBoolean();
this.cuas_num_orient = (int) gd.getNextNumber();
this.cuas_num_accum = (int) gd.getNextNumber();
this.mb_gain_index_pose = (int) gd.getNextNumber();
this.mb_gain_index_depth =(int) gd.getNextNumber();
......@@ -3287,6 +3345,13 @@ min_str_neib_fpn 0.35
terr_debug_improved = gd.getNextBoolean();// boolean
terr_debug_worsened = gd.getNextBoolean();// boolean
// end of vegetation
// Synthesis
synth_directory = gd.getNextString(); // String
synth_scene = gd.getNextString(); // String
synth_model = gd.getNextString(); // String
// synth_source = gd.getNextString(); // String
synth_render = gd.getNextString(); // String
synth_crop_real = gd.getNextBoolean();// boolean
if (this.weight_zero_neibs > 1.0) this.weight_zero_neibs = 1.0;
}
......@@ -3847,9 +3912,19 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_w_outliers", this.cuas_w_outliers+""); // double
properties.setProperty(prefix+"cuas_w_blur", this.cuas_w_blur+""); // double
properties.setProperty(prefix+"cuas_dsi_parent", this.cuas_dsi_parent+""); // boolean
properties.setProperty(prefix+"cuas_fg_strength", this.cuas_fg_strength+""); // double
properties.setProperty(prefix+"cuas_disp_add", this.cuas_disp_add+""); // double
properties.setProperty(prefix+"cuas_skip_bottom", this.cuas_skip_bottom+""); // int
properties.setProperty(prefix+"cuas_multi_strength", this.cuas_multi_strength+""); // double
properties.setProperty(prefix+"cuas_debug", this.cuas_debug+""); // boolean
properties.setProperty(prefix+"cuas_step_debug", this.cuas_step_debug+""); // boolean
properties.setProperty(prefix+"cuas_overwrite", this.cuas_overwrite+""); // boolean
properties.setProperty(prefix+"cuas_num_orient", this.cuas_num_orient+""); // int
properties.setProperty(prefix+"cuas_num_accum", this.cuas_num_accum+""); // int
properties.setProperty(prefix+"mb_gain_index_pose", this.mb_gain_index_pose+""); // int
properties.setProperty(prefix+"mb_gain_index_depth", this.mb_gain_index_depth+""); // int
......@@ -4112,7 +4187,13 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"terr_debug_improved", terr_debug_improved+""); // boolean
properties.setProperty(prefix+"terr_debug_worsened", terr_debug_worsened+""); // boolean
// end of vegetation
// Synthesis
properties.setProperty(prefix+"synth_directory", synth_directory+""); // String
properties.setProperty(prefix+"synth_scene", synth_scene+""); // String
properties.setProperty(prefix+"synth_model", synth_model+""); // String
// properties.setProperty(prefix+"synth_source", synth_source+""); // String
properties.setProperty(prefix+"synth_render", synth_render+""); // String
properties.setProperty(prefix+"synth_crop_real", synth_crop_real+""); // boolean
}
public void getProperties(String prefix,Properties properties){
......@@ -4674,9 +4755,19 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_w_outliers")!=null) this.cuas_w_outliers=Double.parseDouble(properties.getProperty(prefix+"cuas_w_outliers"));
if (properties.getProperty(prefix+"cuas_w_blur")!=null) this.cuas_w_blur=Double.parseDouble(properties.getProperty(prefix+"cuas_w_blur"));
if (properties.getProperty(prefix+"cuas_dsi_parent")!=null) this.cuas_dsi_parent=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_dsi_parent"));
if (properties.getProperty(prefix+"cuas_fg_strength")!=null) this.cuas_fg_strength=Double.parseDouble(properties.getProperty(prefix+"cuas_fg_strength"));
if (properties.getProperty(prefix+"cuas_disp_add")!=null) this.cuas_disp_add=Double.parseDouble(properties.getProperty(prefix+"cuas_disp_add"));
if (properties.getProperty(prefix+"cuas_skip_bottom")!=null) this.cuas_skip_bottom=Integer.parseInt(properties.getProperty(prefix+"cuas_skip_bottom"));
if (properties.getProperty(prefix+"cuas_multi_strength")!=null) this.cuas_multi_strength=Double.parseDouble(properties.getProperty(prefix+"cuas_multi_strength"));
if (properties.getProperty(prefix+"cuas_debug")!=null) this.cuas_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_debug"));
if (properties.getProperty(prefix+"cuas_step_debug")!=null) this.cuas_step_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_step_debug"));
if (properties.getProperty(prefix+"cuas_overwrite")!=null) this.cuas_overwrite=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_overwrite"));
if (properties.getProperty(prefix+"cuas_num_orient")!=null) this.cuas_num_orient=Integer.parseInt(properties.getProperty(prefix+"cuas_num_orient"));
if (properties.getProperty(prefix+"cuas_num_accum")!=null) this.cuas_num_accum=Integer.parseInt(properties.getProperty(prefix+"cuas_num_accum"));
if (properties.getProperty(prefix+"mb_gain_index_pose")!=null) this.mb_gain_index_pose=Integer.parseInt(properties.getProperty(prefix+"mb_gain_index_pose"));
if (properties.getProperty(prefix+"mb_ers_index")!=null) this.mb_ers_index=Integer.parseInt(properties.getProperty(prefix+"mb_ers_index"));
if (properties.getProperty(prefix+"mb_ers_y_index")!=null) this.mb_ers_y_index=Integer.parseInt(properties.getProperty(prefix+"mb_ers_y_index"));
......@@ -4953,7 +5044,13 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"terr_debug_improved")!= null) terr_debug_improved=Boolean.parseBoolean(properties.getProperty(prefix+"terr_debug_improved"));
if (properties.getProperty(prefix+"terr_debug_worsened")!= null) terr_debug_worsened=Boolean.parseBoolean(properties.getProperty(prefix+"terr_debug_worsened"));
// end of vegetation
// Synthesis
if (properties.getProperty(prefix+"synth_directory")!= null) synth_directory=(String) properties.getProperty(prefix+"synth_directory");
if (properties.getProperty(prefix+"synth_scene")!= null) synth_scene=(String) properties.getProperty(prefix+"synth_scene");
if (properties.getProperty(prefix+"synth_model")!= null) synth_model=(String) properties.getProperty(prefix+"synth_model");
// if (properties.getProperty(prefix+"synth_source")!= null) synth_source=(String) properties.getProperty(prefix+"synth_source");
if (properties.getProperty(prefix+"synth_render")!= null) synth_render=(String) properties.getProperty(prefix+"synth_render");
if (properties.getProperty(prefix+"synth_crop_real")!= null) synth_crop_real=Boolean.parseBoolean(properties.getProperty(prefix+"synth_crop_real"));
}
@Override
......@@ -5502,9 +5599,19 @@ min_str_neib_fpn 0.35
imp.cuas_w_outliers = this.cuas_w_outliers;
imp.cuas_w_blur = this.cuas_w_blur;
imp.cuas_dsi_parent = this.cuas_dsi_parent;
imp.cuas_fg_strength = this.cuas_fg_strength;
imp.cuas_disp_add = this.cuas_disp_add;
imp.cuas_skip_bottom = this.cuas_skip_bottom;
imp.cuas_multi_strength = this.cuas_multi_strength;
imp.cuas_debug = this.cuas_debug;
imp.cuas_step_debug = this.cuas_step_debug;
imp.cuas_overwrite = this.cuas_overwrite;
imp.cuas_num_orient = this.cuas_num_orient;
imp.cuas_num_accum = this.cuas_num_accum;
imp.mb_gain_index_pose = this.mb_gain_index_pose;
imp.mb_gain_index_depth = this.mb_gain_index_depth;
......@@ -5750,7 +5857,13 @@ min_str_neib_fpn 0.35
imp.terr_debug_improved = this.terr_debug_improved;
imp.terr_debug_worsened = this.terr_debug_worsened;
// end of vegetation
// Synthesis
imp.synth_directory = this.synth_directory;
imp.synth_scene = this.synth_scene;
imp.synth_model = this.synth_model;
// imp.synth_source = this.synth_source;
imp.synth_render = this.synth_render;
imp.synth_crop_real = this.synth_crop_real;
return imp;
}
public static long getLongColor(Color color) {
......
......@@ -4970,6 +4970,7 @@ public class OpticalFlow {
center_CLT = QuadCLT.restoreCenterClt(
clt_parameters, // CLTParameters clt_parameters,
clt_parameters.imp.cuas_reset_first, // cuas_reset_first, // boolean ignore_this,
clt_parameters.imp.cuas_dsi_parent, // boolean use_parent_dsi,
quadCLTs[last_index], // ref_index]);
parent_clt_name, // test_path); // String full_path); // if non-null, use it instead of ref_clt
false, // boolean single_first, // true: read single first, cumulative second
......@@ -5367,6 +5368,15 @@ public class OpticalFlow {
System.out.println("Reading row/column noise per-scene data.");
}
row_col = center_CLT.getCorrectionFPN().readImageRowCol();
if (show_fpn && (row_col != null)) {
center_CLT.getCorrectionFPN().saveShowRowCol(
row_col[0], // final double [][][] rows, // [scene][sensor][width]
row_col[1], // final double [][][] cols, // [scene][sensor][height]
false, //final boolean save,
show_fpn); // final boolean show)
}
}
if (row_col == null) {
if (debugLevel >-3) {
......@@ -5688,6 +5698,23 @@ public class OpticalFlow {
ErsCorrection ers_reference = master_CLT.getErsCorrection(); // only used in ml_export
if (!reuse_video) {
if (clt_parameters.imp.cuas_overwrite) {
if (debugLevel > -3) {
System.out.println("Overwriting master_CLT.getNumOrient()="+master_CLT.getNumOrient()+
" of "+min_num_orient+", master_CLT.getNumAccum()="+master_CLT.getNumAccum()+
" of "+min_num_interscene);
}
master_CLT.set_orient(Math.min(clt_parameters.imp.cuas_num_orient, master_CLT.getNumOrient()));
master_CLT.set_accum (Math.min(clt_parameters.imp.cuas_num_accum, master_CLT.getNumAccum()));
if (debugLevel > -3) {
System.out.println("New master_CLT.getNumOrient()="+master_CLT.getNumOrient()+
" of "+min_num_orient+", master_CLT.getNumAccum()="+master_CLT.getNumAccum()+
" of "+min_num_interscene);
}
}
while ((master_CLT.getNumOrient() < min_num_orient) || (master_CLT.getNumAccum() < min_num_interscene)) {
if (debugLevel > -3) {
System.out.println("master_CLT.getNumOrient()="+master_CLT.getNumOrient()+
......@@ -10925,8 +10952,41 @@ public class OpticalFlow {
double [][] combo_dsn = null;
// USE reference scene if no individual DSI are available double [][] dsrbg = scene.getDSRBG(); Probably null for non-reference
// make sure to use already integrated if available
final int margin = 8;
final int tilesX = ref_scene.getTileProcessor().getTilesX();
final int tilesY = ref_scene.getTileProcessor().getTilesY();
final int tiles = tilesX * tilesY;
double [][] combo_dsn0 =ref_scene.readComboDSI(true); // scenes[indx_ref].dsi and blue sky are NOT updated
// temporary fix - filtering sky/no bridges or dim branches
boolean use_cuas = clt_parameters.imp.cuas_rotation && clt_parameters.imp.ims_use;
boolean fix_sky = use_cuas; // clt_parameters
// double min_strength = 0.65;
// double disp_above = 0.015;
// int skip_bottom = 2;
int [] slices = {COMBO_DSN_INDX_DISP,COMBO_DSN_INDX_LMA,COMBO_DSN_INDX_DISP_BG,COMBO_DSN_INDX_LMA_BG,COMBO_DSN_INDX_DISP_FG,COMBO_DSN_INDX_DISP_BG_ALL};
if (fix_sky && (combo_dsn0 != null)) {
combo_dsn0= simpleBlueSky(
combo_dsn0, // final double [][] combo_dsn,
clt_parameters.imp.cuas_fg_strength, // min_strength, // final double min_strength,
clt_parameters.imp.cuas_disp_add, // disp_above, // final double disp_above,
slices, // final int [] slices,
tilesX, // final int tilesX,
tilesY, // final int tilesY,
clt_parameters.imp.cuas_skip_bottom );// skip_bottom); // final int skip_bottom)
if (debug_level > 0) {
ShowDoubleFloatArrays.showArrays(
combo_dsn0,
tilesX,
tilesY,
true,
"combo_dsn-skyed"+ref_scene.getImageName(),
combo_dsn_titles); // dsrbg_titles);
}
}
if (combo_dsn0 == null) {
combo_dsn0 = prepareInitialComboDS( // 3
......@@ -10956,10 +11016,6 @@ public class OpticalFlow {
}
final int margin = 8;
final int tilesX = ref_scene.getTileProcessor().getTilesX();
final int tilesY = ref_scene.getTileProcessor().getTilesY();
final int tiles = tilesX * tilesY;
// uses 2 GB - change format
if (generate_outlines) { // debug_level > 100) { // add parameter?
int extra = 10; // pixels around largest outline
......@@ -11028,7 +11084,7 @@ public class OpticalFlow {
}
}
double [] target_disparity = combo_dsn_change[COMBO_DSN_INDX_DISP].clone();
double [] target_disparity_orig = target_disparity.clone(); // will just use NaN/not NaN to restore tasks before second pass with LMA
/// double [] target_disparity_orig = target_disparity.clone(); // will just use NaN/not NaN to restore tasks before second pass with LMA
// double [][] combo_dsn_final = new double [combo_dsn_titles.length][combo_dsn[0].length];
// double [][] combo_dsn_final =
// new double [(clt_parameters.rig.mll_max_refines_bg > 0)?
......@@ -11089,7 +11145,7 @@ public class OpticalFlow {
// First use reduced number of pairs and no LMA, then continue with all pairs and LMA
boolean bg_refine= false;
final double [][] far_fgbg = new double [selection.length][];
final double [][] pre_split_ds = new double [2][];
/// final double [][] pre_split_ds = new double [2][];
double [][] far_fg_ds = null;
double [][] far_bg_ds = null;
boolean [] sel_split = new boolean [selection.length];
......@@ -11102,11 +11158,32 @@ public class OpticalFlow {
Arrays.fill(used_rms_lma, Double.NaN);
boolean use_rms = true; // DISPARITY_STRENGTH_INDEX means LMA RMS (18/04/2023)
for (int nrefine = 0; nrefine < max_refines; nrefine++) {
//// boolean need_fix_sky = false; // re-run simpleBlueSky() in this pass
if (nrefine == clt_parameters.rig.mll_max_refines_pre) {
min_disp_change = clt_parameters.rig.mll_min_disp_change_lma;
clt_parameters.img_dtt.setMcorr(num_sensors, save_pairs_selection); // restore
clt_parameters.correlate_lma = save_run_lma; // restore
selection = selection_orig.clone();
//// need_fix_sky = true;
if (fix_sky) {
// target_disparity
combo_dsn_change[COMBO_DSN_INDX_DISP]= simpleBlueSky(
combo_dsn_change[COMBO_DSN_INDX_DISP], // final double [] disparity,
combo_dsn_change[COMBO_DSN_INDX_STRENGTH], // final double [] strength,
clt_parameters.imp.cuas_fg_strength, // final double min_strength,
clt_parameters.imp.cuas_disp_add, // final double disp_above,
tilesX, // final int tilesX,
tilesY, // final int tilesY,
clt_parameters.imp.cuas_skip_bottom); // final int skip_bottom)
if (debug_level > -2) {
System.out.println ("Re-applied simpleBlueSky() - needed if target disparity remained wrong FG (from previous sequence)");
}
target_disparity = combo_dsn_change[COMBO_DSN_INDX_DISP].clone();
for (int i = 0; i < target_disparity.length; i++) {
selection[i] = !Double.isNaN(target_disparity[i]);
}
}
if (debug_level > -2) {
int num_tomeas = 0;
for (int nt = 0; nt < target_disparity.length; nt++) if (selection[nt]) { // (!Double.isNaN(target_disparity[nt])){
......@@ -11189,11 +11266,43 @@ public class OpticalFlow {
}
}
int mcorr_sel = Correlation2d.corrSelEncode(clt_parameters.img_dtt,num_sensors);
boolean show_dbg_img = true;
/*if (need_fix_sky) {
double [][] dbg_img = show_dbg_img? new double[3][]: null;
if (dbg_img != null) {
dbg_img[0] = target_disparity.clone();
dbg_img[2] = combo_dsn_change[COMBO_DSN_INDX_STRENGTH].clone();
}
target_disparity = simpleBlueSky(
target_disparity, // final double [] disparity,
combo_dsn_change[COMBO_DSN_INDX_STRENGTH], // final double [] strength,
clt_parameters.imp.cuas_fg_strength, // final double min_strength,
clt_parameters.imp.cuas_disp_add, // final double disp_above,
tilesX, // final int tilesX,
tilesY, // final int tilesY,
clt_parameters.imp.cuas_skip_bottom); // final int skip_bottom)
if (debug_level > -2) {
System.out.println ("Re-applied simpleBlueSky() - needed if target disparity remained wrong FG (from previous sequence)");
}
if (dbg_img != null) {
dbg_img[1] = target_disparity;
String [] dbg_titles = {"td_was","td_now","strength"};
ShowDoubleFloatArrays.showArrays(
dbg_img,
tilesX,
tilesY,
true,
ref_scene.getImageName()+"-td_was_now-"+nrefine,
dbg_titles); // ImageDtt.DISPARITY_TITLES
}
}
*/
double [][] disparity_map =
correlateInterscene( // should skip scenes w/o orientation 06/29/2022
clt_parameters, // final CLTParameters clt_parameters,
scenes, // final QuadCLT [] scenes,
//// indx_ref, // final int indx_ref,
ref_scene, // final QuadCLT ref_scene,
target_disparity, // combo_dsn_change[combo_dsn_indx_disp], // final double [] disparity_ref, // disparity in the reference view tiles (Double.NaN - invalid)
selection, // final boolean [] selection, // may be null, if not null do not process unselected tiles
......@@ -11207,13 +11316,14 @@ public class OpticalFlow {
use_rms, // final boolean use_rms, // DISPARITY_STRENGTH_INDEX means LMA RMS (18/04/2023)
debug_level-8); // final int debug_level)
// if ((need_fix_sky && show_dbg_img) || (debug_level > 0)) { //-3) {
if (debug_level > 0) { //-3) {
ShowDoubleFloatArrays.showArrays(
disparity_map,
tilesX,
tilesY,
true,
"accumulated_disparity_map-"+nrefine,
ref_scene.getImageName()+"accumulated_disparity_map-"+nrefine,
ImageDtt.getDisparityTitles(ref_scene.getNumSensors(),ref_scene.isMonochrome()) // ImageDtt.DISPARITY_TITLES
);
}
......@@ -11239,6 +11349,10 @@ public class OpticalFlow {
double [] map_far_bg_strength = disparity_map[ImageDtt.DISPARITY_INDEX_CM+1];
if (split_pass >= 0) {
if (debug_level > -2) {
System.out.println ("split_pass = "+split_pass+", split_src="+split_src);
}
if (far_split == null) {
far_split = new boolean [nTiles];
}
......@@ -11476,13 +11590,14 @@ public class OpticalFlow {
refine_results[last_initial_slices + (i * max_refines) + nrefine] = combo_dsn_change[iter_indices[i]].clone();
}
// clt_parameters.inp.show_final_2d, // final boolean show_2d_corr,
if (debug_level >0) {
// if ((need_fix_sky && show_dbg_img) || (debug_level > 0)) { //-3) {
if (debug_level > 0) { //-3) {
ShowDoubleFloatArrays.showArrays(
combo_dsn_change,
tilesX,
tilesY,
true,
"combo_dsn-"+nrefine+"-"+ref_scene.getImageName(),
ref_scene.getImageName()+"combo_dsn-"+nrefine+"-"+ref_scene.getImageName(),
combo_dsn_titles); // dsrbg_titles);
}
if (debug_level > -2) {
......@@ -11491,7 +11606,6 @@ public class OpticalFlow {
if (num_tomeas == 0) {
break;
}
} // else { //if (split_pass >= 0) {
} //for (int nrefine = 0; nrefine < max_refines; nrefine++) {
......@@ -11701,6 +11815,69 @@ public class OpticalFlow {
}
public static double [][] simpleBlueSky(
final double [][] combo_dsn,
final double min_strength,
final double disp_above,
final int [] slices,
final int tilesX,
final int tilesY,
final int skip_bottom) { // do not look at the very bottom
double [] strength = combo_dsn[COMBO_DSN_INDX_STRENGTH];
double [][] filtered_dsn = combo_dsn.clone();
for (int slice:slices) {
filtered_dsn[slice] = simpleBlueSky(
combo_dsn[slice], // final double [] disparity,
strength, // final double [] strength,
min_strength, // final double min_strength,
disp_above, // final double disp_above,
tilesX, // final int tilesX,
tilesY, // final int tilesY,
skip_bottom); // final int skip_bottom)
}
return filtered_dsn;
}
public static double [] simpleBlueSky(
final double [] disparity,
final double [] strength,
final double min_strength,
final double disp_above,
final int tilesX,
final int tilesY,
final int skip_bottom) { // do not look at the very bottom
double [] filtered_disparity = disparity.clone();
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int tileX = ai.getAndIncrement(); tileX < tilesX; tileX = ai.getAndIncrement()) {
double lim = Double.NaN;
for (int tileY = tilesY-1-skip_bottom; tileY >= 0; tileY--) {
int indx = tileX + tileY * tilesX;
double d = filtered_disparity[indx];
if (!Double.isNaN(d)) {
if (strength[indx] > min_strength) { // NaN OK
if (!(d >= lim)) { // NaN OK
lim = d;
}
} else if (d > (lim + disp_above)) {
filtered_disparity[indx] = lim + disp_above;
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return filtered_disparity;
}
public static boolean [] calcFarFgBg(
......
......@@ -805,6 +805,7 @@ public class QuadCLTCPU {
* Read (try to read) this first, maybe parent is not needed (yet)
* @param clt_parameters
* @param ignore_this do not merge this sequence CLT data, only use parent's cumulative
* @param use_parent_dsi - use parent DSI even if this exists
* @param ref_clt
* @param full_path
* @param single_first true: read single first, cumulative second, false - read cumulative first
......@@ -814,6 +815,7 @@ public class QuadCLTCPU {
public static QuadCLT restoreCenterClt(
CLTParameters clt_parameters,
boolean ignore_this,
boolean use_parent_dsi,
QuadCLT ref_clt , // latest
String full_path, // if non-null, use it instead of ref_clt
boolean single_first, // true: read single first, cumulative second
......@@ -915,11 +917,14 @@ public class QuadCLTCPU {
System.out.println("restoreCenterClt(): parent directory is not provided, and this model data does not exist - bailing out.");
return null;
}
if (center_CLT == null) { // so parent parentCuasData and parent_dsi both exist
if (use_parent_dsi || (center_CLT == null)) { // so parent parentCuasData and parent_dsi both exist
// Create new center_CLT
if (center_CLT == null) {
center_CLT = new QuadCLT(ref_clt, center_name);
center_CLT.setImagePath(cdir.getPath()); // *********************
cdir.mkdirs();
cuasData = parentCuasData; // will be collapsed in one place
}
center_CLT.setDSIFromCombo(parent_dsi); // set center DSI from parent
String rslt_suffix = "-INTER-INTRA";
if (!clt_parameters.correlate_lma){
......@@ -934,7 +939,7 @@ public class QuadCLTCPU {
center_CLT.getTilesX(), // int width,
center_CLT.getTilesY()); // int height)
center_CLT.setDSIFromCombo(parent_dsi);
cuasData = parentCuasData; // will be collapsed in one place
// cuasData = parentCuasData; // will be collapsed in one place
} else { // if (center_CLT == null) {
if (parentCuasData != null) { // both exist - combine
boolean en_create = true;
......@@ -4645,13 +4650,13 @@ public class QuadCLTCPU {
DSI_SUFFIXES[INDEX_INTER_LMA], // String suffix, // "-DSI_COMBO", "-DSI_MAIN" (DSI_COMBO_SUFFIX, DSI_MAIN_SUFFIX)
null, // double [][] dsi, // if null - just check file exists
true); // boolean silent);
if (num_slices >= 0) {
/* if (num_slices >= 0) {
return true;
}
num_slices = restoreDSI(
DSI_SUFFIXES[INDEX_INTER], // String suffix, // "-DSI_COMBO", "-DSI_MAIN" (DSI_COMBO_SUFFIX, DSI_MAIN_SUFFIX)
null, // double [][] dsi, // if null - just check file exists
true); // boolean silent);
true); // boolean silent); */
return num_slices >= 0;
}
......
......@@ -43,8 +43,8 @@ public class VegetationLMA {
public static final int TVAO_VEGETATION = 1;
public static final int TVAO_ALPHA = 2;
public static final int TVAO_ELEVATION = 3;
public static final int TVAO_TERR_ELEV = 4;
public static final int TVAO_TERR_ELEV_PIX = 5;
public static final int TVAO_TERR_ELEV = 4; // common for all the tile
public static final int TVAO_TERR_ELEV_PIX = 5; // per-pixel terrain elevation
public static final int TVAO_SCENE_OFFSET = 6;
public static final int TVAO_TYPES = TVAO_SCENE_OFFSET + 1;
......@@ -439,7 +439,7 @@ public class VegetationLMA {
return;
}
private static double [][][] getScalesXY(
public static double [][][] getScalesXY(
final double [][][] scales_mag_dir) {
final int num_scenes = scales_mag_dir.length;
final int num_pixels = scales_mag_dir[0].length;
......
......@@ -92,6 +92,14 @@ public class VegetationModel {
public String src_dir = null;
public String src_title = null;
public String [] getSceneNames() {
return scene_names;
}
public double [][] getTerrainScenesRendered(){
return terrain_scenes_render;
}
public double [][] tva;
int step_restore;
......@@ -1481,7 +1489,7 @@ public class VegetationModel {
// boolean
tile_woi = clt_parameters.imp.terr_tile_woi; // scan woi_enclosing, false - run a single woi_last
tile_woi = clt_parameters.imp.terr_tile_woi || combine_segments; // scan woi_enclosing, false - run a single woi_last
Rectangle woi_enclosing = clt_parameters.imp.terr_woi_enclos; // new Rectangle(0, 0, 200, 160); // will be tiled, using width/height from woi_step;
Rectangle woi_step = clt_parameters.imp.terr_woi_step; // new Rectangle(10,10,20,20);
Rectangle woi_last = clt_parameters.imp.terr_woi_last; // new Rectangle(160,310,20,20); // 170
......
......@@ -98,7 +98,7 @@ public class VegetationSegment {
int out_length = out_woi.width*out_woi.height;
int accum_indx = segments.length;
String [] top_titles = {"terrain","vegetation","alpha","elevation","terrain_elevation","confidence"};
double [][][] preview_data = new double [top_titles.length][accum_indx+1][out_length];
double [][][] preview_data = new double [top_titles.length][accum_indx+1][out_length]; // Java heap space
String [] titles = new String[accum_indx+1];
for (int ns = 0; ns < segments.length; ns++) {
Rectangle woi = segments[ns].woi; // for confidence and limits for terrain
......
package com.elphel.imagej.vegetation;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.correction.SyncCommand;
import com.elphel.imagej.tileprocessor.ImageDtt;
import com.elphel.imagej.tileprocessor.QuadCLT;
import ij.ImagePlus;
import ij.Prefs;
import ij.io.FileSaver;
public class VegetationSynthesis {
final double [][] tvae;
final double [][][] scales_xy; // x,y offset pairs or null for each scene, each pixel.
final Rectangle full;
// elevation-dependent parameters, calculated once if elevations are not adjusted or each time if they are
private double [] elev_radius; // for the future - make variable-size influence of the vegetation to mitigate far influenced pixels
private double elev_radius_extra = 1.2; // scale both radii when setupElevationLMA(), setupTerrainElevationLMA(), and setupTerrainElevationPixLMA()
private int [][][] elev_woi4; // [scene][woi_veg][~4] indices (in woi) of 4 (or more/less) neighbors of projections (negatives)
private double [][][] elev_weights4; // [scene][woi_veg][~4] weights of influence for 4 neighbors
private double [][] elev_sum_weights; // [scene][woi] sum weights from up to 4 elevation pixels (even more with overlap)
private final int num_scenes;
private final int num_pixels;
private boolean [] valid_scenes;
private double terr_elev_radius = 1.5; // for the future - make variable-size influence of the vegetation to mitigate far influenced pixels
private int [][][] terr_elpix_woi4; // [scene][woi_veg][~4] indices (in woi) of 4 (or more/less) neighbors of projections (negatives)
private double [][][] terr_elpix_weights4; // [scene][woi_veg][~4] weights of influence for 4 neighbors
private double [][] terr_elpix_sum_weights; // [scene][woi] sum weights from up to 4 elevation pixels (even more with overlap)
private boolean alpha_piece_linear = true; // (+)
public static boolean testSynthetic(
SyncCommand SYNC_COMMAND,
final CLTParameters clt_parameters,
final int debugLevel) {
String model_directory = clt_parameters.imp.terr_model_path; // Model directory path with version.
String model_state_file = clt_parameters.imp.terr_model_state; // Model vegetation source data (w/o extension).
String synth_directory = clt_parameters.imp.synth_directory; // "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/restore_foliage/01/";
String synth_scene = clt_parameters.imp.synth_scene; // "1697877490_630338";
String synth_model = clt_parameters.imp.synth_model; // "-preview_segments-0-0-640-512-ACCUM.tiff";
String synth_render_suffix = clt_parameters.imp.synth_render; // "_synth-render.tiff";
boolean synth_crop_real = clt_parameters.imp.synth_crop_real;
boolean update = false;
GenericJTabbedDialog gd = new GenericJTabbedDialog("Set synthesis parameters",900,300);
gd.addStringField ("3D Model directory", model_directory, 120, "Directory with 3D model to extract X,Y scales and captured images.");
gd.addStringField ("3D Model state file", model_state_file, 120,"3D model state file with images, elevation and scales as absolute values and directions.");
gd.addStringField ("Synthesis directory", synth_directory, 120, "Directory with the terrain/foliage model generation files.");
gd.addStringField ("Scene name", synth_scene, 40, "Name (timestamp) of the model.");
gd.addStringField ("Model suffix", synth_model, 120, "File name suffix for the model.");
gd.addStringField ("Rendered suffix", synth_render_suffix, 120, "Result file name suffix for the rendered synthetic images.");
gd.addCheckbox ("Crop by real", synth_crop_real, "Crop synthetic by real.");
gd.addCheckbox ("Update settings", update, "Update settings in the global parameters (wil require saving).");
gd.showDialog();
if (gd.wasCanceled()) return false;
model_directory = gd.getNextString(); // String
model_state_file = gd.getNextString(); // String
synth_directory = gd.getNextString(); // String
synth_scene = gd.getNextString(); // String
synth_model = gd.getNextString(); // String
synth_render_suffix = gd.getNextString(); // String
synth_crop_real = gd.getNextBoolean();
update = gd.getNextBoolean();// boolean
if (update) {
clt_parameters.imp.terr_model_path = model_directory;
clt_parameters.imp.terr_model_state = model_state_file;
clt_parameters.imp.synth_directory = synth_directory;
clt_parameters.imp.synth_scene = synth_scene;
clt_parameters.imp.synth_model = synth_model;
clt_parameters.imp.synth_render = synth_render_suffix;
clt_parameters.imp.synth_crop_real = synth_crop_real;
}
if (!synth_directory.endsWith(Prefs.getFileSeparator())) {
synth_directory+=Prefs.getFileSeparator();
}
VegetationModel vegetationModel = new VegetationModel(
model_directory, // String dir,
model_state_file, // String title)
SYNC_COMMAND); // SyncCommand SYNC_COMMAND,
double [][][] scales_xy = VegetationLMA.getScalesXY(vegetationModel.scale_dirs);
String [] scene_names = vegetationModel.getSceneNames();
// Read the model warps
String path_model = synth_directory+synth_scene+synth_model;
ImagePlus imp_model = new ImagePlus(path_model);
if (imp_model.getWidth() == 0) {
System.out.println("testSynthetic(): Failed reading model from: " + path_model);
return false;
}
int [] wh = new int [2];
int model_slices = imp_model.getStackSize();
System.out.println("testSynthetic(): read model from: " + path_model+", got "+model_slices+" slices");
double [][] model_data = QuadCLT.readDoubleArray(
imp_model, // ImagePlus imp,
0, // int num_slices, // (0 - all)
wh); // int [] wh); // int [] wh)
int width = wh[0];
int height = wh[1];
int num_scenes = scales_xy.length;
int num_pixels = width*height;
double [] scene_offsets = new double[num_scenes]; // so far - no offsets, see what to use - average for the full images?
double elevation_radius = clt_parameters.imp.terr_elevation_radius; // Radius of elevation/vegetation influence
double terr_elev_radius = clt_parameters.imp.terr_terr_elev_radius; // Terrain elevation radius
double [] elev_radius = new double [num_pixels];
Arrays.fill(elev_radius, elevation_radius); // 5);
VegetationSynthesis vegetationSynthesis = new VegetationSynthesis(
model_data[0], // double [] terrain,
model_data[1], // double [] vegetation,
model_data[2], // double [] alpha,
model_data[3], // double [] elevation, // has NaN (more than vegetation)
model_data[4], // double [] terrain_elevation, // pix
scene_offsets, // double [] scene_offsets,
scales_xy, // double [][][] scales_xy, // per scene, per tile, xy offsets per elevation or null
width, // int width)
elev_radius, // double [] elev_radius,
terr_elev_radius); // double terr_elev_radius){
double [][] rendered_model = vegetationSynthesis.renderModel (
debugLevel); // final int debugLevel)
double [][] captured_images = vegetationModel.getTerrainScenesRendered();
if (synth_crop_real) {
maskSynthByReal(
rendered_model, // final double [][] synth, // will be modified
captured_images); // final double [][] captured) { // extracted NaN-s
}
String rendered_title = synth_directory + synth_scene + (synth_crop_real?"-masked":"") +synth_render_suffix;
ImagePlus imp = ShowDoubleFloatArrays.makeArrays(
rendered_model, // double[][] pixels,
width,// int width,
height,// int height,
rendered_title, // String title,
scene_names); // String [] titles)
if (imp != null) {
imp.show();
String file_path = rendered_title;
if (!file_path.endsWith(".tiff")) {
file_path +=".tiff";
}
FileSaver fs=new FileSaver(imp);
fs.saveAsTiff(file_path);
System.out.println("testSynthetic(): saved rendered images to "+file_path);
}
double [][] diffYminusfX = new double [num_scenes][num_pixels];
for (int nscene = 0; nscene <num_scenes;nscene++) {
for (int npix = 0; npix < num_pixels; npix++) {
diffYminusfX[nscene][npix] = captured_images[nscene][npix] - rendered_model[nscene][npix];
}
}
double [][][] compareYfX = {captured_images, rendered_model, diffYminusfX};
String [] top_titles = {"captured", "synthesized", "captured-synthesized"};
String compare_title = synth_directory + synth_scene + (synth_crop_real?"-masked":"")+ "-compare"+ synth_render_suffix;
ImagePlus imp_diff= ShowDoubleFloatArrays.showArraysHyperstack(
compareYfX, // double[][][] pixels,
width, // int width,
compare_title, // String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
scene_names, // String [] titles, // all slices*frames titles or just slice titles or null
top_titles, // String [] frame_titles, // frame titles or null
true); // boolean show)
if (imp_diff != null) {
String compare_path = compare_title;
if (!compare_path.endsWith(".tiff")) {
compare_path +=".tiff";
}
FileSaver fs=new FileSaver(imp_diff);
fs.saveAsTiff(compare_path);
System.out.println("testSynthetic(): saved captured to rendered images comparison to "+compare_path);
}
return true;
}
public static void maskSynthByReal(
final double [][] synth, // will be modified
final double [][] captured) { // extracted NaN-s
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nScene = ai.getAndIncrement(); nScene < synth.length; nScene = ai.getAndIncrement()) {
for (int npix = 0; npix < synth[nScene].length; npix++) if (Double.isNaN(captured[nScene][npix])) {
synth[nScene][npix] = Double.NaN;
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return;
}
public VegetationSynthesis(
double [] terrain,
double [] vegetation,
double [] alpha,
double [] elevation,
double [] terrain_elevation, // pix
double [] scene_offsets,
double [][][] scales_xy, // per scene, per tile, xy offsets per elevation or null
int width,
double [] elev_radius,
double terr_elev_radius){
num_scenes = scene_offsets.length;
num_pixels = terrain.length;
full = new Rectangle(0,0,width, num_pixels/width);
tvae = new double [VegetationLMA.TVAO_TYPES][];
tvae[VegetationLMA.TVAO_TERRAIN] = terrain;
tvae[VegetationLMA.TVAO_VEGETATION] = vegetation.clone(); // should be NaN if alpha or elevation is NaN
tvae[VegetationLMA.TVAO_ALPHA] = alpha;
tvae[VegetationLMA.TVAO_ELEVATION] = elevation;
for (int i = 0; i < vegetation.length; i++) {
if (Double.isNaN(alpha[i]) || Double.isNaN(elevation[i])) {
tvae[VegetationLMA.TVAO_VEGETATION][i] = Double.NaN;
}
}
tvae[VegetationLMA.TVAO_TERR_ELEV_PIX] = terrain_elevation;
tvae[VegetationLMA.TVAO_SCENE_OFFSET] = scene_offsets;
this.scales_xy = scales_xy;
valid_scenes = new boolean [num_scenes];
Arrays.fill(valid_scenes, true);
this.elev_radius = elev_radius;
this.terr_elev_radius = terr_elev_radius;
return;
}
public double [][] renderModel (
final int debugLevel) {
final double [][] render = new double [num_scenes][num_pixels];
for (int nscene = 0; nscene < num_scenes; nscene++) {
Arrays.fill(render[nscene], Double.NaN);
}
setupElevationLMA(
debugLevel); // final int debugLevel);
setupTerrainElevationPixLMA(
terr_elev_radius, // final double radius,
debugLevel); // final int debugLevel);
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final int dbg_scene = -9; // -105; // -20;
final int dbg_windex = -234; // -1;
final int dbg_wtindex = -340; // -1;
final int dbg_findx = -121775;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// vegetation projections to terrain/y_vector/fX pixels
double [] alpha_woi = new double [num_pixels];
double [] veget_woi = new double [num_pixels];
double [] terrain_woi = new double [num_pixels]; // needs to be divided by terrain_woi_weights
for (int nScene = ai.getAndIncrement(); nScene < num_scenes; nScene = ai.getAndIncrement()) if (valid_scenes[nScene]){
Arrays.fill(alpha_woi,0);
Arrays.fill(veget_woi,0);
Arrays.fill(terrain_woi, 0);
double scene_offset = (tvae[VegetationLMA.TVAO_SCENE_OFFSET] != null) ? tvae[VegetationLMA.TVAO_SCENE_OFFSET][nScene]: 0;
double [] vegetation_scene = tvae[VegetationLMA.TVAO_VEGETATION];
double [] alpha_scene = tvae[VegetationLMA.TVAO_ALPHA];
double [] terrain_scene = tvae[VegetationLMA.TVAO_TERRAIN];
// process vegetation, here individually by pixel, if it is not NaN
for (int wvindex = 0; wvindex < num_pixels; wvindex++) if (!Double.isNaN(vegetation_scene[wvindex])) {
int x = wvindex % full.width; // relative to woi_veg
int y = wvindex / full.width; // relative to woi_veg
int npix = x + y * full.width;
if (npix == dbg_findx) {
System.out.println("getFxDerivs() 1: findx="+npix);
}
double vegetation = vegetation_scene[npix];
double alpha = alpha_scene[npix];
int [] result_woi_ind = elev_woi4[nScene][wvindex]; // list of output pixels influenced by each vegetation pixel
if (result_woi_ind != null) {
double [] result_woi_weights = elev_weights4[nScene][wvindex];// same vegetation pixel, per result neighbor
for (int i = 0; i < result_woi_ind.length; i++) {
int windx = result_woi_ind[i];
if (windx >= 0) {
double w = result_woi_weights[i];
veget_woi[windx] += w * vegetation; // accumulate vegetation for the same result pixel
alpha_woi[windx] += w * alpha; // accumulate alpha for the same result pixel
}
}
}
} // for (int wvindex = 0; wvindex < woi_veg_length; wvindex++) if (valid_vegetation[wvindex]) {
if (terr_elpix_woi4 != null) { // per-pixel terrain elevation. Make mutually-exclusive with terr_elev_woi4
for (int wtindex = 0; wtindex < num_pixels; wtindex++) if ((terr_elpix_woi4[nScene] != null) && (terr_elpix_woi4[nScene][wtindex] != null)) {
int x = wtindex % full.width; // relative to woi_terr
int y = wtindex / full.width; // relative to woi_terr
int npix = x + y * full.width;
if (npix == dbg_findx) {
System.out.println("getFxDerivs() 2a: findx="+npix);
}
if ((wtindex== dbg_wtindex) && (nScene ==dbg_scene)) {
System.out.println("getFxDerivs() 2a: nScene="+nScene+", windx="+wtindex);
}
double terrain = terrain_scene[npix]; // [woi_terr], adjusted/elevated terrain
int [] result_woi_ind = terr_elpix_woi4[nScene][wtindex]; // list of output pixels influenced by each terrain pixel
if (result_woi_ind != null) { // now always
double [] result_woi_weights = terr_elpix_weights4[nScene][wtindex];// same terrain pixel, per result neighbor
for (int i = 0; i < result_woi_ind.length; i++) {
int windx = result_woi_ind[i];
if (windx >= 0) {
double stw = terr_elpix_sum_weights[nScene][windx];
if (stw > 0) {
double w = result_woi_weights[i]; /// /stw; // moved division to the woi domain (single division)
terrain_woi[windx] += w * terrain; // accumulate terrain contributors for the same terrain output pixel (wiil need division by terrain_woi_weights)
} else {
System.out.println("getFxDerivs(): BUG: stw=terr_elpix_sum_weights["+nScene+"]["+windx+"] ="+stw);
}
}
}
}
}
} // if (terr_elpix_woi4 != null) {
// projecting vegetation
for (int windx = 0; windx < num_pixels; windx++) if (!Double.isNaN(terrain_scene[windx])) { //(valid_terr_proj[windx]) {
if ((windx== dbg_windex) && (nScene ==dbg_scene)) {
System.out.println("getFxDerivs() nScene="+nScene+", windx="+windx);
}
int x = windx % full.width; // relative to woi
int y = windx / full.width; // relative to woi
int npix = x + y * full.width;
if (npix == dbg_findx) {
System.out.println("getFxDerivs() 3: findx="+npix);
}
double terrain = 0;
double stw = 0;
stw = terr_elpix_sum_weights[nScene][windx];
if (stw > 0) {
terrain = terrain_woi[windx]/stw;// /terr_elev_sum_weights[nScene][windx]; // it already combines parameters and constants, divided by terr_elev_sum_weights[nScene][windx]
}
double d = terrain; // combined from neighbors if needed
double sw = elev_sum_weights[nScene][windx];
if (sw > 0) { // OK, non-zero
double avg_veget = veget_woi[windx] / sw;
double avg_alpha = alpha_woi[windx] / sw;
if (Double.isNaN(avg_veget) || Double.isNaN(avg_alpha)) {
System.out.println("getFxDerivs(): BUG: avg_veget="+avg_veget+", avg_alpha="+avg_alpha+",nScene="+nScene+", windx="+windx+". Restored with different overlaid?");
} else {
double k;
if (alpha_piece_linear) {
k = (avg_alpha < 0)? 0: ((avg_alpha > 1) ? 1.0: avg_alpha);
} else {
k = (avg_alpha < 0)? 0: ((avg_alpha > 1) ? 1.0: 0.5 * (1.0 - Math.cos(avg_alpha*Math.PI)));
}
d = terrain * (1.0 - k) + avg_veget * k;
}
} else { // terrain-only pixel (sw=0)
d = terrain;
}
render[nScene][windx] = d + scene_offset;
} // for (int windx = 0; windx < woi_length; windx++) if (valid_terrain[windx]) {
} // for (int nScene = ai.getAndIncrement(); nScene < num_scenes; nScene = ai.getAndIncrement()) if (valid_scenes[nScene]){
}
};
}
ImageDtt.startAndJoin(threads);
return render;
}
private void setupElevationLMA( // return pivot?
final int debugLevel) {
final double [] vegetation = tvae[VegetationLMA.TVAO_VEGETATION]; //
elev_woi4 = new int [num_scenes][][];
elev_weights4 = new double [num_scenes][][];
elev_sum_weights = new double [num_scenes][];
//elev_radius[num_pixels];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [] wnd_x = new double [3];
for (int nScene = ai.getAndIncrement(); nScene < num_scenes; nScene = ai.getAndIncrement()) if (valid_scenes[nScene]){
elev_woi4[nScene] = new int [num_pixels][];
elev_weights4[nScene] = new double [num_pixels][];
elev_sum_weights[nScene] = new double [num_pixels];
for (int npix = 0; npix < num_pixels; npix++) if (!Double.isNaN(vegetation[npix])) { //
int x = npix % full.width; // relative to woi_veg
int y = npix / full.width; // relative to woi_veg
int fnpix = x + y * full.width;
double elevation = tvae[VegetationLMA.TVAO_ELEVATION][npix];
double [] scales = scales_xy[nScene][fnpix];
double radius = elev_radius[fnpix] * elev_radius_extra; // *1.2;
double px = x + scales[0] * elevation; // ELEV-SIGN
double py = y + scales[1] * elevation; // ELEV-SIGN
double px0 = px - radius, py0 = py - radius;
int ipx0 = (int) Math.floor(px0) + 1;
int ipy0 = (int) Math.floor(py0) + 1;
double px1 = px+radius, py1 = py+radius;
int ipx1 = (int) Math.ceil(px1) - 1;
int ipy1 = (int) Math.ceil(py1) -1;
int dia_y = ipy1-ipy0+1;
int dia_x = ipx1-ipx0+1;
int dia2 = dia_y*dia_x;
if (wnd_x.length < dia_x) {
wnd_x = new double[dia_x];
}
Arrays.fill(wnd_x, Double.NaN);
for (int ipy = ipy0; ipy < py1; ipy++) if (ipy >= full.y){
if (ipy >= full.height) break;
//int wpy = ipy-woi.y; // ==ipy
double wnd_y = 0.5*(1.0+Math.cos((ipy-py)*Math.PI/radius));
int dy = ipy - ipy0;
for (int ipx = ipx0; ipx < px1; ipx++) if (ipx >= full.x){
if (ipx >= full.width) break;
// int wpx = ipx-woi.x; // == ipx
int wpindex = ipx + ipy*full.width;
if (!Double.isNaN(vegetation[npix])) { // has_vegetation[wpindex]) {
if (elev_woi4[nScene][npix] == null) {
elev_woi4[nScene][npix] = new int[dia2]; // meter2];
Arrays.fill(elev_woi4[nScene][npix], -1);
elev_weights4[nScene][npix] = new double[dia2]; // meter2];meter2];
}
int dx = ipx - ipx0;
int dindx = dx + dy*dia_x; // meter;
elev_woi4[nScene][npix][dindx] = wpindex;
if (Double.isNaN(wnd_x[dx])) {
wnd_x[dx]=0.5*(1.0+Math.cos((ipx-px)*Math.PI/radius));
}
double ww= wnd_y*wnd_x[dx];
elev_weights4[nScene][npix][dindx] = ww;
elev_sum_weights[nScene][wpindex] += ww;
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (debugLevel > 6) {
String title = "setupElevationLMA.tiff";
String [] titles = new String [num_scenes];
String [] top_titles = {"sum_weights","contribs"};
double [][][] dbg_img = new double [top_titles.length][num_scenes][];
for (int nscene = 0; nscene < num_scenes; nscene++) {
titles[nscene]= "scene_"+nscene;
if (valid_scenes[nscene]) {
for (int t = 0; t < dbg_img.length; t++) {
dbg_img[t][nscene] = new double [num_pixels];
Arrays.fill(dbg_img[t][nscene], Double.NaN);
}
for (int i = 0; i < num_pixels; i++) {
dbg_img[0][nscene][i] = elev_sum_weights[nscene][i];
}
}
}
ShowDoubleFloatArrays.showArraysHyperstack(
dbg_img, // double[][][] pixels,
full.width, // int width,
title, // "terrain_vegetation_render.tiff", // String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
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;
}
private void setupTerrainElevationPixLMA(
final double radius,
final int debugLevel) {
final double [] terrain = tvae[VegetationLMA.TVAO_TERRAIN]; //
final double [] terrain_elevation = tvae[VegetationLMA.TVAO_TERR_ELEV_PIX]; //
terr_elpix_woi4 = new int [num_scenes][][];
terr_elpix_weights4 = new double [num_scenes][][];
terr_elpix_sum_weights = new double [num_scenes][];
//elev_radius[num_pixels];
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
double [] wnd_x = new double [3];
for (int nScene = ai.getAndIncrement(); nScene < num_scenes; nScene = ai.getAndIncrement()) if (valid_scenes[nScene]){
terr_elpix_woi4[nScene] = new int [num_pixels][];
terr_elpix_weights4[nScene] = new double [num_pixels][];
terr_elpix_sum_weights[nScene] = new double [num_pixels];
for (int wtindex = 0; wtindex < num_pixels; wtindex++) if (!Double.isNaN(terrain[wtindex])) {
int x = wtindex % full.width; // relative to woi_veg
int y = wtindex / full.width; // relative to woi_veg
int fnpix = x + y * full.width;
double terr_elev = terrain_elevation[fnpix];
if (Double.isNaN(terr_elev)) {
terr_elev = 0.0;
}
double [] scales = scales_xy[nScene][fnpix];
double px = x + scales[0] * terr_elev; // ELEV-SIGN
double py = y + scales[1] * terr_elev; // ELEV-SIGN
double px0 = px - radius, py0 = py - radius;
int ipx0 = (int) Math.floor(px0) + 1;
int ipy0 = (int) Math.floor(py0) + 1;
double px1 = px+radius, py1 = py+radius;
int ipx1 = (int) Math.ceil(px1) - 1;
int ipy1 = (int) Math.ceil(py1) -1;
int dia_y = ipy1-ipy0+1;
int dia_x = ipx1-ipx0+1;
int dia2 = dia_y*dia_x;
if (wnd_x.length < dia_x) {
wnd_x = new double[dia_x];
}
Arrays.fill(wnd_x, Double.NaN);
for (int ipy = ipy0; ipy < py1; ipy++) if (ipy >= full.y){ // 0
if (ipy >= full.height) break;
int wpy = ipy-full.y;
double wnd_y = 0.5*(1.0+Math.cos((ipy-py)*Math.PI/radius));
int dy = ipy - ipy0;
for (int ipx = ipx0; ipx < px1; ipx++) if (ipx >= full.x){
if (ipx >= full.width) break;
int wpx = ipx-full.x;
int wpindex = wpx + wpy*full.width;
if (!Double.isNaN(terrain[wpindex])) {
if (terr_elpix_woi4[nScene][wtindex] == null) {
terr_elpix_woi4[nScene][wtindex] = new int[dia2]; // meter2];
Arrays.fill(terr_elpix_woi4[nScene][wtindex], -1);
terr_elpix_weights4[nScene][wtindex] = new double[dia2]; // meter2];meter2];
}
int dx = ipx - ipx0;
int dindx = dx + dy*dia_x; // meter;
terr_elpix_woi4[nScene][wtindex][dindx] = wpindex;
if (Double.isNaN(wnd_x[dx])) {
wnd_x[dx]=0.5*(1.0+Math.cos((ipx-px)*Math.PI/radius));
}
double ww= wnd_y*wnd_x[dx];
terr_elpix_weights4[nScene][wtindex][dindx] = ww;
terr_elpix_sum_weights[nScene][wpindex] += ww;
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (debugLevel > 6) {
String title = "setupTerrainElevationPixLMA.tiff";
String [] titles = new String [num_scenes];
String [] top_titles = {"sum_weights","contribs"};
double [][][] dbg_img = new double [top_titles.length][num_scenes][];
for (int nscene = 0; nscene < num_scenes; nscene++) {
titles[nscene]= "scene_"+nscene;
if (valid_scenes[nscene]) {
for (int t = 0; t < dbg_img.length; t++) {
dbg_img[t][nscene] = new double [num_pixels];
Arrays.fill(dbg_img[t][nscene], Double.NaN);
}
for (int i = 0; i < num_pixels; i++) {
dbg_img[0][nscene][i] = terr_elpix_sum_weights[nscene][i];
}
}
}
ShowDoubleFloatArrays.showArraysHyperstack(
dbg_img, // double[][][] pixels,
full.width, // int width,
title, // "terrain_vegetation_render.tiff", // String title, "time_derivs-rt"+diff_time_rt+"-rxy"+diff_time_rxy,
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;
}
}
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