Loading src/main/java/com/elphel/imagej/orthomosaic/OrthoEqualizeLMA.java +126 −3 Original line number Diff line number Diff line Loading @@ -297,6 +297,129 @@ public class OrthoEqualizeLMA { return weights.length; } /** * Converting to use available_pairs[][] instead of indices[] - not yet used * @param clt_parameters * @param maps_collection * @param available_pairs * @param ignore_equalization * @param scale_weight * @param pull_weight * @param half_weight_sec * @param min_weight_sec * @param use_inv * @param overlap_pow * @param debugLevel * @return */ public int prepareLMA ( CLTParameters clt_parameters, OrthoMapsCollection maps_collection, int [][] available_pairs, // scale_weights applies both to pairs mismatch and per-scene values difference from neutral {1.0, 0.0} boolean ignore_equalization, // ignore previous equalization double scale_weight, // relative weight of scale differences compared to offset differences double pull_weight, // relative weight of offsets and scales differences from 1.0 to pairs mismatch double half_weight_sec, // 300 - time difference to reduce weight twice double min_weight_sec, // 0.01 weight of pairs at very different time boolean use_inv, // use inverse pairs double overlap_pow, // match weight as overlap fraction to this power int debugLevel) { int [] indices = maps_collection.getScenesFromPairs( // may be shorter, each element - absolute scene number used in pairs available_pairs, // pairs_defined_abs,// int [][] pairs, null); // int [] indices_in) // preselected indices or null int [][] defined_pairs = maps_collection.condensePairs (available_pairs, indices); // pairs_defined_abs,indices); this.indices = indices; num_scenes = indices.length; matches = new PairwiseOrthoMatch[indices.length][indices.length]; ArrayList<Point> pairs_list = new ArrayList<Point>(); for (int i = 0; i < num_scenes-1; i++) { int scene0 = indices[i]; for (int j = i+1; j < num_scenes; j++){ int scene1 = indices[j]; PairwiseOrthoMatch match = maps_collection.ortho_maps[scene0].getMatch(maps_collection.ortho_maps[scene1].getName()); PairwiseOrthoMatch inv_match = use_inv? maps_collection.ortho_maps[scene1].getMatch(maps_collection.ortho_maps[scene0].getName()):null; if ((match != null) || (inv_match != null)){ if (match == null) { double [] enuOffset = maps_collection.ortho_maps[scene0].enuOffsetTo(maps_collection.ortho_maps[scene1]); double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image match = inv_match.getInverse(rd); } if (inv_match == null) { double [] enuOffset = maps_collection.ortho_maps[scene1].enuOffsetTo(maps_collection.ortho_maps[scene0]); double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image inv_match = match.getInverse(rd); } } if ((match != null) && match.isSetEqualize2to1()) { matches[i][j] = match; matches[j][i] = inv_match; pairs_list.add(new Point(i,j)); // only once? } } } num_pairs = pairs_list.size(); pairs = new int[num_pairs][2]; for (int np = 0; np < num_pairs; np++) { Point pair = pairs_list.get(np); pairs[np] = new int[] {pair.x, pair.y}; } pairs_ni = OrthoMultiLMA.createNonIntersectingPairs(pairs); y_vector = new double [2*num_pairs + 2*num_scenes]; weights = new double [2*num_pairs + 2*num_scenes]; parameters_vector = new double [2*num_scenes]; int sec_24hrs = 60*60*24; double sw = 0; // pairwise matches for (int npair = 0; npair < num_pairs; npair++) { Point p = pairs_list.get(npair); PairwiseOrthoMatch match = matches[p.x][p.y]; y_vector[2*npair + 0] = match.equalize1to0[0]; y_vector[2*npair + 1] = match.equalize1to0[1]; double diff_seconds = Math.abs((int) ChronoUnit.SECONDS.between( maps_collection.ortho_maps[indices[p.x]].getLocalDateTime(), maps_collection.ortho_maps[indices[p.y]].getLocalDateTime() )) % sec_24hrs; if (diff_seconds > (sec_24hrs/2)) { diff_seconds = sec_24hrs-diff_seconds; } // weight reduction because of different capture time double weight_dt = Math.max(Math.pow(0.5, diff_seconds/half_weight_sec),min_weight_sec); // weight reduction because of partial overlap double weight_overlap = Math.pow(match.getOverlap(), overlap_pow); // scale_weight double w = weight_dt * weight_overlap; weights[2*npair + 0] = w * scale_weight; weights[2*npair + 1] = w; sw += w *(1 + scale_weight); } double swp = sw; // individual scene pulls to {1.0,0} for regularization for (int nscene = 0; nscene < num_scenes; nscene++) { double [] equalize = ignore_equalization? (new double[] {1.0,0.0}): maps_collection.ortho_maps[indices[nscene]].getEqualize(); int np = 2 * nscene; int indx = 2 * num_pairs + np; parameters_vector[np + 0] = equalize[0]; parameters_vector[np + 1] = equalize[1]; y_vector[indx + 0] = 1.0; y_vector[indx + 1] = 0.0; weights [indx + 0] = scale_weight * pull_weight; weights [indx + 1] = pull_weight; sw+= pull_weight * (1 + scale_weight); } pure_weight = swp/sw; double s = 1.0/sw; for (int i = 0; i <weights.length;i++) { weights[i] *=s; } last_jt = new double [parameters_vector.length][]; return weights.length; } public int runLma( // <0 - failed, >=0 iteration number (1 - immediately) double lambda, // 0.1 Loading src/main/java/com/elphel/imagej/orthomosaic/OrthoMultiLMA.java +1 −22 Original line number Diff line number Diff line Loading @@ -423,9 +423,6 @@ public class OrthoMultiLMA { CLTParameters clt_parameters, OrthoMapsCollection maps_collection, String orthoMapsCollection_path, /// boolean all_pairs, /// double min_overlap_frac, /// double max_rms, int [][] available_pairs, boolean move_only, boolean ignore_affines, Loading @@ -441,27 +438,9 @@ public class OrthoMultiLMA { int debugLevel) { double [] val_coord = null; // 1 - valid, 0 - invalid, minimize coordinates errors boolean corr_avg= (skew_pull > 0) || (tilt_pull > 0) || (scale_pull > 0); int [] indices = null; /* if (all_pairs) { } else { indices = maps_collection.getScenesSelection( null, // boolean select_all, " to build a map with LMA from pair-wise matches"); // String purpose) } int [][] pairs_defined_abs = maps_collection.filterPairs( // absolute indices indices, // int [] indices_in, min_overlap_frac, // double min_overlap_frac, max_rms, // double max_rmse, true, // boolean max_resolution, null); // int [][] remove_pairs */ indices= maps_collection.getScenesFromPairs( // may be shorter, each element - absolute scene number used in pairs int [] indices = maps_collection.getScenesFromPairs( // may be shorter, each element - absolute scene number used in pairs available_pairs, // pairs_defined_abs,// int [][] pairs, null); // int [] indices_in) // preselected indices or null int [][] defined_pairs = maps_collection.condensePairs (available_pairs, indices); // pairs_defined_abs,indices); OrthoMultiLMA oml = new OrthoMultiLMA( Loading Loading
src/main/java/com/elphel/imagej/orthomosaic/OrthoEqualizeLMA.java +126 −3 Original line number Diff line number Diff line Loading @@ -297,6 +297,129 @@ public class OrthoEqualizeLMA { return weights.length; } /** * Converting to use available_pairs[][] instead of indices[] - not yet used * @param clt_parameters * @param maps_collection * @param available_pairs * @param ignore_equalization * @param scale_weight * @param pull_weight * @param half_weight_sec * @param min_weight_sec * @param use_inv * @param overlap_pow * @param debugLevel * @return */ public int prepareLMA ( CLTParameters clt_parameters, OrthoMapsCollection maps_collection, int [][] available_pairs, // scale_weights applies both to pairs mismatch and per-scene values difference from neutral {1.0, 0.0} boolean ignore_equalization, // ignore previous equalization double scale_weight, // relative weight of scale differences compared to offset differences double pull_weight, // relative weight of offsets and scales differences from 1.0 to pairs mismatch double half_weight_sec, // 300 - time difference to reduce weight twice double min_weight_sec, // 0.01 weight of pairs at very different time boolean use_inv, // use inverse pairs double overlap_pow, // match weight as overlap fraction to this power int debugLevel) { int [] indices = maps_collection.getScenesFromPairs( // may be shorter, each element - absolute scene number used in pairs available_pairs, // pairs_defined_abs,// int [][] pairs, null); // int [] indices_in) // preselected indices or null int [][] defined_pairs = maps_collection.condensePairs (available_pairs, indices); // pairs_defined_abs,indices); this.indices = indices; num_scenes = indices.length; matches = new PairwiseOrthoMatch[indices.length][indices.length]; ArrayList<Point> pairs_list = new ArrayList<Point>(); for (int i = 0; i < num_scenes-1; i++) { int scene0 = indices[i]; for (int j = i+1; j < num_scenes; j++){ int scene1 = indices[j]; PairwiseOrthoMatch match = maps_collection.ortho_maps[scene0].getMatch(maps_collection.ortho_maps[scene1].getName()); PairwiseOrthoMatch inv_match = use_inv? maps_collection.ortho_maps[scene1].getMatch(maps_collection.ortho_maps[scene0].getName()):null; if ((match != null) || (inv_match != null)){ if (match == null) { double [] enuOffset = maps_collection.ortho_maps[scene0].enuOffsetTo(maps_collection.ortho_maps[scene1]); double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image match = inv_match.getInverse(rd); } if (inv_match == null) { double [] enuOffset = maps_collection.ortho_maps[scene1].enuOffsetTo(maps_collection.ortho_maps[scene0]); double [] rd = {enuOffset[0], -enuOffset[1]}; // {right,down} of the image inv_match = match.getInverse(rd); } } if ((match != null) && match.isSetEqualize2to1()) { matches[i][j] = match; matches[j][i] = inv_match; pairs_list.add(new Point(i,j)); // only once? } } } num_pairs = pairs_list.size(); pairs = new int[num_pairs][2]; for (int np = 0; np < num_pairs; np++) { Point pair = pairs_list.get(np); pairs[np] = new int[] {pair.x, pair.y}; } pairs_ni = OrthoMultiLMA.createNonIntersectingPairs(pairs); y_vector = new double [2*num_pairs + 2*num_scenes]; weights = new double [2*num_pairs + 2*num_scenes]; parameters_vector = new double [2*num_scenes]; int sec_24hrs = 60*60*24; double sw = 0; // pairwise matches for (int npair = 0; npair < num_pairs; npair++) { Point p = pairs_list.get(npair); PairwiseOrthoMatch match = matches[p.x][p.y]; y_vector[2*npair + 0] = match.equalize1to0[0]; y_vector[2*npair + 1] = match.equalize1to0[1]; double diff_seconds = Math.abs((int) ChronoUnit.SECONDS.between( maps_collection.ortho_maps[indices[p.x]].getLocalDateTime(), maps_collection.ortho_maps[indices[p.y]].getLocalDateTime() )) % sec_24hrs; if (diff_seconds > (sec_24hrs/2)) { diff_seconds = sec_24hrs-diff_seconds; } // weight reduction because of different capture time double weight_dt = Math.max(Math.pow(0.5, diff_seconds/half_weight_sec),min_weight_sec); // weight reduction because of partial overlap double weight_overlap = Math.pow(match.getOverlap(), overlap_pow); // scale_weight double w = weight_dt * weight_overlap; weights[2*npair + 0] = w * scale_weight; weights[2*npair + 1] = w; sw += w *(1 + scale_weight); } double swp = sw; // individual scene pulls to {1.0,0} for regularization for (int nscene = 0; nscene < num_scenes; nscene++) { double [] equalize = ignore_equalization? (new double[] {1.0,0.0}): maps_collection.ortho_maps[indices[nscene]].getEqualize(); int np = 2 * nscene; int indx = 2 * num_pairs + np; parameters_vector[np + 0] = equalize[0]; parameters_vector[np + 1] = equalize[1]; y_vector[indx + 0] = 1.0; y_vector[indx + 1] = 0.0; weights [indx + 0] = scale_weight * pull_weight; weights [indx + 1] = pull_weight; sw+= pull_weight * (1 + scale_weight); } pure_weight = swp/sw; double s = 1.0/sw; for (int i = 0; i <weights.length;i++) { weights[i] *=s; } last_jt = new double [parameters_vector.length][]; return weights.length; } public int runLma( // <0 - failed, >=0 iteration number (1 - immediately) double lambda, // 0.1 Loading
src/main/java/com/elphel/imagej/orthomosaic/OrthoMultiLMA.java +1 −22 Original line number Diff line number Diff line Loading @@ -423,9 +423,6 @@ public class OrthoMultiLMA { CLTParameters clt_parameters, OrthoMapsCollection maps_collection, String orthoMapsCollection_path, /// boolean all_pairs, /// double min_overlap_frac, /// double max_rms, int [][] available_pairs, boolean move_only, boolean ignore_affines, Loading @@ -441,27 +438,9 @@ public class OrthoMultiLMA { int debugLevel) { double [] val_coord = null; // 1 - valid, 0 - invalid, minimize coordinates errors boolean corr_avg= (skew_pull > 0) || (tilt_pull > 0) || (scale_pull > 0); int [] indices = null; /* if (all_pairs) { } else { indices = maps_collection.getScenesSelection( null, // boolean select_all, " to build a map with LMA from pair-wise matches"); // String purpose) } int [][] pairs_defined_abs = maps_collection.filterPairs( // absolute indices indices, // int [] indices_in, min_overlap_frac, // double min_overlap_frac, max_rms, // double max_rmse, true, // boolean max_resolution, null); // int [][] remove_pairs */ indices= maps_collection.getScenesFromPairs( // may be shorter, each element - absolute scene number used in pairs int [] indices = maps_collection.getScenesFromPairs( // may be shorter, each element - absolute scene number used in pairs available_pairs, // pairs_defined_abs,// int [][] pairs, null); // int [] indices_in) // preselected indices or null int [][] defined_pairs = maps_collection.condensePairs (available_pairs, indices); // pairs_defined_abs,indices); OrthoMultiLMA oml = new OrthoMultiLMA( Loading