Commit 88dc9e10 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

has bug, but worked without alpha_mm_hole (set it to Double.NaN)

parent e496084a
Loading
Loading
Loading
Loading
+153 −37
Original line number Diff line number Diff line
@@ -55,6 +55,18 @@ public class VegetationLMA {
	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;
	public boolean            alpha_piece_linear = true;
	public double             alpha_scale_avg = 1.0; // 1.1; // scale average alpha (around 0.5) when pulling to it
	public double             alpha_push =      12.0;   // push from alpha==0.5
	public double             alpha_push_neutral = 0.8; // alpha point from which push (closer to opaque)	
	public double             alpha_push_center = 1.5; // weight of center alpha pixel relative to each of the 4 ortho ones
	public double             alpha_mm_hole    = 0.1; // NaN to disable. Local "almost minimum" (lower than this fraction between min and max neighbor) is not subject to alpha_lpf
	public double             alpha_diff_hole = 0.01; // minimal alpha difference between min and max neighbor to be considered a hole

	
	public boolean            from_file =       false;

	
	public double             terr_lpf =        0;
	public double             veget_lpf =       0;
	
@@ -134,6 +146,12 @@ public class VegetationLMA {
			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
			final double             alpha_lpf,      // pull vegetation alpha to average of 4 neighbors
			final boolean            alpha_piece_linear, // true - piece-linear, false - half-cosine
			final double             alpha_scale_avg, //  = 1.2; // scale average alpha (around 0.5) when pulling to it
			final double             alpha_push,      //  5.0;   // push from alpha==0.5
			final double             alpha_push_neutral, //  = 0.8; // alpha point from which push (closer to opaque)
			final double             alpha_push_center,// 1.5; // weight of center alpha pixel relative to each of the 4 ortho ones
			final double             alpha_mm_hole, //     = 0.1; // NaN to disable. Local "almost minimum" (lower than this fraction between min and max neighbor) is not subject to alpha_lpf			
			final double             terr_lpf,       // pull terrain to average of 4 neighbors (very small)
			final double             veget_lpf,      // pull vegetation to average of 4 neighbors (very small - maybe not needed)
			final double             terr_pull0,     // pull terrain to zero (makes sense with UM
@@ -147,8 +165,16 @@ public class VegetationLMA {
		this.alpha_loss =        alpha_loss;
		this.alpha_offset =      alpha_offset;
		this.alpha_lpf =         alpha_lpf;
		this.alpha_scale_avg =   alpha_scale_avg;
		this.alpha_piece_linear= alpha_piece_linear;
		this.alpha_push =        alpha_push; //    5.0;   // push from alpha==0.5
		this.alpha_push_neutral = alpha_push_neutral; // 0.8; // alpha point from which push (closer to opaque)
		this.alpha_push_center = alpha_push_center; // 1.5; // weight of center alpha pixel relative to each of the 4 ortho ones
		this.alpha_mm_hole =     alpha_mm_hole;
		this.terr_lpf =          terr_lpf;
		this.veget_lpf =         veget_lpf;
		this.terr_pull0 =        terr_pull0;
		this.veget_pull0 =       veget_pull0;
		this.boost_parallax =    boost_parallax;
		this.um_sigma =          um_sigma;      // just use in debug image names
		this.um_weight =         um_weight;
@@ -179,6 +205,7 @@ public class VegetationLMA {
		if (!keep_parameters) {
			setupParametersVector (default_alpha); // areas where both terrain and vegetation are available
		}
		from_file = false;
		if (parameters_read_path != null) {
			 readParametersFromImage(
					 parameters_read_path, // String    path,
@@ -527,7 +554,11 @@ public class VegetationLMA {
			if (debug_level > -2) { //
				String  save_dir =    debug_path;
				String  debug_title = "parameters_vector-x"+woi.x+"-y"+woi.y+"-w"+woi.width+"-h"+woi.height;
				debug_title +="-al"+alpha_loss+"-alo"+alpha_offset+"-alp"+alpha_lpf+"-tl"+terr_lpf+"-vl"+veget_lpf+"-bp"+boost_parallax;
				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 += "-tl"+terr_lpf+"-vl"+veget_lpf+"-tp"+terr_pull0+"-vp"+veget_pull0;
				debug_title += "-bp"+boost_parallax;
				debug_title += from_file?"-file":"-new";
				if (um_weight > 0) {
					debug_title +="-um"+um_sigma+"_"+um_weight;
				}
@@ -854,6 +885,7 @@ public class VegetationLMA {
				jt[i] = new double [weights.length]; // weights.length];
			}
		}
		final int dbg_n = -69992;
		final Thread[] threads = ImageDtt.newThreadArray();
		final AtomicInteger ai = new AtomicInteger(0);
		for (int ithread = 0; ithread < threads.length; ithread++) {
@@ -862,6 +894,9 @@ public class VegetationLMA {
					double [] vegetation = new double [4]; 
					double [] alpha =      new double [4];
					for (int n = ai.getAndIncrement(); n < y_vector.length; n = ai.getAndIncrement()) {
						if (n == dbg_n) {
							System.out.println("getFxDerivs(): n="+n);
						}
//						int nscene =   data_source[n][0][0];
//						int indx =     data_source[n][0][1];
						double terrain = vector[data_source[n][0][2]];
@@ -878,7 +913,13 @@ public class VegetationLMA {
								sum_v += vegetation[i];
								sum_a += alpha[i];
							}
							double k = (sum_a < 0)? 0: ( (sum_a > 1) ? 1.0: 0.5 * (1.0 - Math.cos(sum_a*Math.PI)));
							double k;
							if (alpha_piece_linear) {
								k = (sum_a < 0)? 0: ((sum_a > 1) ? 1.0: sum_a);	
							} else {
								k = (sum_a < 0)? 0: ((sum_a > 1) ? 1.0: 0.5 * (1.0 - Math.cos(sum_a*Math.PI)));	
							}
							
//							d = terrain * (1.0 - sum_a) + sum_v * sum_a;
							d = terrain * (1.0 - k) + sum_v * k;
							
@@ -889,12 +930,14 @@ public class VegetationLMA {
										jt[data_source[n][1][i]][n] = cw[i] * k; // sum_a; // d/dvegetation[i]
									}
									if ((indx_alpha[i] >= 0) && (sum_a > 0) && (sum_a < 1.0)) {
//										jt[data_source[n][2][i]][n] = cw[i] * (sum_v - terrain); // d/dalpha[i]
										
									    if (alpha_piece_linear) {
									    	jt[data_source[n][2][i]][n] = cw[i] * (sum_v - terrain); // d/dalpha[i]
									    } else {
									    	jt[data_source[n][2][i]][n] = cw[i] * (sum_v - terrain) *0.5*Math.PI *Math.sin(sum_a*Math.PI); // d/dalpha[i]
									    }
									}
								}								
							}

						} else {
							d = terrain; 
@@ -916,6 +959,7 @@ public class VegetationLMA {
		
		int ind_next = y_vector.length;
		if ((alpha_lpf >= 0) || (alpha_loss > 0)) {
			int dbg_nx = -76340;
			final int ind_y_alpha = ind_next;
			ind_next += num_pars_vegetation_alpha;
			ai.set(0);
@@ -925,6 +969,9 @@ public class VegetationLMA {
						for (int n = ai.getAndIncrement(); n < num_pars_vegetation_alpha; n = ai.getAndIncrement()) {
							int np = ind_pars_vegetation_alpha + n; // index of the alpha parameter
							int nx = n + ind_y_alpha; //  y_vector.length; // x - index
							if (nx == dbg_nx) {
								System.out.println("getFxDerivs(): n="+n+", nx="+nx);
							}
							double d = 0;
							fX[nx] = 0.0;
							if (alpha_loss > 0) {
@@ -941,36 +988,95 @@ public class VegetationLMA {
									}							
								}
							}
							// add cost for difference between this alpha and average of 4 neighbors (when they exist
							// applies to alpha before cosine, so it will pull borders even when alpha<0 or alpha > 1 (zero derivatives)
							if (alpha_lpf > 0) { // should always be > 0 to provide stability for out-of-range alpha 
							double avg = 0;
							int nn = 0;
							double neib_min = Double.POSITIVE_INFINITY, neib_max = Double.NEGATIVE_INFINITY;
							for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased
								int di =  alpha_neibs[n][i];
								d=0;
								if (di >= 0) {
									d = vector[di];  // d - full parameter index
									avg+=d;
									if (d < neib_min) neib_min = d; 
									if (d > neib_max) neib_max = d; 
									nn++;
								} else if (di < -1) {
									d = tvao[TVAO_VEGETATION_ALPHA][-di - 2]; 
									avg+=d;
									if (d < neib_min) neib_min = d; 
									if (d > neib_max) neib_max = d; 
									nn++;
								}
							}
							avg /= nn; // average
								fX[nx] += alpha_lpf * (vector[np] - avg);
							if (alpha_push > 0) {
								// average including center:
								double sum_w = (nn + alpha_push_center);
								double avg_c = (avg * nn + vector[np] * alpha_push_center) / sum_w; 
								if ((avg_c > 0) || (avg_c < 1.0)) {
									fX[nx] += alpha_push * avg_c * (1.0 - avg_c);
								}
								if (jt != null) {
									jt[np][nx] += alpha_lpf;
									double dd = alpha_push / sum_w * (1 - 2 * avg_c);
									jt[np][nx] += dd * alpha_push_center; // 2 * alpha_loss * d; // d/dalpha[i]		
									for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased
										int di =  alpha_neibs[n][i];
										if (di >= 0) {
											jt[di][nx] -= alpha_lpf/nn;
											jt[di][nx] += dd; // 2 * alpha_loss * d; // d/dalpha[i]
										}
									}
								}								
							}
							
							
							// add cost for difference between this alpha and average of 4 neighbors (when they exist
							// applies to alpha before cosine, so it will pull borders even when alpha<0 or alpha > 1 (zero derivatives)
							//alpha_scale_avg
							if (alpha_lpf > 0) { // should always be > 0 to provide stability for out-of-range alpha
								double mm = neib_min + (neib_max-neib_min) * alpha_mm_hole;
								double effective_alpha_lpf = alpha_lpf; 
								if (!Double.isNaN(alpha_mm_hole) && (vector[np] <= mm) && ((neib_max-neib_min) >= alpha_diff_hole)) {
									effective_alpha_lpf = 0.0; // disable alpha_lpf
								}
								// disable pull to average of neighbors for small holes in vegetation (local "almost minimum")
///								if (Double.isNaN(alpha_mm_hole) || (vector[np] > mm) || ((neib_max-neib_min) < alpha_diff_hole)) {
									//		this.alpha_mm_hole =     alpha_mm_hole;
								if (alpha_scale_avg == 1) {
									fX[nx] += effective_alpha_lpf * (vector[np] - avg);
									if (jt != null) {
										jt[np][nx] += effective_alpha_lpf;
										for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased
											int di =  alpha_neibs[n][i];
											if (di >= 0) {
												jt[di][nx] -= effective_alpha_lpf/nn;
											}
										}
									}
								} else {
									if ((avg > 0) && (avg < 1)) { 
										double savg = 0.5 + (avg - 0.5) * alpha_scale_avg;
										fX[nx] += effective_alpha_lpf * (vector[np] - savg);
										if (jt != null) {
											//											jt[np][nx] += effective_alpha_lpf;
											for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased
												int di =  alpha_neibs[n][i];
												if (di >= 0) {
													jt[di][nx] -= effective_alpha_lpf/nn * alpha_scale_avg;
												}
											}
										}
									} else {
										if (avg <= 0) {
											fX[nx] += effective_alpha_lpf * (vector[np] + 0.5*(alpha_scale_avg - 1.0));
										} else { // avg > 1
											fX[nx] += effective_alpha_lpf * (vector[np] - 0.5*(alpha_scale_avg + 1.0));
										}
									}
									if (jt != null) {
										jt[np][nx] += effective_alpha_lpf;
									}
								}	
							}
						}
					}
				};
@@ -1302,8 +1408,12 @@ public class VegetationLMA {
			double []         vector,
			final double      delta,
			final int         debug_level) {
		int dbg_n = -2486;
		double [][] jt =  new double [vector.length][weights.length];
		for (int nv = 0; nv < vector.length; nv++) {
			if (nv == dbg_n) {
				System.out.println("getFxDerivsDelta(): nv="+nv);
			}
			double [] vpm = vector.clone();
			vpm[nv]+= 0.5*delta;
			double [] fx_p =  getFxDerivs(
@@ -1468,6 +1578,7 @@ public class VegetationLMA {
				vector[indices[i]] = d;
			}
		}
		from_file = true;
		return;
	}
	
@@ -1779,6 +1890,11 @@ public class VegetationLMA {
		par_index[TVAO_VEGETATION] =       new int [image_length];
		par_index[TVAO_VEGETATION_ALPHA] = new int [image_length];
		par_index[TVAO_SCENE_OFFSET] =     new int [num_scenes];
		if (valid_woi == null) {
			valid_woi = new boolean [2][woi.width*woi.height];
			Arrays.fill(valid_woi[0],true);
			Arrays.fill(valid_woi[1],true);
		}
		int max_pars = 0;
		for (int i = 0; i < par_index.length; i++) {
			max_pars += par_index[i].length;
+58 −19
Original line number Diff line number Diff line
@@ -678,19 +678,50 @@ public class VegetationModel {
			int                debugLevel) {
		boolean diff_mode = true;
		Rectangle woi50 =       new Rectangle(143,317,35,35);
		/* Bad, pull terr lower, so it all shifts to terrain
		int       min_scenes =   10;
		double    default_alpha = 0.8;
		double    reg_weights =   0.25;        // fraction of the total weight used for regularization
		double    alpha_loss =   10.0;  // 10000.0; // 1000.0; // 100.; // 10.0;         // quadratic loss when alpha reaches -1.0 or 2.0 
		double    alpha_loss =   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;
		double    alpha_lpf =     10;   // 20; // 6.0; // 3.0; // 2.0;    // 1.5; // 5.0; // 0.5;         // pull to average of 4 neighbors
		double    terr_lpf =      0.1;    // pull terrain to average of 4 neighbors (very small)
		double    veget_lpf =     0.1;    // pull vegetation to average of 4 neighbors (very small - maybe not needed)
		double    terr_pull0 =    0.1;    //pull terrain to zero (makes sense with UM
		double    veget_pull0 =   0.1;    // pull vegetation to zero (makes sense with UM
		double    boost_parallax = 1.0; //  5;
		double    alpha_lpf =    5.0; // 10.0; // 3; // 10;   // 20; // 6.0; // 3.0; // 2.0;    // 1.5; // 5.0; // 0.5;         // pull to average of 4 neighbors
		boolean   alpha_piece_linear = true;
		double    terr_lpf =      0.1; // 0.15; /// 0.2;  /// 0.1;    // pull terrain to average of 4 neighbors (very small)
		double    veget_lpf =     0.2; //0.15; /// 0.2; //// 0.01; /// 0.1;    // pull vegetation to average of 4 neighbors (very small - maybe not needed)
		double    terr_pull0 =    0.03; ////// 0.05; ///// 0.1; //// 0.01; /// 0.2; /// 0.1;    //pull terrain to zero (makes sense with UM
		double    veget_pull0 =   0.1; // 0.03; ////// 0.05; ///// 0.1; //// 0.01; /// 0.1;    // pull vegetation to zero (makes sense with UM
		double    boost_parallax = 3.0; /// 1.0; /////// 5.0; /// 1.0; //  5;
		boolean   next_run =      false;
		boolean   read_pars =     true; //   false; // true;
		boolean   read_pars =     true; /// false; /// true; //   false; // true;
		double    threshold_terrain = 0.05;
		double    min_max_terrain= 0.1;
		double    min_terrain =    0.001;
		double    min_vegetation = 0.5;				
		boolean   um_en =     true;
		double    um_sigma =  1.0; 
		double    um_weight = 0.8;

		 */
		int       min_scenes =   1; // 10; // for new scenes only, for old ones use 10
		double    default_alpha = 0.5; //  0.8;
		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;
		double    alpha_lpf =    10; /// 15; // 10.0; // 5.0; // 10.0; // 3; // 10;   // 20; // 6.0; // 3.0; // 2.0;    // 1.5; // 5.0; // 0.5;         // pull to average of 4 neighbors
		boolean   alpha_piece_linear = true; // false; // true;
		double    alpha_scale_avg = 1.0; // 1.1; // 0.9; // 2.0; // 1.5; // scale average alpha (around 0.5) when pulling to it
		double    alpha_push =       12; // 10.0; // 15.0;   // push from alpha==0.5
		double    alpha_push_neutral = 0.8; // alpha point from which push (closer to opaque)
		double    alpha_push_center = 1.5; // weight of center alpha pixel relative to each of the 4 ortho ones
		double    alpha_mm_hole    = 0.1; // NaN to disable. Local "almost minimum" (lower than this fraction between min and max neighbor) is not subject to alpha_lpf
		
		double    terr_lpf =      0.1; // 0.15; /// 0.2;  /// 0.1;    // pull terrain to average of 4 neighbors (very small)
		double    veget_lpf =     0.2; //0.15; /// 0.2; //// 0.01; /// 0.1;    // pull vegetation to average of 4 neighbors (very small - maybe not needed)
		double    terr_pull0 =    0.05; //0.03; ////// 0.05; ///// 0.1; //// 0.01; /// 0.2; /// 0.1;    //pull terrain to zero (makes sense with UM
		double    veget_pull0 =   0.05; //0.1; // 0.03; ////// 0.05; ///// 0.1; //// 0.01; /// 0.1;    // pull vegetation to zero (makes sense with UM
		double    boost_parallax = 3.0; /// 1.0; /////// 5.0; /// 1.0; //  5;
		boolean   next_run =      false;
		boolean   read_pars =     false; // true; /// false; /// true; //   false; // true;
		double    threshold_terrain = 0.05;
		double    min_max_terrain= 0.1;
		double    min_terrain =    0.001;
@@ -705,7 +736,10 @@ public class VegetationModel {
		//		String  parameters_path = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/debug/vegetation/essential/parameters_vector_data_1000-0.03.tiff";
//		String  parameters_path = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/debug/vegetation/essential/parameters_vector_data_x143-y317-w35-h35-live_10000_0.02_3.0.tiff";
//		String  parameters_path = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/debug/vegetation/essential/parameters_vector_data_x143-y317-w35-h35-al0.0-alo0.02-alp10.0-tl0.1-vl0.1-bp1.0-um1.0_0.8.tiff";
		String  parameters_path = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/debug/vegetation/essential/parameters_vector_data_x143-y317-w35-h35-al10.0-alo0.0-alp10.0-tl0.1-vl0.1-bp1.0-um1.0_0.8-live.tiff";
//		String  parameters_path = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/debug/vegetation/essential/parameters_vector_data_x143-y317-w35-h35-al10.0-alo0.0-alp10.0-tl0.1-vl0.1-bp1.0-um1.0_0.8-live.tiff";
		String  parameters_path = "/media/elphel/SSD3-4GB/lwir16-proc/berdich3/debug/vegetation/essential/parameters_vector_data_x143-y317-w35-h35-al100.0-alo0.0-alp10.0-alin-tl0.2-vl0.01-tp0.01-vp0.01-bp5.0-um1.0_0.8.tiff";
		
				
		if (um_en) {
			double [][] um_data = new double [terrain_rendered.length+2][];
			System.arraycopy(terrain_rendered, 0, um_data, 0, terrain_rendered.length);
@@ -787,6 +821,13 @@ public class VegetationModel {
					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
					alpha_lpf,     // final double             alpha_lpf,          // pull to average of 4 neighbors
					alpha_piece_linear, // final boolean       alpha_piece_linear, // true - piece-linear, false - half-cosine
					alpha_scale_avg, // final double             alpha_scale_avg, //  = 1.2; // scale average alpha (around 0.5) when pulling to it
					alpha_push,      //  final double             alpha_push,      //  5.0;   // push from alpha==0.5
					alpha_push_neutral, // double    alpha_push_neutral = 0.8; // alpha point from which push (closer to opaque)
					alpha_push_center,// final double             alpha_push_center,// 1.5; // weight of center alpha pixel relative to each of the 4 ortho ones
					alpha_mm_hole,   //  double    alpha_mm_hole    = 0.1; // NaN to disable. Local "almost minimum" (lower than this fraction between min and max neighbor) is not subject to alpha_lpf

					terr_lpf,      // final double             terr_lpf,           // pull terrain to average of 4 neighbors (very small)
					veget_lpf,     // final double             veget_lpf,          // pull vegetation to average of 4 neighbors (very small - maybe not needed)
					terr_pull0,     // final double             terr_pull0,        // pull terrain to zero (makes sense with UM
@@ -807,8 +848,6 @@ public class VegetationModel {
						min_max_terrain, // double      min_max_terrain, //0.1
						min_terrain,                         //double      min_terrain, //0.001
						min_vegetation);                     // double      min_vegetation) { // 0.5				


			}
			next_run = true;
			double  lambda =            5.0; // 0.1;