Loading src/main/java/com/elphel/imagej/orthomosaic/ERSTiltLMA.java +74 −7 Original line number Original line Diff line number Diff line Loading @@ -54,10 +54,13 @@ public class ERSTiltLMA { private double [] last_ymfx = null; private double [] last_ymfx = null; private double [][] last_jt = null; private double [][] last_jt = null; public double [][][] aff_pairs_nosr = null; public double [][][] aff_pairs_inosr = null; // inverted pairs affines w/o scale and rotation public double [][][][] aff_tilts = null; public double [][][][] aff_tilts = null; public boolean invert_q2a = false; public boolean invert_q2a = false; // debug // debug public double [][][] aff_pairs = null; // pairwise image-based affines public double [][] diff_tilts = null; // pairwise differential tilts public boolean last3only = false; // true; // debug feature public boolean last3only = false; // true; // debug feature public double scale_pairs = 1e3; // 1e4; // increase fX and derivatives for pairs public double scale_pairs = 1e3; // 1e4; // increase fX and derivatives for pairs public double delta= 1e-7; public double delta= 1e-7; Loading Loading @@ -99,7 +102,16 @@ public class ERSTiltLMA { return svd; return svd; } } public void printResults(boolean degrees) { /** * Get differential tilts between the second and the first scenes in each pair * @return [pair]{tiltX,tiltY} */ public double [][] getDiffTilts(){ return diff_tilts; } public void printSceneResults(boolean degrees, boolean percents) { double [][] pseudo_xy = getPseudoXY(); double [][] pseudo_xy = getPseudoXY(); double [][][] ers_affines = getERSAffines(); double [][][] ers_affines = getERSAffines(); SingularValueDecomposition [] svd = getSVD(); SingularValueDecomposition [] svd = getSVD(); Loading @@ -116,8 +128,59 @@ public class ERSTiltLMA { } } return; return; } } public void printPairsResults(boolean degrees, boolean percents) { double sd = degrees? 180/Math.PI : 1.0; double sp = percents? 100 : 1; String svd_title = SingularValueDecomposition.titleString(degrees); double [] fx = getFxDerivs( parameters_vector, // double [] vector, null, // final double [][] jt, // should be null or initialized with [vector.length][] 0); // final int debug_level) String tab_title_rad = String.format( "%4s\t%4s\t%4s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%s", "#","scn0","scn1","tiltX","tiltY","tilt","tilt-dir","elevation","pair_\u0394w","residual",svd_title); String tab_title_deg = String.format( "%4s\t%4s\t%4s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%s", "#","scn0","scn1","tiltX","tiltY","tilt","tilt-dir\u00B0","elevation\u00B0","pair_\u0394w","residual",svd_title); String tab_title_rad_perc = String.format( "%4s\t%4s\t%4s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%s", "#","scn0","scn1","tiltX%","tiltY%","tilt%","tilt-dir","elevation","pair_\u0394w%","residual%",svd_title); String tab_title_deg_perc = String.format( "%4s\t%4s\t%4s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%s", "#","scn0","scn1","tiltX%","tiltY%","tilt%","tilt-dir\u00B0","elevation\u00B0","pair_\u0394w%","residual%",svd_title); String title =degrees ? (percents?tab_title_deg_perc:tab_title_deg) : (percents?tab_title_rad_perc:tab_title_rad); String fmt_rad= "%4d\t%4d\t%4d\t%11.8f\t%11.8f\t%11.8f\t%11.8f\t%11.8f\t%11.8f\t%11.8f\t%s"; String fmt_deg= "%4d\t%4d\t%4d\t%11.8f\t%11.8f\t%11.8f\t%11.6f\t%11.6f\t%11.8f\t%11.8f\t%s"; String fmt_rad_perc="%4d\t%4d\t%4d\t%11.6f%%\t%11.6f%%\t%11.6f%%\t%11.8f\t%11.8f\t%11.6f%%\t%11.6f%%\t%s"; String fmt_deg_perc="%4d\t%4d\t%4d\t%11.6f%%\t%11.6f%%\t%11.6f%%\t%11.6f\t%11.6f\t%11.6f%%\t%11.6f%%\t%s"; String fmt =degrees ? (percents?fmt_deg_perc:fmt_deg) : (percents?fmt_rad_perc:fmt_rad); System.out.println(title); double [] fit_err = new double [num_pairs]; for (int npair=0; npair < num_pairs; npair++) { int [] pscenes = {indices[cpairs[npair][0]], indices[cpairs[npair][1]]}; double [] dtilt_xy = diff_tilts[npair]; double dtilt = Math.sqrt(dtilt_xy[0]*dtilt_xy[0]+dtilt_xy[1]*dtilt_xy[1]); double tilt_dir = Math.atan2(dtilt_xy[1],dtilt_xy[0]); double tilt_ang = Math.atan(dtilt); double [][] aff_pair = aff_pairs[npair]; // image-based affine for a pair SingularValueDecomposition svd_aff_pair = SingularValueDecomposition.singularValueDecompose(aff_pair); // just to see - which is zeroed - beta or gamma? gamma changes, beta stays String ssvd = svd_aff_pair.toString(degrees, 1); double pair_dw = svd_aff_pair.getDW(); fit_err[npair] = fx[npair] / scale_pairs; // dW -> % System.out.println(String.format(fmt, npair, pscenes[0], pscenes[1], sp*dtilt_xy[0], sp*dtilt_xy[1], sp*dtilt, sd*tilt_dir, sd*tilt_ang, sp*pair_dw, sp*fit_err[npair], ssvd)); } return; } /* /* * Starting with tilts0 and tilt1 = tilt0+tilt_diff (differential * Starting with tilts0 and tilt1 = tilt0+tilt_diff (differential Loading Loading @@ -155,9 +218,13 @@ public class ERSTiltLMA { this.cpairs = cpairs; this.cpairs = cpairs; num_scenes = indices.length; num_scenes = indices.length; num_pairs = cpairs.length; num_pairs = cpairs.length; aff_pairs_nosr = new double [num_pairs][][]; aff_pairs = new double [num_pairs][][]; // preserving for stats, not used in processing diff_tilts= new double [num_pairs][]; aff_pairs_inosr = new double [num_pairs][][]; aff_tilts = new double [num_pairs][2][][]; aff_tilts = new double [num_pairs][2][][]; for (int npair = 0; npair < num_pairs; npair++) { for (int npair = 0; npair < num_pairs; npair++) { aff_pairs[npair] = affine_pairs[npair]; // preserving for stats diff_tilts[npair] = new double [] {tilts[npair][1][0]-tilts[npair][0][0],tilts[npair][1][1]-tilts[npair][0][1]}; double [][] affine_pair_nors = SingularValueDecomposition.removeTiltRotScale( double [][] affine_pair_nors = SingularValueDecomposition.removeTiltRotScale( affine_pairs[npair], // double [][] A, affine_pairs[npair], // double [][] A, false, // boolean removeTilt, false, // boolean removeTilt, Loading @@ -165,7 +232,7 @@ public class ERSTiltLMA { true, // boolean removeScale, true, // boolean removeScale, false, // boolean removeOffset, false, // boolean removeOffset, false); // boolean max_is_scale); false); // boolean max_is_scale); aff_pairs_nosr[npair] = QuatUtils.matInverse2x2(affine_pair_nors); // maybe reverse order and do not use inversion? aff_pairs_inosr[npair] = QuatUtils.matInverse2x2(affine_pair_nors); // maybe reverse order and do not use inversion? for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) { aff_tilts[npair][i] = QuatUtils.tiltToAffine( // convert tilts to affines as they will not be modified later aff_tilts[npair][i] = QuatUtils.tiltToAffine( // convert tilts to affines as they will not be modified later tilts[npair][i]); // double [] tilt, tilts[npair][i]); // double [] tilt, Loading Loading @@ -223,7 +290,7 @@ public class ERSTiltLMA { double [][][] aff_err = QuatUtils.pseudoAffineDiffAndDerivatives( //affineDiffAndDerivatives( double [][][] aff_err = QuatUtils.pseudoAffineDiffAndDerivatives( //affineDiffAndDerivatives( pseudo_xy, // double [][] txy, // [scene][direction] pseudo_xy, // double [][] txy, // [scene][direction] aff_tilts[npair], // double [][][] a_tilts, aff_tilts[npair], // double [][][] a_tilts, aff_pairs_nosr[npair], // double [][] iaff_pair, // affine pair inversed aff_pairs_inosr[npair], // double [][] iaff_pair, // affine pair inversed invert_q2a); // boolean invert_q2a) // invert result affines (to match "usual") invert_q2a); // boolean invert_q2a) // invert result affines (to match "usual") if (jt == null) { if (jt == null) { aff_err = new double [][][] {aff_err[0]}; // aff_err = new double [][][] {aff_err[0]}; // Loading @@ -248,7 +315,7 @@ public class ERSTiltLMA { for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { threads[ithread] = new Thread() { public void run() { public void run() { for (int nscene = ai.getAndIncrement(); nscene < num_pairs; nscene = ai.getAndIncrement()) { for (int nscene = ai.getAndIncrement(); nscene < num_scenes; nscene = ai.getAndIncrement()) { int pindx = num_pairs + 2*nscene; int pindx = num_pairs + 2*nscene; for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) { fX[pindx+j] = vector[2*nscene + j]; fX[pindx+j] = vector[2*nscene + j]; Loading src/main/java/com/elphel/imagej/orthomosaic/OrthoAltitudeMatch.java +7 −2 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,8 @@ public class OrthoAltitudeMatch { boolean test_quat0 = false; boolean test_quat0 = false; boolean test_quat2= false; // true; boolean test_quat2= false; // true; boolean use_degrees = true; boolean use_degrees = true; boolean use_percents = true; boolean debug_tilts = true; boolean debug_tilts = true; boolean invert_order= false; // print them boolean invert_order= false; // print them Loading Loading @@ -160,6 +162,7 @@ public class OrthoAltitudeMatch { int [] ipair = {indices[cpair[0]], indices[cpair[1]]}; int [] ipair = {indices[cpair[0]], indices[cpair[1]]}; if (updateStatus) { if (updateStatus) { IJ.showStatus("Processing pair "+npair+" of "+condensed_pairs.length+" "+ipair[0]+"->"+ipair[1]); IJ.showStatus("Processing pair "+npair+" of "+condensed_pairs.length+" "+ipair[0]+"->"+ipair[1]); IJ.showProgress(1.0*npair/condensed_pairs.length-1); } } PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[ipair[0]].getMatch(ortho_maps[ipair[1]].getName(), true); // ? PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[ipair[0]].getMatch(ortho_maps[ipair[1]].getName(), true); // ? if (pairwiseOrthoMatch == null) { if (pairwiseOrthoMatch == null) { Loading Loading @@ -914,7 +917,9 @@ public class OrthoAltitudeMatch { System.out.println("LMA -> "+lma_rslt); System.out.println("LMA -> "+lma_rslt); if (lma_rslt >= 0) { if (lma_rslt >= 0) { if (debugLevel > -3) { if (debugLevel > -3) { ersTiltLMA.printResults(use_degrees); ersTiltLMA.printSceneResults(use_degrees, use_percents); ersTiltLMA.printPairsResults(use_degrees, use_percents); } } } } System.out.println(); System.out.println(); Loading @@ -924,7 +929,7 @@ public class OrthoAltitudeMatch { QuatUtils.testPseudoAffineDiffAndDerivatives( QuatUtils.testPseudoAffineDiffAndDerivatives( pseudo_xy, // double [][] xy, // [scene][direction] pseudo_xy, // double [][] xy, // [scene][direction] ersTiltLMA.aff_tilts[npair], // double [][][] a_tilts, ersTiltLMA.aff_tilts[npair], // double [][][] a_tilts, ersTiltLMA.aff_pairs_nosr[npair], // double [][] iaff_pair, // affine pair inversed ersTiltLMA.aff_pairs_inosr[npair], // double [][] iaff_pair, // affine pair inversed invert_q2a); // boolean invert_q2a){ // invert result affines (to match "usual") invert_q2a); // boolean invert_q2a){ // invert result affines (to match "usual") System.out.println(); System.out.println(); } } Loading src/main/java/com/elphel/imagej/orthomosaic/OrthoMapsCollection.java +42 −3 Original line number Original line Diff line number Diff line Loading @@ -6567,6 +6567,9 @@ public class OrthoMapsCollection implements Serializable{ boolean flt_show_rms = true; // clt_parameters.imp.flt_show_rms; // true; boolean flt_show_rms = true; // clt_parameters.imp.flt_show_rms; // true; boolean flt_show_zoom = true; // clt_parameters.imp.flt_show_zoom; // true; boolean flt_show_zoom = true; // clt_parameters.imp.flt_show_zoom; // true; boolean flt_show_alt = true; // clt_parameters.imp.flt_show_alt; // true; boolean flt_show_alt = true; // clt_parameters.imp.flt_show_alt; // true; boolean flt_show_svd = true; boolean flt_show_degrees = true; boolean alt_overwrite = clt_parameters.imp.alt_overwrite; // false; // overwrite existing altitude match pairs boolean alt_overwrite = clt_parameters.imp.alt_overwrite; // false; // overwrite existing altitude match pairs boolean alt_pairwise = clt_parameters.imp.alt_pairwise; // false; // overwrite existing altitude match pairs boolean alt_pairwise = clt_parameters.imp.alt_pairwise; // false; // overwrite existing altitude match pairs Loading Loading @@ -6671,7 +6674,10 @@ public class OrthoMapsCollection implements Serializable{ flt_show_zoom, // boolean show_zoom, flt_show_zoom, // boolean show_zoom, flt_show_alt, // boolean show_alt, flt_show_alt, // boolean show_alt, use_tab, // boolean use_tab, use_tab, // boolean use_tab, null); // String extra_line) null, // String extra_line) flt_show_svd, // boolean show_svd, flt_show_degrees); // boolean use_degrees); { { System.out.println("Selected\t"+available_pairs.length+"\tscene pairs for matching"); System.out.println("Selected\t"+available_pairs.length+"\tscene pairs for matching"); if (use_tab) { if (use_tab) { Loading @@ -6682,6 +6688,10 @@ public class OrthoMapsCollection implements Serializable{ if (flt_show_zoom) System.out.print(String.format("\t%4s", "Zoom")); if (flt_show_zoom) System.out.print(String.format("\t%4s", "Zoom")); if (flt_show_alt) System.out.print(String.format("\t%7s\t%7s\t%7s", "tiltX","tiltY","offs")); if (flt_show_alt) System.out.print(String.format("\t%7s\t%7s\t%7s", "tiltX","tiltY","offs")); if (flt_show_sfm) System.out.print(String.format("\t%5s\t%5s", "SfM0","SfM1")); if (flt_show_sfm) System.out.print(String.format("\t%5s\t%5s", "SfM0","SfM1")); if (flt_show_svd) { String svd_title=SingularValueDecomposition.titleString(flt_show_degrees); System.out.print("\t"+ svd_title); } System.out.println(); System.out.println(); } } for (int i = 0; i < available_pairs.length; i++) { for (int i = 0; i < available_pairs.length; i++) { Loading Loading @@ -7535,6 +7545,30 @@ public class OrthoMapsCollection implements Serializable{ boolean show_alt, boolean show_alt, boolean use_tab, boolean use_tab, String extra_line) { String extra_line) { return textPairs ( plist, // int [][] plist, show_names, // boolean show_names, show_overlap, // boolean show_overlap, show_rms, // boolean show_rms, show_zoom, // boolean show_zoom, show_alt, // boolean show_alt, use_tab, // boolean use_tab, extra_line, // String extra_line, false, // boolean show_svd, false); // boolean use_degrees); } public String [] textPairs ( int [][] plist, boolean show_names, boolean show_overlap, boolean show_rms, boolean show_zoom, boolean show_alt, boolean use_tab, String extra_line, boolean show_svd, boolean use_degrees) { boolean show_sfm = show_alt; boolean show_sfm = show_alt; // TODO: show SfM of each scene // TODO: show SfM of each scene Loading Loading @@ -7563,6 +7597,11 @@ public class OrthoMapsCollection implements Serializable{ } } } } if (show_sfm) text_pairs[i] += String.format(use_tab?"\t%5.1f\t%5.1f":" S %5.1f %5.1f", sfm_gain[0],sfm_gain[1]); if (show_sfm) text_pairs[i] += String.format(use_tab?"\t%5.1f\t%5.1f":" S %5.1f %5.1f", sfm_gain[0],sfm_gain[1]); if (show_svd && use_tab && (pairwiseOrthoMatch.getAffine()!=null)) { // now only for tab SingularValueDecomposition svd = SingularValueDecomposition.singularValueDecompose(pairwiseOrthoMatch.getAffine()); String ssvd = svd.toString(use_degrees, 1); text_pairs[i] += "\t"+ssvd; } } } } } if (extra_line !=null) { if (extra_line !=null) { Loading src/main/java/com/elphel/imagej/orthomosaic/QuatUtils.java +36 −13 Original line number Original line Diff line number Diff line Loading @@ -1466,13 +1466,36 @@ q11 - q22 = c3 double [][][] a_tilts, double [][][] a_tilts, double [][] iaff_pair, // affine pair inversed double [][] iaff_pair, // affine pair inversed boolean invert_q2a){ // invert result affines (to match "usual") boolean invert_q2a){ // invert result affines (to match "usual") double delta= 1e-6; double delta= 1e-8; /* xy = new double [][] { xy = new double [][] { {xy[0][0]-0.1,xy[0][1]+0.1}, {xy[1][0]+0.1,xy[1][1]+0.1} }; a_tilts = new double[][][] { { {a_tilts[0][0][0], a_tilts[0][0][1]-0.01}, {a_tilts[0][1][0]-0.01,a_tilts[0][1][1]} }, { {a_tilts[1][0][0], a_tilts[1][0][1]-0.1}, {a_tilts[1][1][0]-0.1, a_tilts[1][1][1]} } }; iaff_pair = new double [][] { {iaff_pair[0][0], iaff_pair[0][1]+0.1}, {iaff_pair[1][0]+0.1,iaff_pair[1][1]} }; */ double [][] xy_m = new double [][] { {xy[0][0],xy[0][1]}, {xy[0][0],xy[0][1]}, {xy[1][0],xy[1][1]} {xy[1][0],xy[1][1]} }; }; a_tilts = new double[][][] { double [][][] a_tilts_m= new double[][][] { { { {a_tilts[0][0][0],a_tilts[0][0][1]}, {a_tilts[0][0][0],a_tilts[0][0][1]}, {a_tilts[0][1][0],a_tilts[0][1][1]} {a_tilts[0][1][0],a_tilts[0][1][1]} Loading @@ -1483,14 +1506,14 @@ q11 - q22 = c3 } } }; }; iaff_pair = new double [][] { double [][] iaff_pair_m = new double [][] { {iaff_pair[0][0],iaff_pair[0][1]}, {iaff_pair[0][0],iaff_pair[0][1]}, {iaff_pair[1][0],iaff_pair[1][1]} {iaff_pair[1][0],iaff_pair[1][1]} }; }; testPseudoAffineDiffAndDerivatives( testPseudoAffineDiffAndDerivatives( xy, // double [][] xy, // [scene][direction] xy_m, // double [][] xy, // [scene][direction] a_tilts, // double [][][] a_tilts, a_tilts_m, // double [][][] a_tilts, iaff_pair, // double [][] iaff_pair, // affine pair inversed iaff_pair_m, // double [][] iaff_pair, // affine pair inversed invert_q2a, // boolean invert_q2a, // invert result affines (to match "usual") invert_q2a, // boolean invert_q2a, // invert result affines (to match "usual") delta); // double delta); delta); // double delta); } } Loading Loading @@ -1544,11 +1567,11 @@ q11 - q22 = c3 System.out.println(String.format("%5s\t%20s\t%20s\t%20s\t%20s", System.out.println(String.format("%5s\t%20s\t%20s\t%20s\t%20s", "mode#", "dx0", "dy0", "dx1", "dy1")); "mode#", "dx0", "dy0", "dx1", "dy1")); System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", "deriv", s*dWdW[0], s*dWdW[1], s*dWdW[2], s*dWdW[3])); "deriv", s*dWdW[1], s*dWdW[2], s*dWdW[3], s*dWdW[4])); System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", "delta", s*dWdW_delta[0], s*dWdW_delta[1],s*dWdW_delta[2],s*dWdW_delta[3])); "delta", s*dWdW_delta[1], s*dWdW_delta[2],s*dWdW_delta[3],s*dWdW_delta[4])); System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", "diff", s*(dWdW_delta[0]-dWdW[0]), s*(dWdW_delta[1]-dWdW[1]), s*(dWdW_delta[2]-dWdW[2]), s*(dWdW_delta[3]-dWdW[3]))); "diff", s*(dWdW_delta[1]-dWdW[1]), s*(dWdW_delta[2]-dWdW[2]), s*(dWdW_delta[3]-dWdW[3]), s*(dWdW_delta[4]-dWdW[4]))); System.out.println ("Change xy[0][0] >= 1.0 to exit"); System.out.println ("Change xy[0][0] >= 1.0 to exit"); System.out.println (); System.out.println (); } } Loading src/main/java/com/elphel/imagej/orthomosaic/SingularValueDecomposition.java +11 −5 Original line number Original line Diff line number Diff line Loading @@ -49,6 +49,11 @@ public class SingularValueDecomposition { public double getMinScale() {return Math.min(w1,w2);} public double getMinScale() {return Math.min(w1,w2);} public double getMaxScale() {return Math.max(w1,w2);} public double getMaxScale() {return Math.max(w1,w2);} // Measure of tilt - difference between singular values (they both are assumed to be ~= 1.0) public double getDW() { return Math.abs(w1-w2); } public static String titleString(boolean degrees) { public static String titleString(boolean degrees) { SingularValueDecomposition svd= new SingularValueDecomposition(0,0,0,0,0); SingularValueDecomposition svd= new SingularValueDecomposition(0,0,0,0,0); return svd.toString(degrees, 2); return svd.toString(degrees, 2); Loading @@ -67,20 +72,21 @@ public class SingularValueDecomposition { //System.out.println("svd_affine_pair= ["+svd_affine_pair.scale+ ","+svd_affine_pair.getTiltAngle()+ ","+svd_affine_pair.gamma+ ","+svd_affine_pair.rot+ //System.out.println("svd_affine_pair= ["+svd_affine_pair.scale+ ","+svd_affine_pair.getTiltAngle()+ ","+svd_affine_pair.gamma+ ","+svd_affine_pair.rot+ // "] tilt="+(svd_affine_pair.getTiltAngle()*180/Math.PI)+ "\u00B0, dir="+(svd_affine_pair.gamma*180/Math.PI)+"\u00B0"); // "] tilt="+(svd_affine_pair.getTiltAngle()*180/Math.PI)+ "\u00B0, dir="+(svd_affine_pair.gamma*180/Math.PI)+"\u00B0"); String tab_title_rad = String.format("%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s", String tab_title_rad = String.format("%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s", "scale","tilt","gamma","beta","rot", "w1", "w2", "ratio"); "scale","tilt","gamma","beta","rot", "w1", "w2", "\u0394w"); // ratio"); String tab_title_deg = String.format("%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s", String tab_title_deg = String.format("%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s", "scale","tilt\u00B0","gamma\u00B0","beta\u00B0","rot\u00B0", "w1", "w2", "ratio"); "scale","tilt\u00B0","gamma\u00B0","beta\u00B0","rot\u00B0", "w1", "w2", "\u0394w"); // ratio"); String tab_fmt_rad = "%10.8f\t%10.7f\t%10.7f\t%10.7f\t%10.7f\t%10.8f\t%10.8f\t%10.8f"; String tab_fmt_rad = "%10.8f\t%10.7f\t%10.7f\t%10.7f\t%10.7f\t%10.8f\t%10.8f\t%10.8f"; String tab_fmt_deg = "%10.8f\t%10.5f\t%10.5f\t%10.5f\t%10.5f\t%10.8f\t%10.8f\t%10.8f"; String tab_fmt_deg = "%10.8f\t%10.5f\t%10.5f\t%10.5f\t%10.5f\t%10.8f\t%10.8f\t%10.8f"; String fmt_rad = " scale=%10.8f,tilt= %10.7f, gamma=%10.7f, beta=%10.7f, rot=%10.7f, w1=%10.8f, w2=%10.8f, ratio=%10.8f"; String fmt_rad = " scale=%10.8f,tilt= %10.7f, gamma=%10.7f, beta=%10.7f, rot=%10.7f, w1=%10.8f, w2=%10.8f, \u0394w=%10.8f"; // ratio=%10.8f"; String fmt_deg = " scale=%10.8f,tilt= %10.5f\u00B0, gamma=%10.5f\u00B0, beta=%10.5f\u00B0, rot=%10.5f\u00B0, w1=%10.8f, w2=%10.8f, ratio=%10.8f"; String fmt_deg = " scale=%10.8f,tilt= %10.5f\u00B0, gamma=%10.5f\u00B0, beta=%10.5f\u00B0, rot=%10.5f\u00B0, w1=%10.8f, w2=%10.8f, \u0394w=%10.8f"; // ratio=%10.8f\"; if (tab_mode==2) { if (tab_mode==2) { return degrees?tab_title_deg:tab_title_rad; return degrees?tab_title_deg:tab_title_rad; } } String fmt = (tab_mode==1)?(degrees ? tab_fmt_deg : tab_fmt_rad):(degrees ? fmt_deg : fmt_rad); String fmt = (tab_mode==1)?(degrees ? tab_fmt_deg : tab_fmt_rad):(degrees ? fmt_deg : fmt_rad); double s = degrees ? (180/Math.PI):1; double s = degrees ? (180/Math.PI):1; // String fmt=degrees ? fmt_deg : fmt_rad; // String fmt=degrees ? fmt_deg : fmt_rad; return String.format(fmt, scale, s*getTiltAngle(), s*gamma, s*beta, s*rot, w1, w2, ratio); // return String.format(fmt, scale, s*getTiltAngle(), s*gamma, s*beta, s*rot, w1, w2, ratio); return String.format(fmt, scale, s*getTiltAngle(), s*gamma, s*beta, s*rot, w1, w2, Math.abs(w1-w2)); } } Loading Loading
src/main/java/com/elphel/imagej/orthomosaic/ERSTiltLMA.java +74 −7 Original line number Original line Diff line number Diff line Loading @@ -54,10 +54,13 @@ public class ERSTiltLMA { private double [] last_ymfx = null; private double [] last_ymfx = null; private double [][] last_jt = null; private double [][] last_jt = null; public double [][][] aff_pairs_nosr = null; public double [][][] aff_pairs_inosr = null; // inverted pairs affines w/o scale and rotation public double [][][][] aff_tilts = null; public double [][][][] aff_tilts = null; public boolean invert_q2a = false; public boolean invert_q2a = false; // debug // debug public double [][][] aff_pairs = null; // pairwise image-based affines public double [][] diff_tilts = null; // pairwise differential tilts public boolean last3only = false; // true; // debug feature public boolean last3only = false; // true; // debug feature public double scale_pairs = 1e3; // 1e4; // increase fX and derivatives for pairs public double scale_pairs = 1e3; // 1e4; // increase fX and derivatives for pairs public double delta= 1e-7; public double delta= 1e-7; Loading Loading @@ -99,7 +102,16 @@ public class ERSTiltLMA { return svd; return svd; } } public void printResults(boolean degrees) { /** * Get differential tilts between the second and the first scenes in each pair * @return [pair]{tiltX,tiltY} */ public double [][] getDiffTilts(){ return diff_tilts; } public void printSceneResults(boolean degrees, boolean percents) { double [][] pseudo_xy = getPseudoXY(); double [][] pseudo_xy = getPseudoXY(); double [][][] ers_affines = getERSAffines(); double [][][] ers_affines = getERSAffines(); SingularValueDecomposition [] svd = getSVD(); SingularValueDecomposition [] svd = getSVD(); Loading @@ -116,8 +128,59 @@ public class ERSTiltLMA { } } return; return; } } public void printPairsResults(boolean degrees, boolean percents) { double sd = degrees? 180/Math.PI : 1.0; double sp = percents? 100 : 1; String svd_title = SingularValueDecomposition.titleString(degrees); double [] fx = getFxDerivs( parameters_vector, // double [] vector, null, // final double [][] jt, // should be null or initialized with [vector.length][] 0); // final int debug_level) String tab_title_rad = String.format( "%4s\t%4s\t%4s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%s", "#","scn0","scn1","tiltX","tiltY","tilt","tilt-dir","elevation","pair_\u0394w","residual",svd_title); String tab_title_deg = String.format( "%4s\t%4s\t%4s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%s", "#","scn0","scn1","tiltX","tiltY","tilt","tilt-dir\u00B0","elevation\u00B0","pair_\u0394w","residual",svd_title); String tab_title_rad_perc = String.format( "%4s\t%4s\t%4s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%s", "#","scn0","scn1","tiltX%","tiltY%","tilt%","tilt-dir","elevation","pair_\u0394w%","residual%",svd_title); String tab_title_deg_perc = String.format( "%4s\t%4s\t%4s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%11s\t%s", "#","scn0","scn1","tiltX%","tiltY%","tilt%","tilt-dir\u00B0","elevation\u00B0","pair_\u0394w%","residual%",svd_title); String title =degrees ? (percents?tab_title_deg_perc:tab_title_deg) : (percents?tab_title_rad_perc:tab_title_rad); String fmt_rad= "%4d\t%4d\t%4d\t%11.8f\t%11.8f\t%11.8f\t%11.8f\t%11.8f\t%11.8f\t%11.8f\t%s"; String fmt_deg= "%4d\t%4d\t%4d\t%11.8f\t%11.8f\t%11.8f\t%11.6f\t%11.6f\t%11.8f\t%11.8f\t%s"; String fmt_rad_perc="%4d\t%4d\t%4d\t%11.6f%%\t%11.6f%%\t%11.6f%%\t%11.8f\t%11.8f\t%11.6f%%\t%11.6f%%\t%s"; String fmt_deg_perc="%4d\t%4d\t%4d\t%11.6f%%\t%11.6f%%\t%11.6f%%\t%11.6f\t%11.6f\t%11.6f%%\t%11.6f%%\t%s"; String fmt =degrees ? (percents?fmt_deg_perc:fmt_deg) : (percents?fmt_rad_perc:fmt_rad); System.out.println(title); double [] fit_err = new double [num_pairs]; for (int npair=0; npair < num_pairs; npair++) { int [] pscenes = {indices[cpairs[npair][0]], indices[cpairs[npair][1]]}; double [] dtilt_xy = diff_tilts[npair]; double dtilt = Math.sqrt(dtilt_xy[0]*dtilt_xy[0]+dtilt_xy[1]*dtilt_xy[1]); double tilt_dir = Math.atan2(dtilt_xy[1],dtilt_xy[0]); double tilt_ang = Math.atan(dtilt); double [][] aff_pair = aff_pairs[npair]; // image-based affine for a pair SingularValueDecomposition svd_aff_pair = SingularValueDecomposition.singularValueDecompose(aff_pair); // just to see - which is zeroed - beta or gamma? gamma changes, beta stays String ssvd = svd_aff_pair.toString(degrees, 1); double pair_dw = svd_aff_pair.getDW(); fit_err[npair] = fx[npair] / scale_pairs; // dW -> % System.out.println(String.format(fmt, npair, pscenes[0], pscenes[1], sp*dtilt_xy[0], sp*dtilt_xy[1], sp*dtilt, sd*tilt_dir, sd*tilt_ang, sp*pair_dw, sp*fit_err[npair], ssvd)); } return; } /* /* * Starting with tilts0 and tilt1 = tilt0+tilt_diff (differential * Starting with tilts0 and tilt1 = tilt0+tilt_diff (differential Loading Loading @@ -155,9 +218,13 @@ public class ERSTiltLMA { this.cpairs = cpairs; this.cpairs = cpairs; num_scenes = indices.length; num_scenes = indices.length; num_pairs = cpairs.length; num_pairs = cpairs.length; aff_pairs_nosr = new double [num_pairs][][]; aff_pairs = new double [num_pairs][][]; // preserving for stats, not used in processing diff_tilts= new double [num_pairs][]; aff_pairs_inosr = new double [num_pairs][][]; aff_tilts = new double [num_pairs][2][][]; aff_tilts = new double [num_pairs][2][][]; for (int npair = 0; npair < num_pairs; npair++) { for (int npair = 0; npair < num_pairs; npair++) { aff_pairs[npair] = affine_pairs[npair]; // preserving for stats diff_tilts[npair] = new double [] {tilts[npair][1][0]-tilts[npair][0][0],tilts[npair][1][1]-tilts[npair][0][1]}; double [][] affine_pair_nors = SingularValueDecomposition.removeTiltRotScale( double [][] affine_pair_nors = SingularValueDecomposition.removeTiltRotScale( affine_pairs[npair], // double [][] A, affine_pairs[npair], // double [][] A, false, // boolean removeTilt, false, // boolean removeTilt, Loading @@ -165,7 +232,7 @@ public class ERSTiltLMA { true, // boolean removeScale, true, // boolean removeScale, false, // boolean removeOffset, false, // boolean removeOffset, false); // boolean max_is_scale); false); // boolean max_is_scale); aff_pairs_nosr[npair] = QuatUtils.matInverse2x2(affine_pair_nors); // maybe reverse order and do not use inversion? aff_pairs_inosr[npair] = QuatUtils.matInverse2x2(affine_pair_nors); // maybe reverse order and do not use inversion? for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) { aff_tilts[npair][i] = QuatUtils.tiltToAffine( // convert tilts to affines as they will not be modified later aff_tilts[npair][i] = QuatUtils.tiltToAffine( // convert tilts to affines as they will not be modified later tilts[npair][i]); // double [] tilt, tilts[npair][i]); // double [] tilt, Loading Loading @@ -223,7 +290,7 @@ public class ERSTiltLMA { double [][][] aff_err = QuatUtils.pseudoAffineDiffAndDerivatives( //affineDiffAndDerivatives( double [][][] aff_err = QuatUtils.pseudoAffineDiffAndDerivatives( //affineDiffAndDerivatives( pseudo_xy, // double [][] txy, // [scene][direction] pseudo_xy, // double [][] txy, // [scene][direction] aff_tilts[npair], // double [][][] a_tilts, aff_tilts[npair], // double [][][] a_tilts, aff_pairs_nosr[npair], // double [][] iaff_pair, // affine pair inversed aff_pairs_inosr[npair], // double [][] iaff_pair, // affine pair inversed invert_q2a); // boolean invert_q2a) // invert result affines (to match "usual") invert_q2a); // boolean invert_q2a) // invert result affines (to match "usual") if (jt == null) { if (jt == null) { aff_err = new double [][][] {aff_err[0]}; // aff_err = new double [][][] {aff_err[0]}; // Loading @@ -248,7 +315,7 @@ public class ERSTiltLMA { for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) { threads[ithread] = new Thread() { threads[ithread] = new Thread() { public void run() { public void run() { for (int nscene = ai.getAndIncrement(); nscene < num_pairs; nscene = ai.getAndIncrement()) { for (int nscene = ai.getAndIncrement(); nscene < num_scenes; nscene = ai.getAndIncrement()) { int pindx = num_pairs + 2*nscene; int pindx = num_pairs + 2*nscene; for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) { fX[pindx+j] = vector[2*nscene + j]; fX[pindx+j] = vector[2*nscene + j]; Loading
src/main/java/com/elphel/imagej/orthomosaic/OrthoAltitudeMatch.java +7 −2 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,8 @@ public class OrthoAltitudeMatch { boolean test_quat0 = false; boolean test_quat0 = false; boolean test_quat2= false; // true; boolean test_quat2= false; // true; boolean use_degrees = true; boolean use_degrees = true; boolean use_percents = true; boolean debug_tilts = true; boolean debug_tilts = true; boolean invert_order= false; // print them boolean invert_order= false; // print them Loading Loading @@ -160,6 +162,7 @@ public class OrthoAltitudeMatch { int [] ipair = {indices[cpair[0]], indices[cpair[1]]}; int [] ipair = {indices[cpair[0]], indices[cpair[1]]}; if (updateStatus) { if (updateStatus) { IJ.showStatus("Processing pair "+npair+" of "+condensed_pairs.length+" "+ipair[0]+"->"+ipair[1]); IJ.showStatus("Processing pair "+npair+" of "+condensed_pairs.length+" "+ipair[0]+"->"+ipair[1]); IJ.showProgress(1.0*npair/condensed_pairs.length-1); } } PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[ipair[0]].getMatch(ortho_maps[ipair[1]].getName(), true); // ? PairwiseOrthoMatch pairwiseOrthoMatch = ortho_maps[ipair[0]].getMatch(ortho_maps[ipair[1]].getName(), true); // ? if (pairwiseOrthoMatch == null) { if (pairwiseOrthoMatch == null) { Loading Loading @@ -914,7 +917,9 @@ public class OrthoAltitudeMatch { System.out.println("LMA -> "+lma_rslt); System.out.println("LMA -> "+lma_rslt); if (lma_rslt >= 0) { if (lma_rslt >= 0) { if (debugLevel > -3) { if (debugLevel > -3) { ersTiltLMA.printResults(use_degrees); ersTiltLMA.printSceneResults(use_degrees, use_percents); ersTiltLMA.printPairsResults(use_degrees, use_percents); } } } } System.out.println(); System.out.println(); Loading @@ -924,7 +929,7 @@ public class OrthoAltitudeMatch { QuatUtils.testPseudoAffineDiffAndDerivatives( QuatUtils.testPseudoAffineDiffAndDerivatives( pseudo_xy, // double [][] xy, // [scene][direction] pseudo_xy, // double [][] xy, // [scene][direction] ersTiltLMA.aff_tilts[npair], // double [][][] a_tilts, ersTiltLMA.aff_tilts[npair], // double [][][] a_tilts, ersTiltLMA.aff_pairs_nosr[npair], // double [][] iaff_pair, // affine pair inversed ersTiltLMA.aff_pairs_inosr[npair], // double [][] iaff_pair, // affine pair inversed invert_q2a); // boolean invert_q2a){ // invert result affines (to match "usual") invert_q2a); // boolean invert_q2a){ // invert result affines (to match "usual") System.out.println(); System.out.println(); } } Loading
src/main/java/com/elphel/imagej/orthomosaic/OrthoMapsCollection.java +42 −3 Original line number Original line Diff line number Diff line Loading @@ -6567,6 +6567,9 @@ public class OrthoMapsCollection implements Serializable{ boolean flt_show_rms = true; // clt_parameters.imp.flt_show_rms; // true; boolean flt_show_rms = true; // clt_parameters.imp.flt_show_rms; // true; boolean flt_show_zoom = true; // clt_parameters.imp.flt_show_zoom; // true; boolean flt_show_zoom = true; // clt_parameters.imp.flt_show_zoom; // true; boolean flt_show_alt = true; // clt_parameters.imp.flt_show_alt; // true; boolean flt_show_alt = true; // clt_parameters.imp.flt_show_alt; // true; boolean flt_show_svd = true; boolean flt_show_degrees = true; boolean alt_overwrite = clt_parameters.imp.alt_overwrite; // false; // overwrite existing altitude match pairs boolean alt_overwrite = clt_parameters.imp.alt_overwrite; // false; // overwrite existing altitude match pairs boolean alt_pairwise = clt_parameters.imp.alt_pairwise; // false; // overwrite existing altitude match pairs boolean alt_pairwise = clt_parameters.imp.alt_pairwise; // false; // overwrite existing altitude match pairs Loading Loading @@ -6671,7 +6674,10 @@ public class OrthoMapsCollection implements Serializable{ flt_show_zoom, // boolean show_zoom, flt_show_zoom, // boolean show_zoom, flt_show_alt, // boolean show_alt, flt_show_alt, // boolean show_alt, use_tab, // boolean use_tab, use_tab, // boolean use_tab, null); // String extra_line) null, // String extra_line) flt_show_svd, // boolean show_svd, flt_show_degrees); // boolean use_degrees); { { System.out.println("Selected\t"+available_pairs.length+"\tscene pairs for matching"); System.out.println("Selected\t"+available_pairs.length+"\tscene pairs for matching"); if (use_tab) { if (use_tab) { Loading @@ -6682,6 +6688,10 @@ public class OrthoMapsCollection implements Serializable{ if (flt_show_zoom) System.out.print(String.format("\t%4s", "Zoom")); if (flt_show_zoom) System.out.print(String.format("\t%4s", "Zoom")); if (flt_show_alt) System.out.print(String.format("\t%7s\t%7s\t%7s", "tiltX","tiltY","offs")); if (flt_show_alt) System.out.print(String.format("\t%7s\t%7s\t%7s", "tiltX","tiltY","offs")); if (flt_show_sfm) System.out.print(String.format("\t%5s\t%5s", "SfM0","SfM1")); if (flt_show_sfm) System.out.print(String.format("\t%5s\t%5s", "SfM0","SfM1")); if (flt_show_svd) { String svd_title=SingularValueDecomposition.titleString(flt_show_degrees); System.out.print("\t"+ svd_title); } System.out.println(); System.out.println(); } } for (int i = 0; i < available_pairs.length; i++) { for (int i = 0; i < available_pairs.length; i++) { Loading Loading @@ -7535,6 +7545,30 @@ public class OrthoMapsCollection implements Serializable{ boolean show_alt, boolean show_alt, boolean use_tab, boolean use_tab, String extra_line) { String extra_line) { return textPairs ( plist, // int [][] plist, show_names, // boolean show_names, show_overlap, // boolean show_overlap, show_rms, // boolean show_rms, show_zoom, // boolean show_zoom, show_alt, // boolean show_alt, use_tab, // boolean use_tab, extra_line, // String extra_line, false, // boolean show_svd, false); // boolean use_degrees); } public String [] textPairs ( int [][] plist, boolean show_names, boolean show_overlap, boolean show_rms, boolean show_zoom, boolean show_alt, boolean use_tab, String extra_line, boolean show_svd, boolean use_degrees) { boolean show_sfm = show_alt; boolean show_sfm = show_alt; // TODO: show SfM of each scene // TODO: show SfM of each scene Loading Loading @@ -7563,6 +7597,11 @@ public class OrthoMapsCollection implements Serializable{ } } } } if (show_sfm) text_pairs[i] += String.format(use_tab?"\t%5.1f\t%5.1f":" S %5.1f %5.1f", sfm_gain[0],sfm_gain[1]); if (show_sfm) text_pairs[i] += String.format(use_tab?"\t%5.1f\t%5.1f":" S %5.1f %5.1f", sfm_gain[0],sfm_gain[1]); if (show_svd && use_tab && (pairwiseOrthoMatch.getAffine()!=null)) { // now only for tab SingularValueDecomposition svd = SingularValueDecomposition.singularValueDecompose(pairwiseOrthoMatch.getAffine()); String ssvd = svd.toString(use_degrees, 1); text_pairs[i] += "\t"+ssvd; } } } } } if (extra_line !=null) { if (extra_line !=null) { Loading
src/main/java/com/elphel/imagej/orthomosaic/QuatUtils.java +36 −13 Original line number Original line Diff line number Diff line Loading @@ -1466,13 +1466,36 @@ q11 - q22 = c3 double [][][] a_tilts, double [][][] a_tilts, double [][] iaff_pair, // affine pair inversed double [][] iaff_pair, // affine pair inversed boolean invert_q2a){ // invert result affines (to match "usual") boolean invert_q2a){ // invert result affines (to match "usual") double delta= 1e-6; double delta= 1e-8; /* xy = new double [][] { xy = new double [][] { {xy[0][0]-0.1,xy[0][1]+0.1}, {xy[1][0]+0.1,xy[1][1]+0.1} }; a_tilts = new double[][][] { { {a_tilts[0][0][0], a_tilts[0][0][1]-0.01}, {a_tilts[0][1][0]-0.01,a_tilts[0][1][1]} }, { {a_tilts[1][0][0], a_tilts[1][0][1]-0.1}, {a_tilts[1][1][0]-0.1, a_tilts[1][1][1]} } }; iaff_pair = new double [][] { {iaff_pair[0][0], iaff_pair[0][1]+0.1}, {iaff_pair[1][0]+0.1,iaff_pair[1][1]} }; */ double [][] xy_m = new double [][] { {xy[0][0],xy[0][1]}, {xy[0][0],xy[0][1]}, {xy[1][0],xy[1][1]} {xy[1][0],xy[1][1]} }; }; a_tilts = new double[][][] { double [][][] a_tilts_m= new double[][][] { { { {a_tilts[0][0][0],a_tilts[0][0][1]}, {a_tilts[0][0][0],a_tilts[0][0][1]}, {a_tilts[0][1][0],a_tilts[0][1][1]} {a_tilts[0][1][0],a_tilts[0][1][1]} Loading @@ -1483,14 +1506,14 @@ q11 - q22 = c3 } } }; }; iaff_pair = new double [][] { double [][] iaff_pair_m = new double [][] { {iaff_pair[0][0],iaff_pair[0][1]}, {iaff_pair[0][0],iaff_pair[0][1]}, {iaff_pair[1][0],iaff_pair[1][1]} {iaff_pair[1][0],iaff_pair[1][1]} }; }; testPseudoAffineDiffAndDerivatives( testPseudoAffineDiffAndDerivatives( xy, // double [][] xy, // [scene][direction] xy_m, // double [][] xy, // [scene][direction] a_tilts, // double [][][] a_tilts, a_tilts_m, // double [][][] a_tilts, iaff_pair, // double [][] iaff_pair, // affine pair inversed iaff_pair_m, // double [][] iaff_pair, // affine pair inversed invert_q2a, // boolean invert_q2a, // invert result affines (to match "usual") invert_q2a, // boolean invert_q2a, // invert result affines (to match "usual") delta); // double delta); delta); // double delta); } } Loading Loading @@ -1544,11 +1567,11 @@ q11 - q22 = c3 System.out.println(String.format("%5s\t%20s\t%20s\t%20s\t%20s", System.out.println(String.format("%5s\t%20s\t%20s\t%20s\t%20s", "mode#", "dx0", "dy0", "dx1", "dy1")); "mode#", "dx0", "dy0", "dx1", "dy1")); System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", "deriv", s*dWdW[0], s*dWdW[1], s*dWdW[2], s*dWdW[3])); "deriv", s*dWdW[1], s*dWdW[2], s*dWdW[3], s*dWdW[4])); System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", "delta", s*dWdW_delta[0], s*dWdW_delta[1],s*dWdW_delta[2],s*dWdW_delta[3])); "delta", s*dWdW_delta[1], s*dWdW_delta[2],s*dWdW_delta[3],s*dWdW_delta[4])); System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", System.out.println(String.format("%5s\t%20.12f\t%20.12f\t%20.12f\t%20.12f", "diff", s*(dWdW_delta[0]-dWdW[0]), s*(dWdW_delta[1]-dWdW[1]), s*(dWdW_delta[2]-dWdW[2]), s*(dWdW_delta[3]-dWdW[3]))); "diff", s*(dWdW_delta[1]-dWdW[1]), s*(dWdW_delta[2]-dWdW[2]), s*(dWdW_delta[3]-dWdW[3]), s*(dWdW_delta[4]-dWdW[4]))); System.out.println ("Change xy[0][0] >= 1.0 to exit"); System.out.println ("Change xy[0][0] >= 1.0 to exit"); System.out.println (); System.out.println (); } } Loading
src/main/java/com/elphel/imagej/orthomosaic/SingularValueDecomposition.java +11 −5 Original line number Original line Diff line number Diff line Loading @@ -49,6 +49,11 @@ public class SingularValueDecomposition { public double getMinScale() {return Math.min(w1,w2);} public double getMinScale() {return Math.min(w1,w2);} public double getMaxScale() {return Math.max(w1,w2);} public double getMaxScale() {return Math.max(w1,w2);} // Measure of tilt - difference between singular values (they both are assumed to be ~= 1.0) public double getDW() { return Math.abs(w1-w2); } public static String titleString(boolean degrees) { public static String titleString(boolean degrees) { SingularValueDecomposition svd= new SingularValueDecomposition(0,0,0,0,0); SingularValueDecomposition svd= new SingularValueDecomposition(0,0,0,0,0); return svd.toString(degrees, 2); return svd.toString(degrees, 2); Loading @@ -67,20 +72,21 @@ public class SingularValueDecomposition { //System.out.println("svd_affine_pair= ["+svd_affine_pair.scale+ ","+svd_affine_pair.getTiltAngle()+ ","+svd_affine_pair.gamma+ ","+svd_affine_pair.rot+ //System.out.println("svd_affine_pair= ["+svd_affine_pair.scale+ ","+svd_affine_pair.getTiltAngle()+ ","+svd_affine_pair.gamma+ ","+svd_affine_pair.rot+ // "] tilt="+(svd_affine_pair.getTiltAngle()*180/Math.PI)+ "\u00B0, dir="+(svd_affine_pair.gamma*180/Math.PI)+"\u00B0"); // "] tilt="+(svd_affine_pair.getTiltAngle()*180/Math.PI)+ "\u00B0, dir="+(svd_affine_pair.gamma*180/Math.PI)+"\u00B0"); String tab_title_rad = String.format("%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s", String tab_title_rad = String.format("%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s", "scale","tilt","gamma","beta","rot", "w1", "w2", "ratio"); "scale","tilt","gamma","beta","rot", "w1", "w2", "\u0394w"); // ratio"); String tab_title_deg = String.format("%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s", String tab_title_deg = String.format("%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s", "scale","tilt\u00B0","gamma\u00B0","beta\u00B0","rot\u00B0", "w1", "w2", "ratio"); "scale","tilt\u00B0","gamma\u00B0","beta\u00B0","rot\u00B0", "w1", "w2", "\u0394w"); // ratio"); String tab_fmt_rad = "%10.8f\t%10.7f\t%10.7f\t%10.7f\t%10.7f\t%10.8f\t%10.8f\t%10.8f"; String tab_fmt_rad = "%10.8f\t%10.7f\t%10.7f\t%10.7f\t%10.7f\t%10.8f\t%10.8f\t%10.8f"; String tab_fmt_deg = "%10.8f\t%10.5f\t%10.5f\t%10.5f\t%10.5f\t%10.8f\t%10.8f\t%10.8f"; String tab_fmt_deg = "%10.8f\t%10.5f\t%10.5f\t%10.5f\t%10.5f\t%10.8f\t%10.8f\t%10.8f"; String fmt_rad = " scale=%10.8f,tilt= %10.7f, gamma=%10.7f, beta=%10.7f, rot=%10.7f, w1=%10.8f, w2=%10.8f, ratio=%10.8f"; String fmt_rad = " scale=%10.8f,tilt= %10.7f, gamma=%10.7f, beta=%10.7f, rot=%10.7f, w1=%10.8f, w2=%10.8f, \u0394w=%10.8f"; // ratio=%10.8f"; String fmt_deg = " scale=%10.8f,tilt= %10.5f\u00B0, gamma=%10.5f\u00B0, beta=%10.5f\u00B0, rot=%10.5f\u00B0, w1=%10.8f, w2=%10.8f, ratio=%10.8f"; String fmt_deg = " scale=%10.8f,tilt= %10.5f\u00B0, gamma=%10.5f\u00B0, beta=%10.5f\u00B0, rot=%10.5f\u00B0, w1=%10.8f, w2=%10.8f, \u0394w=%10.8f"; // ratio=%10.8f\"; if (tab_mode==2) { if (tab_mode==2) { return degrees?tab_title_deg:tab_title_rad; return degrees?tab_title_deg:tab_title_rad; } } String fmt = (tab_mode==1)?(degrees ? tab_fmt_deg : tab_fmt_rad):(degrees ? fmt_deg : fmt_rad); String fmt = (tab_mode==1)?(degrees ? tab_fmt_deg : tab_fmt_rad):(degrees ? fmt_deg : fmt_rad); double s = degrees ? (180/Math.PI):1; double s = degrees ? (180/Math.PI):1; // String fmt=degrees ? fmt_deg : fmt_rad; // String fmt=degrees ? fmt_deg : fmt_rad; return String.format(fmt, scale, s*getTiltAngle(), s*gamma, s*beta, s*rot, w1, w2, ratio); // return String.format(fmt, scale, s*getTiltAngle(), s*gamma, s*beta, s*rot, w1, w2, ratio); return String.format(fmt, scale, s*getTiltAngle(), s*gamma, s*beta, s*rot, w1, w2, Math.abs(w1-w2)); } } Loading