Commit 108cab36 authored by Andrey Filippov's avatar Andrey Filippov

working snapshot, running composite

parent f2072077
......@@ -768,6 +768,7 @@ min_str_neib_fpn 0.35
public double terr_max_warp = 1.8;
public int terr_max_elevation = 22; // maximal offset to consider when looking for vegetation influence
public int terr_max_elev_terr = 2; // maximal offset to consider when looking for terrain of variable elevation
public double terr_max_elev_chng = 0.5; // maximal terrain elevation change from last successfully used
@Deprecated
......@@ -2130,6 +2131,7 @@ min_str_neib_fpn 0.35
gd.addNumericField("Maximal warp", terr_max_warp, 5,7,"pix", "(1.8) Do not use scenes where distance between vegetation projection exceeds this.");
gd.addNumericField("Max elevation/offset", terr_max_elevation, 0,3,"pix","Maximal offset to consider when looking for vegetation influence.");
gd.addNumericField("Max terrain elevation",terr_max_elev_terr, 0,3,"pix","Maximal terrain offset to consider when looking for variable-elevation terrain.");
gd.addNumericField("Max elevation cjange", terr_max_elev_chng, 5,7,"pix","Maximal terrain elevation change from the previous success.");
gd.addNumericField("(Min influenced scenes)",terr_min_scenes, 0,3, "", "Deprecated: Minimal number of scenes (inside woi) vegetation pixel must influence.");
gd.addNumericField("Minimal samples/scene",terr_min_samples_scene, 0,3,"","Minimal samples per scene used for fitting (skip scene if less).");
......@@ -2919,6 +2921,7 @@ min_str_neib_fpn 0.35
terr_max_warp = gd.getNextNumber();// double
terr_max_elevation = (int) gd.getNextNumber();// int
terr_max_elev_terr = (int) gd.getNextNumber();// int
terr_max_elev_chng = gd.getNextNumber();// double
terr_min_scenes = (int) gd.getNextNumber();// int
terr_min_samples_scene=(int) gd.getNextNumber();// int
......@@ -3668,6 +3671,8 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"terr_max_warp", terr_max_warp+""); // double
properties.setProperty(prefix+"terr_max_elevation", terr_max_elevation+""); // int
properties.setProperty(prefix+"terr_max_elev_terr", terr_max_elev_terr+""); // int
properties.setProperty(prefix+"terr_max_elev_chng", terr_max_elev_chng+""); // double
properties.setProperty(prefix+"terr_min_scenes", terr_min_scenes+""); // int
properties.setProperty(prefix+"terr_min_samples_scene", terr_min_samples_scene+""); // int
properties.setProperty(prefix+"terr_min_total_scenes", terr_min_total_scenes+""); // int
......@@ -4435,6 +4440,7 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"terr_max_warp")!= null) terr_max_warp=Double.parseDouble(properties.getProperty(prefix+"terr_max_warp"));
if (properties.getProperty(prefix+"terr_max_elevation")!= null) terr_max_elevation=Integer.parseInt(properties.getProperty(prefix+"terr_max_elevation"));
if (properties.getProperty(prefix+"terr_max_elev_terr")!= null) terr_max_elev_terr=Integer.parseInt(properties.getProperty(prefix+"terr_max_elev_terr"));
if (properties.getProperty(prefix+"terr_max_elev_chng")!= null) terr_max_elev_chng=Double.parseDouble(properties.getProperty(prefix+"terr_max_elev_chng"));
if (properties.getProperty(prefix+"terr_min_scenes")!= null) terr_min_scenes=Integer.parseInt(properties.getProperty(prefix+"terr_min_scenes"));
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"));
......@@ -5171,6 +5177,7 @@ min_str_neib_fpn 0.35
imp.terr_max_warp = this.terr_max_warp;
imp.terr_max_elevation = this.terr_max_elevation;
imp.terr_max_elev_terr = this.terr_max_elev_terr;
imp.terr_max_elev_chng = this.terr_max_elev_chng;
imp.terr_min_scenes = this.terr_min_scenes;
imp.terr_min_samples_scene = this.terr_min_samples_scene;
imp.terr_min_total_scenes = this.terr_min_total_scenes;
......
......@@ -73,17 +73,17 @@ public class VegetationLMA {
// public static final int [] SAVE_TYPES = {TVAO_TERRAIN, TVAO_VEGETATION, TVAO_ALPHA, TVAO_ELEVATION, TVAO_TERR_ELEV, TVAO_SCENE_OFFSET};
public static final int [] SAVE_TYPES = {TVAO_TERRAIN, TVAO_VEGETATION, TVAO_ALPHA, TVAO_ELEVATION, TVAO_SCENE_OFFSET};
private final Rectangle full;
private final int image_length;
private final Rectangle full;
private final int image_length;
// should be non-null everywhere where elevation is defined?
private double [] vegetation_average; // full image average vegetation (with nulls)
private double [] vegetation_pull; // have nan far from vegetation, use to pull LMA to this
private double [] terrain_average; // full image average terrain (no nulls)
private double [][] terrain_rendered; // terrain rendered for scenes (has nulls)
private double [][] terrain_rendered_hf; // terrain rendered for scenes (has nulls)
private double [][][] vegetation_offsets; // [num_scenes][pixle]{dx,dy} differential offsets of vegetation to terrain grid
private double [] vegetation_average; // full image average vegetation (with nulls)
private double [] vegetation_pull; // have nan far from vegetation, use to pull LMA to this
private double [] terrain_average; // full image average terrain (no nulls)
private double [][] terrain_rendered; // terrain rendered for scenes (has nulls)
private double [][] terrain_rendered_hf; // terrain rendered for scenes (has nulls)
private double [][][] vegetation_offsets; // [num_scenes][pixle]{dx,dy} differential offsets of vegetation to terrain grid
// 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 [][] tvao; // [0][image_length] - terrain, [1][image_length] - vegetation,
private double [][][] scales_xy; // [scene][pixel{scale_x,scale_y}
private VegetationModel vegetationModel = null;
private int [][] par_index; // indices - [0..4][full_pixel] - same as for tvao, value - parameter index
......@@ -122,6 +122,8 @@ public class VegetationLMA {
private double [][][] terr_elev_dweights4; // [scene][woi_terr][4] derivatives of weights of influence for 4 neighbors with respect to elevations
private double [][] terr_elev_dsum_weights; // [scene][woi] derivative of elev_sum_weights by terr_elev parameter
private double terr_elev_last = Double.NaN; // terrain elevation for which terr_elev_woi4, ... where last calculated
private double terr_elev_last_success = 0; // terrain elevation last successfully used
private double terr_elev_initial = 0; // use with initial rms
// possible to combine the next 2 (overwrite)
private ArrayList<HashSet<Integer>> elev_contribs; // new ArrayList<HashSet<Integer>>(woi_length);
private ArrayList<HashSet<Integer>> param_contribs; // new ArrayList<HashSet<Integer>>(woi_length);
......@@ -221,8 +223,8 @@ public class VegetationLMA {
public double max_warp = 3.8; // 1.8 - do not use scenes where distance between vegetation projection exceeds this
public int max_elevation = 22; // maximal "elevation" to consider
public int max_elev_terr = 2; // maximal terrain "elevation" to consider
public double max_elev_terr_chg = 0.5;// Maximal terrain elevation change from last successfully used .
public double elevation_radius = 1.5; // Radius of elevation/vegetation influence.
private double elevation_lpf_transp = 1000; // lpf for transparent areas
private double elevation_lpf_pow = 2; // lpf for transparent areas power
......@@ -369,6 +371,15 @@ public class VegetationLMA {
this.vegetationModel = vegetationModel; // to access scene names, directories, reference index
scene_weights = new double [num_scenes];
scales_xy = getScalesXY(vegetationModel.scale_dirs);
/*
int grow_width = 24; // max of woi.width, woi.height plus 2 * max_terr_elev
// TODO: make it once for tiled (save with VegetationModel
fillScalesXY(
scales_xy, // double [][][] scalesXY,
full.width, // int width) {
grow_width, // int grow_width,
debugLevel); // int debugLevel)
*/
tvao[TVAO_ELEVATION] = vegetationModel.elevations.clone();
// vegetation_pull = vegetationModel.vegetation_pull; // pull LMA to this level
vegetation_pull =tvao[TVAO_VEGETATION].clone();
......@@ -414,6 +425,308 @@ public class VegetationLMA {
return scales_xy;
}
public void fillScalesWOI(
final Rectangle woi_in,
final boolean debug) {
final Rectangle woi = woi_in.intersection(full); // if woi_in extends beyond full
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final AtomicBoolean ahas_null = new AtomicBoolean(false);
final int woi_length = woi.width*woi.height;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int wIndx = ai.getAndIncrement(); (wIndx < woi_length) && !ahas_null.get(); wIndx = ai.getAndIncrement()){
int findx = getWoiIndex(
woi, // Rectangle woi_src,
full, // Rectangle woi_dst,
full, // Rectangle woi_full,
wIndx); // int indx)
for (int nscene = 0;nscene <scales_xy.length; nscene++) {
if (scales_xy[nscene][findx] == null) {
ahas_null.set(true);
break;
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
if (ahas_null.get()) {
if (debug) {
System.out.println("fillScalesWOI(): detected null in scales_xy inside woi="+woi.toString()+", filling missing pairs");
}
fillScalesXY( // FIXME: make it work with woi outside of full!
scales_xy, // double [][][] scalesXY,
full.width, // int width,
woi, // Rectangle woi,
false); // debug); // false); // boolean debug)
if (debug) {
System.out.println("fillScalesWOI(): DONE.");
}
}
return; //
}
/*
private static void fillScalesXY(
double [][][] scalesXY,
int width,
int grow_width,
boolean debug) {
final int num_pixels = scalesXY[0].length;
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final double [][] full_scales = new double [2][num_pixels];
for (int nscene = 0; nscene < scalesXY.length; nscene++) {
final int nScene = nscene;
if (debug) {
System.out.println("fillScalesXY(): filling scalesXY for scene "+nScene);
}
Arrays.fill(full_scales[0],Double.NaN);
Arrays.fill(full_scales[1],Double.NaN);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nPix = ai.getAndIncrement(); nPix < num_pixels; nPix = ai.getAndIncrement()) if (scalesXY[nScene][nPix] != null){
full_scales[0][nPix] = scalesXY[nScene][nPix][0];
full_scales[1][nPix] = scalesXY[nScene][nPix][1];
}
}
};
}
ImageDtt.startAndJoin(threads);
for (int i = 0; i < 2; i++) {
full_scales[i] = TileProcessor.fillNaNs(
full_scales[i], // final double [] data,
null, // final boolean [] prohibit,
width, // int width,
2 * grow_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
}
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nPix = ai.getAndIncrement(); nPix < num_pixels; nPix = ai.getAndIncrement()) if (scalesXY[nScene][nPix] == null){
if (!Double.isNaN(full_scales[0][nPix]) && !Double.isNaN(full_scales[1][nPix])) {
scalesXY[nScene][nPix] = new double [] {
full_scales[0][nPix],
full_scales[1][nPix]};
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
return;
}
*/
private static void fillScalesXY(
double [][][] scalesXY,
int width,
Rectangle woi,
boolean debug) {
final int woi_length = woi.width*woi.height;
final int grow_width = Math.max(woi.width,woi.height);
final Rectangle full_woi = new Rectangle (0,0,width,scalesXY[0].length/width);
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final double [][] full_scales = new double [2][woi_length];
final int num_passes = 20;
for (int nscene = 0; nscene < scalesXY.length; nscene++) {
final int nScene = nscene;
if (debug) {
System.out.println("fillScalesXY(): filling scalesXY for scene "+nScene);
}
Arrays.fill(full_scales[0],Double.NaN);
Arrays.fill(full_scales[1],Double.NaN);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int wIndx = ai.getAndIncrement(); wIndx < woi_length; wIndx = ai.getAndIncrement()) {
int findx = getWoiIndex(
woi, // Rectangle woi_src,
full_woi, // Rectangle woi_dst,
full_woi, // Rectangle woi_full,
wIndx); // int indx)
if (scalesXY[nScene][findx] != null) {
full_scales[0][wIndx] = scalesXY[nScene][findx][0];
full_scales[1][wIndx] = scalesXY[nScene][findx][1];
}
}
}
};
}
ImageDtt.startAndJoin(threads);
for (int i = 0; i < 2; i++) {
full_scales[i] = TileProcessor.fillNaNs(
full_scales[i], // final double [] data,
null, // final boolean [] prohibit,
woi.width, // int width,
2 * grow_width, // 100, // 2*width, // 16, // final int grow,
0.7, // double diagonal_weight, // relative to ortho
num_passes, // int num_passes,
0.03); // final double max_rchange, // = 0.01 - does not need to be accurate
}
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int wIndx = ai.getAndIncrement(); wIndx < woi_length; wIndx = ai.getAndIncrement()) {
int findx = getWoiIndex(
woi, // Rectangle woi_src,
full_woi, // Rectangle woi_dst,
full_woi, // Rectangle woi_full,
wIndx); // int indx)
if (Double.isNaN(full_scales[0][wIndx]) || Double.isNaN(full_scales[0][wIndx])) {
throw new IllegalArgumentException("fillScalesXY(): BUG: full_scales[0]["+wIndx+"] ="+full_scales[0][wIndx]+
", full_scales[1]["+wIndx+"] ="+full_scales[1][wIndx]);
}
scalesXY[nScene][findx] = new double [] {
full_scales[0][wIndx],
full_scales[1][wIndx]};
}
}
};
}
ImageDtt.startAndJoin(threads);
}
if (debug) {
System.out.println("fillScalesXY(): filling scalesXY DONE.");
}
return;
}
private static void fillScalesXY1(
double [][][] scalesXY,
int width,
Rectangle woi,
boolean debug) {
final int woi_length = woi.width*woi.height;
final int grow_width = Math.max(woi.width,woi.height);
final double [][][] scalesXY_woi = new double [scalesXY.length][woi_length][2];
// final int num_pixels = scalesXY[0].length;
final Rectangle full_woi = new Rectangle (0,0,width,scalesXY[0].length/width);
final Thread[] threads = ImageDtt.newThreadArray();
final AtomicInteger ai = new AtomicInteger(0);
final double [][] full_scales = new double [2][woi_length];
for (int nscene = 0; nscene < scalesXY.length; nscene++) {
final int nScene = nscene;
if (debug) {
System.out.println("fillScalesXY(): filling scalesXY for scene "+nScene);
Runtime runtime = Runtime.getRuntime();
runtime.gc();
System.out.println("----- fillScalesXY() --- Free memory="+runtime.freeMemory()+" (of "+runtime.totalMemory()+")");
}
Arrays.fill(full_scales[0],Double.NaN);
Arrays.fill(full_scales[1],Double.NaN);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int wIndx = ai.getAndIncrement(); wIndx < woi_length; wIndx = ai.getAndIncrement()) {
int findx = getWoiIndex(
woi, // Rectangle woi_src,
full_woi, // Rectangle woi_dst,
full_woi, // Rectangle woi_full,
wIndx); // int indx)
if (scalesXY[nScene][findx] != null) {
full_scales[0][wIndx] = scalesXY[nScene][findx][0];
full_scales[1][wIndx] = scalesXY[nScene][findx][1];
}
}
}
};
}
ImageDtt.startAndJoin(threads);
for (int i = 0; i < 2; i++) {
full_scales[i] = TileProcessor.fillNaNs(
full_scales[i], // final double [] data,
null, // final boolean [] prohibit,
woi.width, // int width,
2 * grow_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
}
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int wIndx = ai.getAndIncrement(); wIndx < woi_length; wIndx = ai.getAndIncrement()) {
/*
int findx = getWoiIndex(
woi, // Rectangle woi_src,
full_woi, // Rectangle woi_dst,
full_woi, // Rectangle woi_full,
wIndx); // int indx)
*/
if (Double.isNaN(full_scales[0][wIndx]) || Double.isNaN(full_scales[0][wIndx])) {
throw new IllegalArgumentException("fillScalesXY(): BUG: full_scales[0]["+wIndx+"] ="+full_scales[0][wIndx]+
", full_scales[1]["+wIndx+"] ="+full_scales[1][wIndx]);
}
/*
scalesXY[nScene][findx] = new double [] {
full_scales[0][wIndx],
full_scales[1][wIndx]};
*/
scalesXY_woi[nScene][wIndx][0] = full_scales[0][wIndx];
scalesXY_woi[nScene][wIndx][1] = full_scales[1][wIndx];
}
}
};
}
ImageDtt.startAndJoin(threads);
}
if (debug) {
System.out.println("fillScalesXY(): filling scalesXY_woi DONE.");
}
for (int nscene = 0; nscene < scalesXY.length; nscene++) {
final int nScene = nscene;
if (debug) {
System.out.println("fillScalesXY(): copying scalesXY_woi->scalesXY for scene "+nScene);
}
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int wIndx = ai.getAndIncrement(); wIndx < woi_length; wIndx = ai.getAndIncrement()) {
int findx = getWoiIndex(
woi, // Rectangle woi_src,
full_woi, // Rectangle woi_dst,
full_woi, // Rectangle woi_full,
wIndx); // int indx)
scalesXY[nScene][findx] = scalesXY_woi[nScene][wIndx];
}
}
};
}
ImageDtt.startAndJoin(threads);
}
if (debug) {
System.out.println("fillScalesXY(): filling scalesXY DONE.");
}
return;
}
private void setupLaplacians(double weight_diag) {
......@@ -503,6 +816,7 @@ public class VegetationLMA {
final double max_warp, // 1.8 - do not use scenes where distance between vegetation projection exceeds this
final int max_elevation, // maximal "elevation" to consider
final int max_elev_terr, // maximal terrain "elevation" to consider
final double max_elev_terr_chg, // 0.5 maximal terrain elevation change from last successfully used
final double elevation_radius, //Radius of elevation/vegetation influence.
final boolean [][] valid_scene_pix_in, // may have nulls or be shorter (do not update "overlaid")
final double hifreq_weight, // 22.5 0 - do not use high-freq. Relative weight of laplacian components
......@@ -624,6 +938,7 @@ public class VegetationLMA {
this.max_warp = max_warp;
this.max_elevation = max_elevation;
this.max_elev_terr = max_elev_terr;
this.max_elev_terr_chg = max_elev_terr_chg;
this.elevation_radius = elevation_radius;
if ((debug_path != null) && (debug_path.length() > 0)) {
this.debug_path = debug_path;
......@@ -638,6 +953,12 @@ public class VegetationLMA {
this.elev_radius = new double[full.width*full.height];
Arrays.fill(elev_radius, elevation_radius); // 5);
Rectangle woi_terr_ext = expandWoi(woi,max_elev_terr);
fillScalesWOI(
woi_terr_ext, // final Rectangle woi,
(debugLevel > -2)); // final boolean debug)
// calculate warps (as distances between vegetation projections of this pixel and its neighbors)
warps = getMaxWarp(
tvao[TVAO_ELEVATION], // final double [] elevations,
......@@ -971,7 +1292,7 @@ public class VegetationLMA {
double d = y_vector[n] - fx[n]; // - fx[n]; // +y_vector[i]
double wd = d * weights[n];
if (Double.isNaN(wd)) {
System.out.println("getYminusFxWeighted(): wd=NaN, n="+n);
System.out.println("getYminusFxWeighted(): wd=NaN, y_vector["+n+"]="+y_vector[n]+", fx["+n+"]="+fx[n]+", weights["+n+"]="+weights[n]);
}
wymfw[n] = wd;
swd2[nthread] += d * wd;
......@@ -1048,7 +1369,7 @@ public class VegetationLMA {
double w = weights[indx];
double wd = d * w;
if (Double.isNaN(wd)) {
System.out.println("yMinusFxSummary(): wd=NaN, n="+n);
System.out.println("yMinusFxSummary(): wd=NaN, y_vector["+n+"]="+y_vector[n]+", fx["+n+"]="+fx[n]+", weights["+n+"]="+weights[n]);
}
stats_threaded[nthread][0] += wd * d;
stats_threaded[nthread][1] += w;
......@@ -1224,6 +1545,7 @@ public class VegetationLMA {
double rms_diff,
int debug_level) {
boolean [] rslt = {false,false};
int par_indx_terr_elev = (num_pars[TVAO_TERR_ELEV] > 0) ? par_index[TVAO_TERR_ELEV][0] : -1; // index of terrain elevcation or -1
// maybe the following if() branch is not needed - already done in prepareLMA !
if (this.last_rms == null) { //first time, need to calculate all (vector is valid)
last_rms = new double[2];
......@@ -1239,6 +1561,10 @@ public class VegetationLMA {
last_rms); // final double [] rms_fp // null or [2]
this.initial_rms = this.last_rms.clone();
this.good_or_bad_rms = this.last_rms.clone();
if ((par_indx_terr_elev >=0) && !Double.isNaN(terr_elev_last)) {
terr_elev_last_success = terr_elev_last;
terr_elev_initial = terr_elev_last;
}
if (debug_level > -1) {
yMinusFxSummary(
fx, // final double [] fx,
......@@ -1267,7 +1593,7 @@ public class VegetationLMA {
debugImageSaveShow(
parameters_vector, // double [] vector
last_ymfx, // double [] ymfx,
last_rms, // double [] rms,
last_rms, // double [] rms,
save_dir, // String save_dir, // save if not null
debug_title, // String title, // not null
save_all, // boolean save_all,
......@@ -1364,6 +1690,31 @@ public class VegetationLMA {
par_map, //final int [][] par_map, // only [0] used
delta_decim); // final double [] data_decimated)
// Limit terrain elevation/ terrain elevation change
if (par_indx_terr_elev >= 0) {
double te_change = delta[par_indx_terr_elev];
if (Math.abs(te_change) > max_elev_terr_chg) {
delta[par_indx_terr_elev] = (te_change > 0) ? max_elev_terr_chg : -max_elev_terr_chg;
if (debug_level > - 2) {
System.out.println("lmaStep(): tried to adjust terrain elevation by "+te_change+", exceeding maximal change of "+max_elev_terr_chg+" pix.");
System.out.println("lmaStep(): limiting delta["+par_indx_terr_elev+"] to "+delta[par_indx_terr_elev]+" pix.");
}
}
double old_te = parameters_vector[par_indx_terr_elev];
double new_te = old_te+delta[par_indx_terr_elev];
if (Math.abs(new_te) > max_elev_terr) {
double new_te_mod = (new_te > 0)? max_elev_terr : -max_elev_terr;
te_change = new_te_mod - new_te;
delta[par_indx_terr_elev] = te_change;
if (debug_level > - 2) {
System.out.println("lmaStep(): tried to set terrain elevation to "+new_te+"(current is "+old_te+"), exceeding maximal allowed "+max_elev_terr+" pix.");
System.out.println("lmaStep(): limiting delta["+par_indx_terr_elev+"] to "+delta[par_indx_terr_elev]);
}
}
}
double [] new_vector = parameters_vector.clone();
for (int i = 0; i < parameters_vector.length; i++) {
new_vector[i] += scale * delta[i];
......@@ -1395,6 +1746,7 @@ public class VegetationLMA {
rslt[1] = rms[0] >=(this.last_rms[0] * (1.0 - rms_diff));
this.last_rms = rms.clone();
this.parameters_vector = new_vector.clone();
terr_elev_last_success = terr_elev_last;
/*
if (debug_level > -2) { //
String save_dir = debug_path;
......@@ -1738,7 +2090,6 @@ public class VegetationLMA {
public double [] getRms() {
return last_rms;
}
public double [] getInitialRms() {
......@@ -2248,7 +2599,7 @@ public class VegetationLMA {
double ww= wnd_y*wnd_x[dx];
terr_elev_weights4[nScene][wtindex][dindx] = ww;
terr_elev_sum_weights[nScene][wpindex] += ww;
if (need_derivs) {
if (need_derivs && terr_elev_parameters) { // otherwise par_index[TVAO_TERR_ELEV][0] will fail
double dww = wnd_y * dwnd_x[dx] + dwnd_y*wnd_x[dx];
terr_elev_dweights4[nScene][wtindex][dindx] = dww;
int par_indx_elev = par_index[TVAO_TERR_ELEV][0]; // fnpix]; // ipx+ipy*full.width];
......@@ -2691,8 +3042,10 @@ public class VegetationLMA {
contrib_threads.add(contrib_thread);
}
}
final int dbg_scene = -105; // -20;
final int dbg_y_indx = -340;
final int dbg_scene = -9; // -105; // -20;
final int dbg_windex = -234; // -1;
final int dbg_wtindex = -340; // -1;
final int dbg_n = -7402; // -69992;
final int dbg_findx = -121775;
final int fdbg_scene = dbg_scene;
......@@ -2821,10 +3174,8 @@ public class VegetationLMA {
}
}
}
} // for (int wvindex = 0; wvindex < woi_veg_length; wvindex++) if (valid_vegetation[wvindex]) {
// if (offset_terrain) { // calculate terrain projection terr_woi
for (int wtindex = 0; wtindex < woi_terr_length; wtindex++) if (terr_elev_woi4[nScene][wtindex] != null) { //valid_terrain[wtindex]) {
int wtx = wtindex % woi_terr.width; // relative to woi_terr
int wty = wtindex / woi_terr.width; // relative to woi_terr
......@@ -2834,6 +3185,10 @@ public class VegetationLMA {
if (npix == dbg_findx) {
System.out.println("getFxDerivs() 2: findx="+npix);
}
if ((wtindex== dbg_wtindex) && (nScene ==dbg_scene)) {
System.out.println("getFxDerivs() 2: nScene="+nScene+", windx="+wtindex);
}
double terrain; // [woi_terr], adjusted/elevated terrain
int ntpar = -1;
if (terrain_parameters) {
......@@ -2864,10 +3219,7 @@ public class VegetationLMA {
dterrain_woi_dterrain[ntpar-ind_pars[TVAO_TERRAIN]][windx] += w; // /stw; // this fX pixel's terrain with respect to this terrain parameter
}
// calculate dterrain_woi_dtelev - derivative of terrain_woi[windx] with respect to terr_elev
// int terr_elev_dsum_weights_indx = 0; // single-element parameters, always 0
if (terr_elev_parameters) {
// dterrain_woi_dtelev[windx] += (w - w * terrain* terr_elev_dsum_weights[nScene][terr_elev_dsum_weights_indx])/(stw * stw);
// dterrain_woi_dtelev[windx] += (w - w * terrain* terr_elev_dsum_weights[nScene][windx])/(stw * stw);
dterrain_woi_dtelev[windx] +=
terrain * (terr_elev_dweights4[nScene][wtindex][i] * stw -
w * terr_elev_dsum_weights[nScene][windx])/(stw * stw);
......@@ -2900,6 +3252,9 @@ public class VegetationLMA {
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]
// Fill in fX for this scene
int y_indx = y_wsrc[nScene][windx]; // y_indx is different for threads, no conflict
if (y_indx == dbg_y_indx) {
System.out.println("getFxDerivs() 1: y_indx="+y_indx);
}
double d = terrain; // combined from neighbors if needed
if (has_vegetation[windx]) {
......@@ -4625,6 +4980,7 @@ public class VegetationLMA {
imp.setProperty("MAX_WARP", ""+max_warp);
imp.setProperty("MAX_ELEVATION", ""+max_elevation);
imp.setProperty("MAX_ELEV_TERR", ""+max_elev_terr);
imp.setProperty("MAX_ELEV_TERR_CHN", ""+max_elev_terr_chg);
imp.setProperty("ELEVATION_RADIUS", ""+elevation_radius);
imp.setProperty("NUM_PARS_TERRAIN", ""+num_pars[TVAO_TERRAIN]);
......@@ -4639,6 +4995,7 @@ public class VegetationLMA {
imp.setProperty("IND_PARS_ELEVATION", ""+ind_pars[TVAO_ELEVATION]);
imp.setProperty("IND_PARS_SCENES", ""+ind_pars[TVAO_SCENE_OFFSET]);
imp.setProperty("TERRAIN_OFFSET", ""+terrain_offset);
imp.setProperty("TERR_ELEV_LAST_SUCCESS", ""+terr_elev_last_success);
// samples_pointers
for (int nsp = 0; nsp < SAMPLES_SIZE; nsp++) {
......@@ -4850,9 +5207,10 @@ public class VegetationLMA {
max_warp = getProperty(imp_pars,"MAX_WARP", max_warp);
max_elevation = getProperty(imp_pars,"MAX_ELEVATION", max_elevation);
max_elev_terr = getProperty(imp_pars,"MAX_ELEV_TERR", max_elev_terr);
max_elev_terr_chg = getProperty(imp_pars,"MAX_ELEV_TERR_CHG", max_elev_terr_chg);
elevation_radius = getProperty(imp_pars,"ELEVATION_RADIUS", elevation_radius);
terrain_offset = getProperty(imp_pars,"TERRAIN_OFFSET", terrain_offset);
terr_elev_last_success = getProperty(imp_pars,"TERR_ELEV_LAST_SUCCESS",terr_elev_last_success);
// if (imp_pars.getProperty("TERRAIN_OFFSET") != null) terrain_offset = Double.parseDouble((String) imp_pars.getProperty("TERRAIN_OFFSET"));
}
num_pars[TVAO_TERRAIN] = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_TERRAIN"));
......@@ -5027,6 +5385,7 @@ public class VegetationLMA {
getProperty(imp_pars,"MAX_WARP", max_warp), // final double max_warp, // 1.8 - do not use scenes where distance between vegetation projection exceeds this
getProperty(imp_pars,"MAX_ELEVATION", max_elevation), // final int max_offset, // maximal "elevation" to consider
getProperty(imp_pars,"MAX_ELEV_TERR", max_elev_terr), // final int max_elev_terr, // maximal terrain "elevation" to consider
getProperty(imp_pars,"MAX_ELEV_TERR_CHG", max_elev_terr_chg), // final double max_elev_terr_chg, // 0.5 maximal terrain elevation change from last successfully used
getProperty(imp_pars,"ELEVATION_RADIUS", elevation_radius), // final double elevation_radius, // Radius of elevation/vegetation influence.
valid_scene_pix, // final boolean [] valid_scene_pix, valid_scene_pix_in, // may have nulls or be shorter (do not update "overlaid")
getProperty(imp_pars, "HIGHFREQ_WEIGHT", hifreq_weight), // final double hifreq_weight, // 22.5 0 - do not use high-freq. Relative weight of laplacian components
......@@ -5083,12 +5442,15 @@ public class VegetationLMA {
getProperty(imp_pars, "TTOP_REM_RAD", ttop_rem_rad), // final double ttop_rem_rad,
getProperty(imp_pars, "BOOST_PARALLAX", boost_parallax), // final double boost_parallax, // increase weight of scene with maximal parallax relative to the reference scene
getProperty(imp_pars, "MAX_PARALLAX", max_parallax), // final double max_parallax, // do not consider maximal parallax above this (consider it a glitch)
getProperty(imp_pars, "MAX_PARALLAX", max_parallax), // final double max_parallax, // do not consider maximal parallax above this (consider it a glitch)
debugLevel, // final int debugLevel);
debug_path, // final String debug_path,
debug_save_improved, // final boolean debug_save_improved, // Save debug image after successful LMA step.");
debug_save_worsened); // final boolean debug_save_worsened) // Save debug image after unsuccessful LMA step.");
terr_elev_last_success = getProperty(imp_pars,"TERR_ELEV_LAST_SUCCESS",terr_elev_last_success);
num_pars[TVAO_TERRAIN] = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_TERRAIN"));
num_pars[TVAO_VEGETATION] = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_VEGETATION"));
num_pars[TVAO_ALPHA] = Integer.parseInt((String) imp_pars.getProperty("NUM_PARS_ALPHA"));
......@@ -5101,6 +5463,7 @@ public class VegetationLMA {
ind_pars[TVAO_ELEVATION] = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_ELEVATION"));
ind_pars[TVAO_TERR_ELEV] = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_TERR_ELEV"));
ind_pars[TVAO_SCENE_OFFSET] = Integer.parseInt((String) imp_pars.getProperty("IND_PARS_SCENES"));
par_index = new int[TVAO_TYPES][];
for (int n = 0; n < par_index.length; n++) {
if (n < TVAO_SCENE_OFFSET) {
......@@ -7572,8 +7935,8 @@ public class VegetationLMA {
final Rectangle woi_terr_ext = expandWoi(woi,max_elev_terr);
final int woi_terr_ext_len = woi_terr_ext.width*woi_terr_ext.height;
final boolean [] terr_scene_used_prefilter = new boolean [woi_terr_ext_len]; // which of the source terrain pixel amy be used
final boolean [] terr_scene_used = new boolean [woi_terr_ext_len]; // which of the source terrain pixel amy be used
final boolean [] terr_scene_used_prefilter = new boolean [woi_terr_ext_len]; // which of the source terrain pixel may be used
final boolean [] terr_scene_used = new boolean [woi_terr_ext_len]; // which of the source terrain pixel may be used
final boolean [][][] has_terr_thread = new boolean [threads.length][num_scenes][woi_length];
final boolean [][] has_terr_scene = new boolean [num_scenes][woi_length]; // which image pixels in woi have source terrain
ai.set(0);
......@@ -7616,15 +7979,15 @@ public class VegetationLMA {
if (woi.contains(ax,ay)) {
double ddx = ax - (x + dx);
// double ddr2 = ddy2 + ddx*ddx;
if ((ddy2 <= radius2) && (ddx*ddx < radius2)) { // if (ddr2 <= radius2) {
// if ((ddy2 <= radius2) && (ddx*ddx < radius2)) { // if (ddr2 <= radius2) {
int wx = ax - woi.x;
int wy = ay - woi.y;
int wpix =wx + wy*woi.width;
if (valid_pixels[wpix]) {
// if (valid_pixels[wpix]) {
has_terr_thread[nthread][nscene][wpix] = true;
has_valid_dependent = true;
}
}
// }
// }
}
}
}
......@@ -8265,7 +8628,7 @@ public class VegetationLMA {
return null;
}
/**
* Copy data beween WOIs
* Copy data between WOIs
* @param woi_src_in source WOI (or null if it is the full image WOI)
* @param woi_dst_in destination WOI (or null if it is the full image WOI)
* @param woi_full full WOI (not null)
......
......@@ -1489,7 +1489,8 @@ public class VegetationModel {
boolean continue_woi = clt_parameters.imp.terr_continue; // false;
double max_warp = clt_parameters.imp.terr_max_warp; // 1.8 - do not use scenes where distance between vegetation projection exceeds this
int max_elevation = clt_parameters.imp.terr_max_elevation; // maximal "elevation" to consider
int max_elev_terr = clt_parameters.imp.terr_max_elev_terr; // maximal "elevation" to consider
int max_elev_terr = clt_parameters.imp.terr_max_elev_terr; // 2.0 maximal "elevation" to consider
double max_elev_terr_chg = clt_parameters.imp.terr_max_elev_chng; // 0.5 maximal terrain elevation change from last successfully used
// int min_scenes = clt_parameters.imp.terr_min_scenes; // 1;
// int min_samples_scene = clt_parameters.imp.terr_min_samples_scene; //10;
......@@ -2090,6 +2091,7 @@ public class VegetationModel {
max_warp, // final double max_warp, // 1.8 - do not use scenes where distance between vegetation projection exceeds this
max_elevation, // final int max_offset, // maximal "elevation" to consider
max_elev_terr, // final int max_elev_terr, // maximal terrain "elevation" to consider
max_elev_terr_chg, // final double max_elev_terr_chg, // 0.5 maximal terrain elevation change from last successfully used
elevation_radius, // final double elevation_radius, // Radius of elevation/vegetation influence.
null, // final boolean [] valid_scene_pix,
hifreq_weight, //final double hifreq_weight, // 22.5 0 - do not use high-freq. Relative weight of laplacian components
......
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