Loading src/main/java/com/elphel/imagej/vegetation/VegetationLMA.java +117 −41 Original line number Original line Diff line number Diff line Loading @@ -37,6 +37,11 @@ public class VegetationLMA { // private double default_alpha; // private double default_alpha; private int num_pars_terrain; private int num_pars_terrain; private int num_pars_vegetation; private int num_pars_vegetation; private int num_pars_vegetation_alpha; //== num_pars_vegetation private int ind_pars_terrain = 0; // index of the first terrain parameter private int ind_pars_vegetation; // index of the first vegetation parameter private int ind_pars_vegetation_alpha; // index of the first alpha parameter private int ind_pars_scenes; // index of the first scene parameter private int num_pars_scenes; private int num_pars_scenes; private int [][][] data_source; // [index][windx][3]: private int [][][] data_source; // [index][windx][3]: // 0:{ scene, full_indx, terr_indx, scale_indx} - always present as parameters // 0:{ scene, full_indx, terr_indx, scale_indx} - always present as parameters Loading @@ -48,10 +53,13 @@ public class VegetationLMA { private double [] y_vector = null; private double [] y_vector = null; private double weight_pure = 0; private double weight_pure = 0; private double [] weights; // normalized so sum is 1.0 for all - samples and extra regularization private double [] weights; // normalized so sum is 1.0 for all - samples and extra regularization public double alpha_loss; public double alpha_offset = 0; // if >0, start losses above 0.0 and below 1.0; public double delta= 1e-5; // 7; public double delta= 1e-5; // 7; public int debug_index; public double [][] debug_image; public static double [] debug_alpha_scales = {100,150}; public int [] indices; public int [] indices; public int [][] cpairs = null; public int [][] cpairs = null; Loading Loading @@ -101,8 +109,13 @@ public class VegetationLMA { final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence final double default_alpha, final double default_alpha, final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? final double reg_weights, // fraction of the total weight used for regularization final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0 final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0 final int debugLevel) { final int debugLevel) { this.woi = woi; this.woi = woi; this.alpha_loss = alpha_loss; this.alpha_offset = alpha_offset; // this.default_alpha = default_alpha; // this.default_alpha = default_alpha; int min_scenes_uses = min_scenes; int min_scenes_uses = min_scenes; int min_scenes_used = min_scenes * 4; int min_scenes_used = min_scenes * 4; Loading @@ -114,16 +127,14 @@ public class VegetationLMA { setupParametersVector (default_alpha); // areas where both terrain and vegetation are available setupParametersVector (default_alpha); // areas where both terrain and vegetation are available setupDataSource(); // condensed setupDataSource(); // condensed setupYVector(); setupYVector(); setupWeights(scene_weights); setupWeights( // after setupParametersIndices scene_weights, reg_weights); // final double reg_weights); last_jt = new double [parameters_vector.length][]; last_jt = new double [parameters_vector.length][]; return weights.length; return weights.length; } } private double [] getYminusFxWeighted( private double [] getYminusFxWeighted( final double [] fx, final double [] fx, final double [] rms_fp // null or [2] final double [] rms_fp // null or [2] Loading Loading @@ -154,6 +165,9 @@ public class VegetationLMA { // System.out.println("ai.get()="+ai.get()); // System.out.println("ai.get()="+ai.get()); // important to set - after first cycle ai is left 16(number of threads) larger than number of cycles! // important to set - after first cycle ai is left 16(number of threads) larger than number of cycles! // It is so, because it first increments, then tests if (n < num_pairs) // It is so, because it first increments, then tests if (n < num_pairs) // Regularization part where y is assumed==0, only fX is used ai.set(y_vector.length); // not yet used ai.set(y_vector.length); // not yet used ati.set(0); ati.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) { Loading Loading @@ -312,22 +326,25 @@ public class VegetationLMA { } } if (debug_level > 3) { // 0) { if (debug_level > 3) { // 0) { double delta = this.delta; // 1E-3; double delta = this.delta; // 1E-3; if (debug_level > 4) { double delta_err= debugDerivs ( double delta_err= debugDerivs ( parameters_vector, // double [] vector, parameters_vector, // double [] vector, delta, // double delta, delta, // double delta, debug_level, //int debugLevel, debug_level, //int debugLevel, false); // boolean show_img) false); // boolean show_img) System.out.println("\nMaximal error = "+delta_err); System.out.println("\nMaximal error = "+delta_err); } int [] wh = new int[2]; int [] wh = new int[2]; double [] debug_image = parametersImage ( double [] debug_image = parametersImage ( parameters_vector, // double [] vector, parameters_vector, // double [] vector, 1, // int gap) 1, // int gap) wh); wh, null); // String title) ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays( debug_image, debug_image, wh[0], wh[0], wh[1], wh[1], "parameters.vector"); "parameters.vector-"+debug_index); } } Loading Loading @@ -402,13 +419,27 @@ public class VegetationLMA { rslt[0] = true; rslt[0] = true; rslt[1] = rms[0] >=(this.last_rms[0] * (1.0 - rms_diff)); rslt[1] = rms[0] >=(this.last_rms[0] * (1.0 - rms_diff)); this.last_rms = rms.clone(); this.last_rms = rms.clone(); this.parameters_vector = new_vector.clone(); this.parameters_vector = new_vector.clone(); if (debug_level > 3) { if (debug_level > 2) { double [] debug_image = parametersImage ( String title = (debug_level > 3)? "parameters.vector":null; int [] wh = new int [2]; double [] debug_img = parametersImage ( parameters_vector, // double [] vector, parameters_vector, // double [] vector, 1, // int gap) 1, // int gap) null); wh, title); if ((debug_image != null) && (debug_index < debug_image.length)) { debug_image[debug_index++] = debug_img; } if (debug_level > 4) { ShowDoubleFloatArrays.showArrays( debug_image, wh[0], wh[1], true, "parameters_vector_live.tiff"); } // print vectors in some format // print vectors in some format /* /* Loading Loading @@ -514,7 +545,7 @@ public class VegetationLMA { public void run() { public void run() { double [] vegetation = new double [4]; double [] vegetation = new double [4]; double [] alpha = new double [4]; double [] alpha = new double [4]; for (int n = ai.getAndIncrement(); n < weights.length; n = ai.getAndIncrement()) { for (int n = ai.getAndIncrement(); n < y_vector.length; n = ai.getAndIncrement()) { // int nscene = data_source[n][0][0]; // int nscene = data_source[n][0][0]; // int indx = data_source[n][0][1]; // int indx = data_source[n][0][1]; double terrain = vector[data_source[n][0][2]]; double terrain = vector[data_source[n][0][2]]; Loading Loading @@ -563,6 +594,35 @@ public class VegetationLMA { }; }; } } ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads); // regularization weights and derivatives 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 + 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] } } } } }; } ImageDtt.startAndJoin(threads); return fX; return fX; } } Loading Loading @@ -624,7 +684,8 @@ public class VegetationLMA { public double [] parametersImage ( public double [] parametersImage ( double [] vector, double [] vector, int gap, int gap, int [] wh) { int [] wh, String title) { int [] indices = getParamDebugIndices (gap); int [] indices = getParamDebugIndices (gap); int woi_width3=woi.width*3 + 2 * gap; int woi_width3=woi.width*3 + 2 * gap; double [] dbg_img = new double [indices.length]; double [] dbg_img = new double [indices.length]; Loading @@ -633,18 +694,24 @@ public class VegetationLMA { dbg_img[i] = Double.NaN; dbg_img[i] = Double.NaN; } else { } else { dbg_img[i]= vector[indices[i]]; dbg_img[i]= vector[indices[i]]; // scale alpha for the same image int w = i % woi_width3; if (w > 2 *( woi.width+ gap)) { dbg_img[i] = debug_alpha_scales[0] + (debug_alpha_scales[1] - debug_alpha_scales[0]) * dbg_img[i]; } } } } } if (wh != null) { if (wh != null) { wh[0] = woi_width3; wh[0] = woi_width3; wh[1] = indices.length/woi_width3; wh[1] = indices.length/woi_width3; } } if (title != null) { ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays( dbg_img, dbg_img, woi_width3, woi_width3, indices.length/woi_width3, indices.length/woi_width3, "parameters.vector"); title); } return dbg_img; return dbg_img; } } Loading Loading @@ -683,9 +750,11 @@ public class VegetationLMA { } } private void setupWeights(final double [] scene_weights) { private void setupWeights( // after setupParametersIndices int extra_samples = 0; // in the future may be regularization final double [] scene_weights, double extra_weights = 0.0; final double reg_weights) { int extra_samples = num_pars_vegetation_alpha; // in the future may be more regularization double reg_sample_weight = reg_weights/num_pars_vegetation_alpha; // weight of each regularization sample final double [] sw = (scene_weights != null) ? scene_weights : new double [num_scenes]; final double [] sw = (scene_weights != null) ? scene_weights : new double [num_scenes]; if (scene_weights == null) { if (scene_weights == null) { Arrays.fill (sw, 1.0); Arrays.fill (sw, 1.0); Loading @@ -693,15 +762,17 @@ public class VegetationLMA { weights = new double [data_source.length + extra_samples]; weights = new double [data_source.length + extra_samples]; double s = 0; double s = 0; for (int ny = 0; ny < data_source.length; ny++) { for (int ny = 0; ny < data_source.length; ny++) { s += sw[data_source[ny][0][0]]; int nscene = data_source[ny][0][0]; // int indx = data_source[ny][0][1]; s += sw[nscene]; } } final double s0 = s; final double s0 = s; for (int i = 0; i < extra_samples; i++) { s *= (1+ reg_weights); s+=extra_weights; } final double k = 1.0/s; final double k = 1.0/s; weight_pure = s0/s; weight_pure = s0/s; // for (int i = 0; i < extra_samples; i++) { // s+=extra_weights; // } final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX); final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX); final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0); for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) { Loading @@ -711,7 +782,7 @@ public class VegetationLMA { if (nw < data_source.length) { if (nw < data_source.length) { weights[nw] = sw[data_source[nw][0][0]] * k; weights[nw] = sw[data_source[nw][0][0]] * k; } else { } else { weights[nw] = extra_weights * k; weights[nw] = reg_sample_weight; } } } } } } Loading Loading @@ -872,6 +943,7 @@ public class VegetationLMA { Arrays.fill(par_index[TVAO_VEGETATION], -1); Arrays.fill(par_index[TVAO_VEGETATION], -1); Arrays.fill(par_index[TVAO_VEGETATION_ALPHA], -1); Arrays.fill(par_index[TVAO_VEGETATION_ALPHA], -1); int par_num = 0; int par_num = 0; ind_pars_terrain = 0; for (int drow = 0; drow < woi.height; drow++) { for (int drow = 0; drow < woi.height; drow++) { int row = woi.y + drow; int row = woi.y + drow; for (int dcol = 0; dcol < woi.width; dcol++) { for (int dcol = 0; dcol < woi.width; dcol++) { Loading @@ -884,6 +956,7 @@ public class VegetationLMA { } } } } num_pars_terrain = par_num; num_pars_terrain = par_num; ind_pars_vegetation = par_num; for (int drow = 0; drow < woi.height; drow++) { for (int drow = 0; drow < woi.height; drow++) { int row = woi.y + drow; int row = woi.y + drow; for (int dcol = 0; dcol < woi.width; dcol++) { for (int dcol = 0; dcol < woi.width; dcol++) { Loading @@ -895,7 +968,8 @@ public class VegetationLMA { } } } } } } num_pars_vegetation = par_num - num_pars_terrain; ind_pars_vegetation_alpha = par_num; num_pars_vegetation = par_num - ind_pars_vegetation; for (int drow = 0; drow < woi.height; drow++) { for (int drow = 0; drow < woi.height; drow++) { int row = woi.y + drow; int row = woi.y + drow; for (int dcol = 0; dcol < woi.width; dcol++) { for (int dcol = 0; dcol < woi.width; dcol++) { Loading @@ -907,11 +981,13 @@ public class VegetationLMA { } } } } } } int num_pars_pixel = par_num; num_pars_vegetation_alpha = par_num - ind_pars_vegetation_alpha; // normally should be == num_pars_vegetation // int num_pars_pixel = par_num; ind_pars_scenes = par_num; for (int i = 0; i < par_index[TVAO_SCENE_OFFSET].length; i++) { for (int i = 0; i < par_index[TVAO_SCENE_OFFSET].length; i++) { par_index[TVAO_SCENE_OFFSET][i] = par_num++; par_index[TVAO_SCENE_OFFSET][i] = par_num++; } } num_pars_scenes = par_num - num_pars_pixel; num_pars_scenes = par_num - ind_pars_scenes; parameters_vector = new double [par_num]; parameters_vector = new double [par_num]; } } Loading src/main/java/com/elphel/imagej/vegetation/VegetationModel.java +11 −1 Original line number Original line Diff line number Diff line Loading @@ -698,11 +698,18 @@ public class VegetationModel { int min_scenes = 10; int min_scenes = 10; double default_alpha = 0.8; double default_alpha = 0.8; double [] scene_weights = null; double [] scene_weights = null; double reg_weights = 0.25; // fraction of the total weight used for regularization double alpha_loss = 1.0; // quadratic loss when alpha reaches -1.0 or 2.0 double alpha_offset = 0.0; // if >0, start losses above 0.0 and below 1.0; int num_samples = vegetationLMA.prepareLMA( int num_samples = vegetationLMA.prepareLMA( woi50, // final Rectangle woi, woi50, // final Rectangle woi, min_scenes, // final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence min_scenes, // final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence default_alpha, // final double default_alpha, default_alpha, // final double default_alpha, scene_weights, // final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? scene_weights, // final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? reg_weights, // final double reg_weights, // fraction of the total weight used for regularization alpha_loss, // final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0 alpha_offset, // final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0 debugLevel); // final int debugLevel); debugLevel); // final int debugLevel); double lambda = 0.1; double lambda = 0.1; Loading @@ -712,6 +719,9 @@ public class VegetationModel { boolean last_run = false; boolean last_run = false; double rms_diff = 0.0001; double rms_diff = 0.0001; int num_iter = 100; int num_iter = 100; vegetationLMA.debug_index = 0; vegetationLMA.debug_image = new double [num_iter][]; int lma_rslt= vegetationLMA.runLma( // <0 - failed, >=0 iteration number (1 - immediately) int lma_rslt= vegetationLMA.runLma( // <0 - failed, >=0 iteration number (1 - immediately) lambda, // double lambda, // 0.1 lambda, // double lambda, // 0.1 lambda_scale_good,// double lambda_scale_good,// 0.5 lambda_scale_good,// double lambda_scale_good,// 0.5 Loading Loading
src/main/java/com/elphel/imagej/vegetation/VegetationLMA.java +117 −41 Original line number Original line Diff line number Diff line Loading @@ -37,6 +37,11 @@ public class VegetationLMA { // private double default_alpha; // private double default_alpha; private int num_pars_terrain; private int num_pars_terrain; private int num_pars_vegetation; private int num_pars_vegetation; private int num_pars_vegetation_alpha; //== num_pars_vegetation private int ind_pars_terrain = 0; // index of the first terrain parameter private int ind_pars_vegetation; // index of the first vegetation parameter private int ind_pars_vegetation_alpha; // index of the first alpha parameter private int ind_pars_scenes; // index of the first scene parameter private int num_pars_scenes; private int num_pars_scenes; private int [][][] data_source; // [index][windx][3]: private int [][][] data_source; // [index][windx][3]: // 0:{ scene, full_indx, terr_indx, scale_indx} - always present as parameters // 0:{ scene, full_indx, terr_indx, scale_indx} - always present as parameters Loading @@ -48,10 +53,13 @@ public class VegetationLMA { private double [] y_vector = null; private double [] y_vector = null; private double weight_pure = 0; private double weight_pure = 0; private double [] weights; // normalized so sum is 1.0 for all - samples and extra regularization private double [] weights; // normalized so sum is 1.0 for all - samples and extra regularization public double alpha_loss; public double alpha_offset = 0; // if >0, start losses above 0.0 and below 1.0; public double delta= 1e-5; // 7; public double delta= 1e-5; // 7; public int debug_index; public double [][] debug_image; public static double [] debug_alpha_scales = {100,150}; public int [] indices; public int [] indices; public int [][] cpairs = null; public int [][] cpairs = null; Loading Loading @@ -101,8 +109,13 @@ public class VegetationLMA { final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence final double default_alpha, final double default_alpha, final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? final double reg_weights, // fraction of the total weight used for regularization final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0 final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0 final int debugLevel) { final int debugLevel) { this.woi = woi; this.woi = woi; this.alpha_loss = alpha_loss; this.alpha_offset = alpha_offset; // this.default_alpha = default_alpha; // this.default_alpha = default_alpha; int min_scenes_uses = min_scenes; int min_scenes_uses = min_scenes; int min_scenes_used = min_scenes * 4; int min_scenes_used = min_scenes * 4; Loading @@ -114,16 +127,14 @@ public class VegetationLMA { setupParametersVector (default_alpha); // areas where both terrain and vegetation are available setupParametersVector (default_alpha); // areas where both terrain and vegetation are available setupDataSource(); // condensed setupDataSource(); // condensed setupYVector(); setupYVector(); setupWeights(scene_weights); setupWeights( // after setupParametersIndices scene_weights, reg_weights); // final double reg_weights); last_jt = new double [parameters_vector.length][]; last_jt = new double [parameters_vector.length][]; return weights.length; return weights.length; } } private double [] getYminusFxWeighted( private double [] getYminusFxWeighted( final double [] fx, final double [] fx, final double [] rms_fp // null or [2] final double [] rms_fp // null or [2] Loading Loading @@ -154,6 +165,9 @@ public class VegetationLMA { // System.out.println("ai.get()="+ai.get()); // System.out.println("ai.get()="+ai.get()); // important to set - after first cycle ai is left 16(number of threads) larger than number of cycles! // important to set - after first cycle ai is left 16(number of threads) larger than number of cycles! // It is so, because it first increments, then tests if (n < num_pairs) // It is so, because it first increments, then tests if (n < num_pairs) // Regularization part where y is assumed==0, only fX is used ai.set(y_vector.length); // not yet used ai.set(y_vector.length); // not yet used ati.set(0); ati.set(0); for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) { Loading Loading @@ -312,22 +326,25 @@ public class VegetationLMA { } } if (debug_level > 3) { // 0) { if (debug_level > 3) { // 0) { double delta = this.delta; // 1E-3; double delta = this.delta; // 1E-3; if (debug_level > 4) { double delta_err= debugDerivs ( double delta_err= debugDerivs ( parameters_vector, // double [] vector, parameters_vector, // double [] vector, delta, // double delta, delta, // double delta, debug_level, //int debugLevel, debug_level, //int debugLevel, false); // boolean show_img) false); // boolean show_img) System.out.println("\nMaximal error = "+delta_err); System.out.println("\nMaximal error = "+delta_err); } int [] wh = new int[2]; int [] wh = new int[2]; double [] debug_image = parametersImage ( double [] debug_image = parametersImage ( parameters_vector, // double [] vector, parameters_vector, // double [] vector, 1, // int gap) 1, // int gap) wh); wh, null); // String title) ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays( debug_image, debug_image, wh[0], wh[0], wh[1], wh[1], "parameters.vector"); "parameters.vector-"+debug_index); } } Loading Loading @@ -402,13 +419,27 @@ public class VegetationLMA { rslt[0] = true; rslt[0] = true; rslt[1] = rms[0] >=(this.last_rms[0] * (1.0 - rms_diff)); rslt[1] = rms[0] >=(this.last_rms[0] * (1.0 - rms_diff)); this.last_rms = rms.clone(); this.last_rms = rms.clone(); this.parameters_vector = new_vector.clone(); this.parameters_vector = new_vector.clone(); if (debug_level > 3) { if (debug_level > 2) { double [] debug_image = parametersImage ( String title = (debug_level > 3)? "parameters.vector":null; int [] wh = new int [2]; double [] debug_img = parametersImage ( parameters_vector, // double [] vector, parameters_vector, // double [] vector, 1, // int gap) 1, // int gap) null); wh, title); if ((debug_image != null) && (debug_index < debug_image.length)) { debug_image[debug_index++] = debug_img; } if (debug_level > 4) { ShowDoubleFloatArrays.showArrays( debug_image, wh[0], wh[1], true, "parameters_vector_live.tiff"); } // print vectors in some format // print vectors in some format /* /* Loading Loading @@ -514,7 +545,7 @@ public class VegetationLMA { public void run() { public void run() { double [] vegetation = new double [4]; double [] vegetation = new double [4]; double [] alpha = new double [4]; double [] alpha = new double [4]; for (int n = ai.getAndIncrement(); n < weights.length; n = ai.getAndIncrement()) { for (int n = ai.getAndIncrement(); n < y_vector.length; n = ai.getAndIncrement()) { // int nscene = data_source[n][0][0]; // int nscene = data_source[n][0][0]; // int indx = data_source[n][0][1]; // int indx = data_source[n][0][1]; double terrain = vector[data_source[n][0][2]]; double terrain = vector[data_source[n][0][2]]; Loading Loading @@ -563,6 +594,35 @@ public class VegetationLMA { }; }; } } ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads); // regularization weights and derivatives 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 + 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] } } } } }; } ImageDtt.startAndJoin(threads); return fX; return fX; } } Loading Loading @@ -624,7 +684,8 @@ public class VegetationLMA { public double [] parametersImage ( public double [] parametersImage ( double [] vector, double [] vector, int gap, int gap, int [] wh) { int [] wh, String title) { int [] indices = getParamDebugIndices (gap); int [] indices = getParamDebugIndices (gap); int woi_width3=woi.width*3 + 2 * gap; int woi_width3=woi.width*3 + 2 * gap; double [] dbg_img = new double [indices.length]; double [] dbg_img = new double [indices.length]; Loading @@ -633,18 +694,24 @@ public class VegetationLMA { dbg_img[i] = Double.NaN; dbg_img[i] = Double.NaN; } else { } else { dbg_img[i]= vector[indices[i]]; dbg_img[i]= vector[indices[i]]; // scale alpha for the same image int w = i % woi_width3; if (w > 2 *( woi.width+ gap)) { dbg_img[i] = debug_alpha_scales[0] + (debug_alpha_scales[1] - debug_alpha_scales[0]) * dbg_img[i]; } } } } } if (wh != null) { if (wh != null) { wh[0] = woi_width3; wh[0] = woi_width3; wh[1] = indices.length/woi_width3; wh[1] = indices.length/woi_width3; } } if (title != null) { ShowDoubleFloatArrays.showArrays( ShowDoubleFloatArrays.showArrays( dbg_img, dbg_img, woi_width3, woi_width3, indices.length/woi_width3, indices.length/woi_width3, "parameters.vector"); title); } return dbg_img; return dbg_img; } } Loading Loading @@ -683,9 +750,11 @@ public class VegetationLMA { } } private void setupWeights(final double [] scene_weights) { private void setupWeights( // after setupParametersIndices int extra_samples = 0; // in the future may be regularization final double [] scene_weights, double extra_weights = 0.0; final double reg_weights) { int extra_samples = num_pars_vegetation_alpha; // in the future may be more regularization double reg_sample_weight = reg_weights/num_pars_vegetation_alpha; // weight of each regularization sample final double [] sw = (scene_weights != null) ? scene_weights : new double [num_scenes]; final double [] sw = (scene_weights != null) ? scene_weights : new double [num_scenes]; if (scene_weights == null) { if (scene_weights == null) { Arrays.fill (sw, 1.0); Arrays.fill (sw, 1.0); Loading @@ -693,15 +762,17 @@ public class VegetationLMA { weights = new double [data_source.length + extra_samples]; weights = new double [data_source.length + extra_samples]; double s = 0; double s = 0; for (int ny = 0; ny < data_source.length; ny++) { for (int ny = 0; ny < data_source.length; ny++) { s += sw[data_source[ny][0][0]]; int nscene = data_source[ny][0][0]; // int indx = data_source[ny][0][1]; s += sw[nscene]; } } final double s0 = s; final double s0 = s; for (int i = 0; i < extra_samples; i++) { s *= (1+ reg_weights); s+=extra_weights; } final double k = 1.0/s; final double k = 1.0/s; weight_pure = s0/s; weight_pure = s0/s; // for (int i = 0; i < extra_samples; i++) { // s+=extra_weights; // } final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX); final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX); final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0); for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) { Loading @@ -711,7 +782,7 @@ public class VegetationLMA { if (nw < data_source.length) { if (nw < data_source.length) { weights[nw] = sw[data_source[nw][0][0]] * k; weights[nw] = sw[data_source[nw][0][0]] * k; } else { } else { weights[nw] = extra_weights * k; weights[nw] = reg_sample_weight; } } } } } } Loading Loading @@ -872,6 +943,7 @@ public class VegetationLMA { Arrays.fill(par_index[TVAO_VEGETATION], -1); Arrays.fill(par_index[TVAO_VEGETATION], -1); Arrays.fill(par_index[TVAO_VEGETATION_ALPHA], -1); Arrays.fill(par_index[TVAO_VEGETATION_ALPHA], -1); int par_num = 0; int par_num = 0; ind_pars_terrain = 0; for (int drow = 0; drow < woi.height; drow++) { for (int drow = 0; drow < woi.height; drow++) { int row = woi.y + drow; int row = woi.y + drow; for (int dcol = 0; dcol < woi.width; dcol++) { for (int dcol = 0; dcol < woi.width; dcol++) { Loading @@ -884,6 +956,7 @@ public class VegetationLMA { } } } } num_pars_terrain = par_num; num_pars_terrain = par_num; ind_pars_vegetation = par_num; for (int drow = 0; drow < woi.height; drow++) { for (int drow = 0; drow < woi.height; drow++) { int row = woi.y + drow; int row = woi.y + drow; for (int dcol = 0; dcol < woi.width; dcol++) { for (int dcol = 0; dcol < woi.width; dcol++) { Loading @@ -895,7 +968,8 @@ public class VegetationLMA { } } } } } } num_pars_vegetation = par_num - num_pars_terrain; ind_pars_vegetation_alpha = par_num; num_pars_vegetation = par_num - ind_pars_vegetation; for (int drow = 0; drow < woi.height; drow++) { for (int drow = 0; drow < woi.height; drow++) { int row = woi.y + drow; int row = woi.y + drow; for (int dcol = 0; dcol < woi.width; dcol++) { for (int dcol = 0; dcol < woi.width; dcol++) { Loading @@ -907,11 +981,13 @@ public class VegetationLMA { } } } } } } int num_pars_pixel = par_num; num_pars_vegetation_alpha = par_num - ind_pars_vegetation_alpha; // normally should be == num_pars_vegetation // int num_pars_pixel = par_num; ind_pars_scenes = par_num; for (int i = 0; i < par_index[TVAO_SCENE_OFFSET].length; i++) { for (int i = 0; i < par_index[TVAO_SCENE_OFFSET].length; i++) { par_index[TVAO_SCENE_OFFSET][i] = par_num++; par_index[TVAO_SCENE_OFFSET][i] = par_num++; } } num_pars_scenes = par_num - num_pars_pixel; num_pars_scenes = par_num - ind_pars_scenes; parameters_vector = new double [par_num]; parameters_vector = new double [par_num]; } } Loading
src/main/java/com/elphel/imagej/vegetation/VegetationModel.java +11 −1 Original line number Original line Diff line number Diff line Loading @@ -698,11 +698,18 @@ public class VegetationModel { int min_scenes = 10; int min_scenes = 10; double default_alpha = 0.8; double default_alpha = 0.8; double [] scene_weights = null; double [] scene_weights = null; double reg_weights = 0.25; // fraction of the total weight used for regularization double alpha_loss = 1.0; // quadratic loss when alpha reaches -1.0 or 2.0 double alpha_offset = 0.0; // if >0, start losses above 0.0 and below 1.0; int num_samples = vegetationLMA.prepareLMA( int num_samples = vegetationLMA.prepareLMA( woi50, // final Rectangle woi, woi50, // final Rectangle woi, min_scenes, // final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence min_scenes, // final int min_scenes, // minimal number of scenes (inside woi) vegetation pixel must influence default_alpha, // final double default_alpha, default_alpha, // final double default_alpha, scene_weights, // final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? scene_weights, // final double [] scene_weights, // null or per-scene weights (higher for larger offsets)? reg_weights, // final double reg_weights, // fraction of the total weight used for regularization alpha_loss, // final double alpha_loss, // quadratic loss when alpha reaches -1.0 or 2.0 alpha_offset, // final double alpha_offset, // quadratic loss when alpha reaches -1.0 or 2.0 debugLevel); // final int debugLevel); debugLevel); // final int debugLevel); double lambda = 0.1; double lambda = 0.1; Loading @@ -712,6 +719,9 @@ public class VegetationModel { boolean last_run = false; boolean last_run = false; double rms_diff = 0.0001; double rms_diff = 0.0001; int num_iter = 100; int num_iter = 100; vegetationLMA.debug_index = 0; vegetationLMA.debug_image = new double [num_iter][]; int lma_rslt= vegetationLMA.runLma( // <0 - failed, >=0 iteration number (1 - immediately) int lma_rslt= vegetationLMA.runLma( // <0 - failed, >=0 iteration number (1 - immediately) lambda, // double lambda, // 0.1 lambda, // double lambda, // 0.1 lambda_scale_good,// double lambda_scale_good,// 0.5 lambda_scale_good,// double lambda_scale_good,// 0.5 Loading