Loading src/main/java/com/elphel/imagej/vegetation/VegetationLMA.java +84 −262 Original line number Original line Diff line number Diff line Loading @@ -956,11 +956,12 @@ public class VegetationLMA { } } ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads); // regularization weights and derivatives // regularization weights and derivatives // splitting alpha_lpf from alpha_loss+alpha_push int ind_next = y_vector.length; int ind_next = y_vector.length; if ((alpha_lpf >= 0) || (alpha_loss > 0)) { if ((alpha_loss > 0) || (alpha_push > 0)) { int dbg_nx = -76340; int dbg_nx = -76340; final int ind_y_alpha = ind_next; final int ind_y_alpha_loss = ind_next; ind_next += num_pars_vegetation_alpha; ind_next += num_pars_vegetation_alpha; ai.set(0); ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) { Loading @@ -968,7 +969,7 @@ public class VegetationLMA { public void run() { public void run() { for (int n = ai.getAndIncrement(); n < num_pars_vegetation_alpha; n = ai.getAndIncrement()) { 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 np = ind_pars_vegetation_alpha + n; // index of the alpha parameter int nx = n + ind_y_alpha; // y_vector.length; // x - index int nx = n + ind_y_alpha_loss; // y_vector.length; // x - index if (nx == dbg_nx) { if (nx == dbg_nx) { System.out.println("getFxDerivs(): n="+n+", nx="+nx); System.out.println("getFxDerivs(): n="+n+", nx="+nx); } } Loading Loading @@ -1027,12 +1028,56 @@ public class VegetationLMA { } } } } } } } } }; } ImageDtt.startAndJoin(threads); } // if ((alpha_loss > 0) || (alpha_push > 0)){ if (alpha_lpf >= 0) { int dbg_nx = -76340; final int ind_y_alpha_lpf = ind_next; ind_next += num_pars_vegetation_alpha; ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { 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_lpf; // y_vector.length; // x - index if (nx == dbg_nx) { System.out.println("getFxDerivs(): n="+n+", nx="+nx); } double d = 0; fX[nx] = 0.0; 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 // add cost for difference between this alpha and average of 4 neighbors (when they exist // 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) // applies to alpha before cosine, so it will pull borders even when alpha<0 or alpha > 1 (zero derivatives) //alpha_scale_avg //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 mm = neib_min + (neib_max-neib_min) * alpha_mm_hole; double effective_alpha_lpf = alpha_lpf; double effective_alpha_lpf = alpha_lpf; if (!Double.isNaN(alpha_mm_hole) && (vector[np] <= mm) && ((neib_max-neib_min) >= alpha_diff_hole)) { if (!Double.isNaN(alpha_mm_hole) && (vector[np] <= mm) && ((neib_max-neib_min) >= alpha_diff_hole)) { Loading @@ -1042,7 +1087,7 @@ public class VegetationLMA { /// if (Double.isNaN(alpha_mm_hole) || (vector[np] > mm) || ((neib_max-neib_min) < alpha_diff_hole)) { /// if (Double.isNaN(alpha_mm_hole) || (vector[np] > mm) || ((neib_max-neib_min) < alpha_diff_hole)) { // this.alpha_mm_hole = alpha_mm_hole; // this.alpha_mm_hole = alpha_mm_hole; if (alpha_scale_avg == 1) { if (alpha_scale_avg == 1) { fX[nx] += effective_alpha_lpf * (vector[np] - avg); fX[nx] = effective_alpha_lpf * (vector[np] - avg); if (jt != null) { if (jt != null) { jt[np][nx] += effective_alpha_lpf; jt[np][nx] += effective_alpha_lpf; for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased Loading @@ -1055,7 +1100,7 @@ public class VegetationLMA { } else { } else { if ((avg > 0) && (avg < 1)) { if ((avg > 0) && (avg < 1)) { double savg = 0.5 + (avg - 0.5) * alpha_scale_avg; double savg = 0.5 + (avg - 0.5) * alpha_scale_avg; fX[nx] += effective_alpha_lpf * (vector[np] - savg); fX[nx] = effective_alpha_lpf * (vector[np] - savg); if (jt != null) { if (jt != null) { // jt[np][nx] += effective_alpha_lpf; // jt[np][nx] += effective_alpha_lpf; for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased Loading @@ -1067,9 +1112,9 @@ public class VegetationLMA { } } } else { } else { if (avg <= 0) { if (avg <= 0) { fX[nx] += effective_alpha_lpf * (vector[np] + 0.5*(alpha_scale_avg - 1.0)); fX[nx] = effective_alpha_lpf * (vector[np] + 0.5*(alpha_scale_avg - 1.0)); } else { // avg > 1 } else { // avg > 1 fX[nx] += effective_alpha_lpf * (vector[np] - 0.5*(alpha_scale_avg + 1.0)); fX[nx] = effective_alpha_lpf * (vector[np] - 0.5*(alpha_scale_avg + 1.0)); } } } } if (jt != null) { if (jt != null) { Loading @@ -1078,7 +1123,6 @@ public class VegetationLMA { } } } } } } } }; }; } } ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads); Loading Loading @@ -1178,231 +1222,6 @@ public class VegetationLMA { return fX; return fX; } } private double [] getFxDerivs_precos( final double [] vector, final double [][] jt, // should be null or initialized with [vector.length][] final int debug_level) { double [] fX = new double [weights.length]; // num_pairs + vector.length]; if (jt != null) { for (int i = 0; i < jt.length; i++) { jt[i] = new double [weights.length]; // weights.length]; } } 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 [] vegetation = new double [4]; double [] alpha = new double [4]; for (int n = ai.getAndIncrement(); n < y_vector.length; n = ai.getAndIncrement()) { // int nscene = data_source[n][0][0]; // int indx = data_source[n][0][1]; double terrain = vector[data_source[n][0][2]]; double [] cw = corners_weights[n]; double d; int [] indx_vegetation = data_source[n][1]; int [] indx_alpha = data_source[n][2]; double sum_v =0, sum_a =0; if (cw != null) { for (int i = 0; i < 4; i++ ) { int iv = indx_vegetation[i], ia=indx_alpha[i]; vegetation[i] = cw[i] * ((iv >= 0) ? vector[iv]: tvao[TVAO_VEGETATION][-1-iv]); alpha[i] = cw[i] * ((ia >= 0) ? vector[ia]: tvao[TVAO_VEGETATION_ALPHA][-1-ia]); sum_v += vegetation[i]; sum_a += alpha[i]; } d = terrain * (1.0 - sum_a) + sum_v * sum_a; if (jt != null) { jt[data_source[n][0][2]][n] = 1 - sum_a; // d/dterrain for (int i = 0; i < 4; i++ ) { if (indx_vegetation[i] >= 0) { // jt[data_source[n][1][indx_vegetation[i]]][n] = cw[i] * sum_a; // d/dvegetation[i] jt[data_source[n][1][i]][n] = cw[i] * sum_a; // d/dvegetation[i] } if (indx_alpha[i] >= 0) { // jt[data_source[n][2][indx_alpha[i]]][n] = cw[i] * (sum_v - terrain); // d/dalpha[i] jt[data_source[n][2][i]][n] = cw[i] * (sum_v - terrain); // d/dalpha[i] } } } } else { d = terrain; if (jt != null) { jt[data_source[n][0][2]][n] = 1; // d/dterrain } } double scene_offs = vector[data_source[n][0][3]]; fX[n] = d + scene_offs; if (jt != null) { jt[data_source[n][0][3]][n] = 1; } } } }; } ImageDtt.startAndJoin(threads); // regularization weights and derivatives int ind_next = y_vector.length; if (alpha_lpf >= 0) { final int ind_y_alpha = ind_next; ind_next += num_pars_vegetation_alpha; ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { 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 double d = 0; fX[nx] = 0.0; double alpha = vector[np]; if (alpha < alpha_offset) { d = alpha- alpha_offset; } else if (alpha > (1 - alpha_offset)) { d = alpha - (1.0 - alpha_offset); } if (d != 0) { fX[nx] = d * d * alpha_loss; if (jt != null) { jt[np][nx] = 2 * alpha_loss * d; // d/dalpha[i] } } // add cost for difference between this alpha and average of 4 neighbors (when they exist if (alpha_lpf > 0) { double avg = 0; int nn = 0; 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; nn++; } else if (di < -1) { d = tvao[TVAO_VEGETATION_ALPHA][-di - 2]; avg+=d; nn++; } } avg /= nn; // average fX[nx] += alpha_lpf * (vector[np] - avg); if (jt != null) { jt[np][nx] += 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] -= alpha_lpf/nn; } } } } } } }; } ImageDtt.startAndJoin(threads); } // if (alpha_lpf >= 0) { if (terr_lpf >= 0) { final int ind_y_terr = ind_next; ind_next += num_pars_terrain; ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { for (int n = ai.getAndIncrement(); n < num_pars_terrain; n = ai.getAndIncrement()) { int np = ind_pars_terrain + n; // index of the alpha parameter int nx = n + ind_y_terr; // y_vector.length; // x - index double d = 0; if (terr_lpf > 0) { double avg = 0; int nn = 0; for (int i = 0; i < terr_neibs[n].length; i++) { // now 4, may be increased int di = terr_neibs[n][i]; d=0; if (di >= 0) { d = vector[di]; // d - full parameter index avg+=d; nn++; } else if (di < -1) { d = tvao[TVAO_TERRAIN][-di - 2]; avg+=d; nn++; } } avg /= nn; // average fX[nx] += terr_lpf * (vector[np] - avg); if (jt != null) { jt[np][nx] += terr_lpf; for (int i = 0; i < terr_neibs[n].length; i++) { // now 4, may be increased int di = terr_neibs[n][i]; if (di > 0) { jt[di][nx] -= terr_lpf/nn; } } } } } } }; } ImageDtt.startAndJoin(threads); } if (veget_lpf >= 0) { final int ind_y_veget = ind_next; ind_next += num_pars_vegetation; ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { for (int n = ai.getAndIncrement(); n < num_pars_vegetation; n = ai.getAndIncrement()) { int np = ind_pars_vegetation + n; // index of the alpha parameter int nx = n + ind_y_veget; // y_vector.length; // x - index double d = 0; if (veget_lpf > 0) { double avg = 0; int nn = 0; for (int i = 0; i < veget_neibs[n].length; i++) { // now 4, may be increased int di = veget_neibs[n][i]; d=0; if (di >= 0) { d = vector[di]; // d - full parameter index avg+=d; nn++; } else if (di < -1) { d = tvao[TVAO_VEGETATION][-di - 2]; avg+=d; nn++; } } avg /= nn; // average fX[nx] += veget_lpf * (vector[np] - avg); if (jt != null) { jt[np][nx] += veget_lpf; for (int i = 0; i < veget_neibs[n].length; i++) { // now 4, may be increased int di = veget_neibs[n][i]; if (di > 0) { jt[di][nx] -= veget_lpf/nn; } } } } } } }; } ImageDtt.startAndJoin(threads); } return fX; } private double [][] getFxDerivsDelta( private double [][] getFxDerivsDelta( double [] vector, double [] vector, Loading Loading @@ -1629,6 +1448,9 @@ public class VegetationLMA { // int extra_samples = num_pars_vegetation_alpha; // in the future may be more regularization // int extra_samples = num_pars_vegetation_alpha; // in the future may be more regularization int extra_samples = 0; int extra_samples = 0; // using >=0 no use 0 as NOP but reserve space, <0 - do not reserve space // using >=0 no use 0 as NOP but reserve space, <0 - do not reserve space //(alpha_loss > 0) if ((alpha_loss > 0) || (alpha_push > 0)) extra_samples+= num_pars_vegetation_alpha; // need to split loss (always positive) from alpha_lpf if (alpha_lpf >= 0) extra_samples+= num_pars_vegetation_alpha; if (alpha_lpf >= 0) extra_samples+= num_pars_vegetation_alpha; if (terr_lpf >= 0) extra_samples+= num_pars_terrain; if (terr_lpf >= 0) extra_samples+= num_pars_terrain; if (veget_lpf >= 0) extra_samples+= num_pars_vegetation; if (veget_lpf >= 0) extra_samples+= num_pars_vegetation; Loading src/main/java/com/elphel/imagej/vegetation/VegetationModel.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -677,7 +677,8 @@ public class VegetationModel { String [] titles, String [] titles, int debugLevel) { int debugLevel) { boolean diff_mode = true; boolean diff_mode = true; Rectangle woi50 = new Rectangle(143,317,35,35); // Rectangle woi50 = new Rectangle(143,317,35,35); Rectangle woi50 = new Rectangle(160,317,35,35); // X+17 /* Bad, pull terr lower, so it all shifts to terrain /* Bad, pull terr lower, so it all shifts to terrain int min_scenes = 10; int min_scenes = 10; double default_alpha = 0.8; double default_alpha = 0.8; Loading Loading @@ -707,7 +708,7 @@ public class VegetationModel { double reg_weights = 0.25; // fraction of the total weight used for regularization 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_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_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 double alpha_lpf = 5; /// 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; 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_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 = 12; // 10.0; // 15.0; // push from alpha==0.5 Loading Loading
src/main/java/com/elphel/imagej/vegetation/VegetationLMA.java +84 −262 Original line number Original line Diff line number Diff line Loading @@ -956,11 +956,12 @@ public class VegetationLMA { } } ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads); // regularization weights and derivatives // regularization weights and derivatives // splitting alpha_lpf from alpha_loss+alpha_push int ind_next = y_vector.length; int ind_next = y_vector.length; if ((alpha_lpf >= 0) || (alpha_loss > 0)) { if ((alpha_loss > 0) || (alpha_push > 0)) { int dbg_nx = -76340; int dbg_nx = -76340; final int ind_y_alpha = ind_next; final int ind_y_alpha_loss = ind_next; ind_next += num_pars_vegetation_alpha; ind_next += num_pars_vegetation_alpha; ai.set(0); ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) { Loading @@ -968,7 +969,7 @@ public class VegetationLMA { public void run() { public void run() { for (int n = ai.getAndIncrement(); n < num_pars_vegetation_alpha; n = ai.getAndIncrement()) { 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 np = ind_pars_vegetation_alpha + n; // index of the alpha parameter int nx = n + ind_y_alpha; // y_vector.length; // x - index int nx = n + ind_y_alpha_loss; // y_vector.length; // x - index if (nx == dbg_nx) { if (nx == dbg_nx) { System.out.println("getFxDerivs(): n="+n+", nx="+nx); System.out.println("getFxDerivs(): n="+n+", nx="+nx); } } Loading Loading @@ -1027,12 +1028,56 @@ public class VegetationLMA { } } } } } } } } }; } ImageDtt.startAndJoin(threads); } // if ((alpha_loss > 0) || (alpha_push > 0)){ if (alpha_lpf >= 0) { int dbg_nx = -76340; final int ind_y_alpha_lpf = ind_next; ind_next += num_pars_vegetation_alpha; ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { 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_lpf; // y_vector.length; // x - index if (nx == dbg_nx) { System.out.println("getFxDerivs(): n="+n+", nx="+nx); } double d = 0; fX[nx] = 0.0; 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 // add cost for difference between this alpha and average of 4 neighbors (when they exist // 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) // applies to alpha before cosine, so it will pull borders even when alpha<0 or alpha > 1 (zero derivatives) //alpha_scale_avg //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 mm = neib_min + (neib_max-neib_min) * alpha_mm_hole; double effective_alpha_lpf = alpha_lpf; double effective_alpha_lpf = alpha_lpf; if (!Double.isNaN(alpha_mm_hole) && (vector[np] <= mm) && ((neib_max-neib_min) >= alpha_diff_hole)) { if (!Double.isNaN(alpha_mm_hole) && (vector[np] <= mm) && ((neib_max-neib_min) >= alpha_diff_hole)) { Loading @@ -1042,7 +1087,7 @@ public class VegetationLMA { /// if (Double.isNaN(alpha_mm_hole) || (vector[np] > mm) || ((neib_max-neib_min) < alpha_diff_hole)) { /// if (Double.isNaN(alpha_mm_hole) || (vector[np] > mm) || ((neib_max-neib_min) < alpha_diff_hole)) { // this.alpha_mm_hole = alpha_mm_hole; // this.alpha_mm_hole = alpha_mm_hole; if (alpha_scale_avg == 1) { if (alpha_scale_avg == 1) { fX[nx] += effective_alpha_lpf * (vector[np] - avg); fX[nx] = effective_alpha_lpf * (vector[np] - avg); if (jt != null) { if (jt != null) { jt[np][nx] += effective_alpha_lpf; jt[np][nx] += effective_alpha_lpf; for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased Loading @@ -1055,7 +1100,7 @@ public class VegetationLMA { } else { } else { if ((avg > 0) && (avg < 1)) { if ((avg > 0) && (avg < 1)) { double savg = 0.5 + (avg - 0.5) * alpha_scale_avg; double savg = 0.5 + (avg - 0.5) * alpha_scale_avg; fX[nx] += effective_alpha_lpf * (vector[np] - savg); fX[nx] = effective_alpha_lpf * (vector[np] - savg); if (jt != null) { if (jt != null) { // jt[np][nx] += effective_alpha_lpf; // jt[np][nx] += effective_alpha_lpf; for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased for (int i = 0; i < alpha_neibs[n].length; i++) { // now 4, may be increased Loading @@ -1067,9 +1112,9 @@ public class VegetationLMA { } } } else { } else { if (avg <= 0) { if (avg <= 0) { fX[nx] += effective_alpha_lpf * (vector[np] + 0.5*(alpha_scale_avg - 1.0)); fX[nx] = effective_alpha_lpf * (vector[np] + 0.5*(alpha_scale_avg - 1.0)); } else { // avg > 1 } else { // avg > 1 fX[nx] += effective_alpha_lpf * (vector[np] - 0.5*(alpha_scale_avg + 1.0)); fX[nx] = effective_alpha_lpf * (vector[np] - 0.5*(alpha_scale_avg + 1.0)); } } } } if (jt != null) { if (jt != null) { Loading @@ -1078,7 +1123,6 @@ public class VegetationLMA { } } } } } } } }; }; } } ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads); Loading Loading @@ -1178,231 +1222,6 @@ public class VegetationLMA { return fX; return fX; } } private double [] getFxDerivs_precos( final double [] vector, final double [][] jt, // should be null or initialized with [vector.length][] final int debug_level) { double [] fX = new double [weights.length]; // num_pairs + vector.length]; if (jt != null) { for (int i = 0; i < jt.length; i++) { jt[i] = new double [weights.length]; // weights.length]; } } 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 [] vegetation = new double [4]; double [] alpha = new double [4]; for (int n = ai.getAndIncrement(); n < y_vector.length; n = ai.getAndIncrement()) { // int nscene = data_source[n][0][0]; // int indx = data_source[n][0][1]; double terrain = vector[data_source[n][0][2]]; double [] cw = corners_weights[n]; double d; int [] indx_vegetation = data_source[n][1]; int [] indx_alpha = data_source[n][2]; double sum_v =0, sum_a =0; if (cw != null) { for (int i = 0; i < 4; i++ ) { int iv = indx_vegetation[i], ia=indx_alpha[i]; vegetation[i] = cw[i] * ((iv >= 0) ? vector[iv]: tvao[TVAO_VEGETATION][-1-iv]); alpha[i] = cw[i] * ((ia >= 0) ? vector[ia]: tvao[TVAO_VEGETATION_ALPHA][-1-ia]); sum_v += vegetation[i]; sum_a += alpha[i]; } d = terrain * (1.0 - sum_a) + sum_v * sum_a; if (jt != null) { jt[data_source[n][0][2]][n] = 1 - sum_a; // d/dterrain for (int i = 0; i < 4; i++ ) { if (indx_vegetation[i] >= 0) { // jt[data_source[n][1][indx_vegetation[i]]][n] = cw[i] * sum_a; // d/dvegetation[i] jt[data_source[n][1][i]][n] = cw[i] * sum_a; // d/dvegetation[i] } if (indx_alpha[i] >= 0) { // jt[data_source[n][2][indx_alpha[i]]][n] = cw[i] * (sum_v - terrain); // d/dalpha[i] jt[data_source[n][2][i]][n] = cw[i] * (sum_v - terrain); // d/dalpha[i] } } } } else { d = terrain; if (jt != null) { jt[data_source[n][0][2]][n] = 1; // d/dterrain } } double scene_offs = vector[data_source[n][0][3]]; fX[n] = d + scene_offs; if (jt != null) { jt[data_source[n][0][3]][n] = 1; } } } }; } ImageDtt.startAndJoin(threads); // regularization weights and derivatives int ind_next = y_vector.length; if (alpha_lpf >= 0) { final int ind_y_alpha = ind_next; ind_next += num_pars_vegetation_alpha; ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { 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 double d = 0; fX[nx] = 0.0; double alpha = vector[np]; if (alpha < alpha_offset) { d = alpha- alpha_offset; } else if (alpha > (1 - alpha_offset)) { d = alpha - (1.0 - alpha_offset); } if (d != 0) { fX[nx] = d * d * alpha_loss; if (jt != null) { jt[np][nx] = 2 * alpha_loss * d; // d/dalpha[i] } } // add cost for difference between this alpha and average of 4 neighbors (when they exist if (alpha_lpf > 0) { double avg = 0; int nn = 0; 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; nn++; } else if (di < -1) { d = tvao[TVAO_VEGETATION_ALPHA][-di - 2]; avg+=d; nn++; } } avg /= nn; // average fX[nx] += alpha_lpf * (vector[np] - avg); if (jt != null) { jt[np][nx] += 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] -= alpha_lpf/nn; } } } } } } }; } ImageDtt.startAndJoin(threads); } // if (alpha_lpf >= 0) { if (terr_lpf >= 0) { final int ind_y_terr = ind_next; ind_next += num_pars_terrain; ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { for (int n = ai.getAndIncrement(); n < num_pars_terrain; n = ai.getAndIncrement()) { int np = ind_pars_terrain + n; // index of the alpha parameter int nx = n + ind_y_terr; // y_vector.length; // x - index double d = 0; if (terr_lpf > 0) { double avg = 0; int nn = 0; for (int i = 0; i < terr_neibs[n].length; i++) { // now 4, may be increased int di = terr_neibs[n][i]; d=0; if (di >= 0) { d = vector[di]; // d - full parameter index avg+=d; nn++; } else if (di < -1) { d = tvao[TVAO_TERRAIN][-di - 2]; avg+=d; nn++; } } avg /= nn; // average fX[nx] += terr_lpf * (vector[np] - avg); if (jt != null) { jt[np][nx] += terr_lpf; for (int i = 0; i < terr_neibs[n].length; i++) { // now 4, may be increased int di = terr_neibs[n][i]; if (di > 0) { jt[di][nx] -= terr_lpf/nn; } } } } } } }; } ImageDtt.startAndJoin(threads); } if (veget_lpf >= 0) { final int ind_y_veget = ind_next; ind_next += num_pars_vegetation; ai.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { public void run() { for (int n = ai.getAndIncrement(); n < num_pars_vegetation; n = ai.getAndIncrement()) { int np = ind_pars_vegetation + n; // index of the alpha parameter int nx = n + ind_y_veget; // y_vector.length; // x - index double d = 0; if (veget_lpf > 0) { double avg = 0; int nn = 0; for (int i = 0; i < veget_neibs[n].length; i++) { // now 4, may be increased int di = veget_neibs[n][i]; d=0; if (di >= 0) { d = vector[di]; // d - full parameter index avg+=d; nn++; } else if (di < -1) { d = tvao[TVAO_VEGETATION][-di - 2]; avg+=d; nn++; } } avg /= nn; // average fX[nx] += veget_lpf * (vector[np] - avg); if (jt != null) { jt[np][nx] += veget_lpf; for (int i = 0; i < veget_neibs[n].length; i++) { // now 4, may be increased int di = veget_neibs[n][i]; if (di > 0) { jt[di][nx] -= veget_lpf/nn; } } } } } } }; } ImageDtt.startAndJoin(threads); } return fX; } private double [][] getFxDerivsDelta( private double [][] getFxDerivsDelta( double [] vector, double [] vector, Loading Loading @@ -1629,6 +1448,9 @@ public class VegetationLMA { // int extra_samples = num_pars_vegetation_alpha; // in the future may be more regularization // int extra_samples = num_pars_vegetation_alpha; // in the future may be more regularization int extra_samples = 0; int extra_samples = 0; // using >=0 no use 0 as NOP but reserve space, <0 - do not reserve space // using >=0 no use 0 as NOP but reserve space, <0 - do not reserve space //(alpha_loss > 0) if ((alpha_loss > 0) || (alpha_push > 0)) extra_samples+= num_pars_vegetation_alpha; // need to split loss (always positive) from alpha_lpf if (alpha_lpf >= 0) extra_samples+= num_pars_vegetation_alpha; if (alpha_lpf >= 0) extra_samples+= num_pars_vegetation_alpha; if (terr_lpf >= 0) extra_samples+= num_pars_terrain; if (terr_lpf >= 0) extra_samples+= num_pars_terrain; if (veget_lpf >= 0) extra_samples+= num_pars_vegetation; if (veget_lpf >= 0) extra_samples+= num_pars_vegetation; Loading
src/main/java/com/elphel/imagej/vegetation/VegetationModel.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -677,7 +677,8 @@ public class VegetationModel { String [] titles, String [] titles, int debugLevel) { int debugLevel) { boolean diff_mode = true; boolean diff_mode = true; Rectangle woi50 = new Rectangle(143,317,35,35); // Rectangle woi50 = new Rectangle(143,317,35,35); Rectangle woi50 = new Rectangle(160,317,35,35); // X+17 /* Bad, pull terr lower, so it all shifts to terrain /* Bad, pull terr lower, so it all shifts to terrain int min_scenes = 10; int min_scenes = 10; double default_alpha = 0.8; double default_alpha = 0.8; Loading Loading @@ -707,7 +708,7 @@ public class VegetationModel { double reg_weights = 0.25; // fraction of the total weight used for regularization 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_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_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 double alpha_lpf = 5; /// 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; 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_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 = 12; // 10.0; // 15.0; // push from alpha==0.5 Loading