Loading src/main/java/com/elphel/imagej/orthomosaic/ComboMatch.java +103 −7 Original line number Original line Diff line number Diff line Loading @@ -327,7 +327,29 @@ public class ComboMatch { "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or45.0_oe20.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or45.0_oe20.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or40.0_oe20.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or40.0_oe20.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or35.0_oe15.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or35.0_oe15.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e20.0_ir10.0_ie8.0_is0.0_or35.0_oe15.0_os-1.0_h8_w0.6_s-60.0_200x200.tif" "patterns_r20.0_e20.0_ir10.0_ie8.0_is0.0_or35.0_oe15.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r30.0_e15.0_ir15.0ie8.0_is-0.05_h8_w0.6_s-200.0_200x200.tiff", // morning used "--- 30, 28 edge 10 --", "patterns_r30.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r30.0_e10.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r28.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r28.0_e10.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "--- 26, 32 edge 10 --", "patterns_r26.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e10.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", // "patterns_r32.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-170.0_200x200.tif", "patterns_r32.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r32.0_e10.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "---- 30, 26 edge 6 ---", "patterns_r30.0_e6.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r30.0_e6.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e6.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e6.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "---- 30, 26 edge 8 ---", "patterns_r30.0_e8.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r30.0_e8.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e8.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e8.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif" }; }; Loading Loading @@ -399,9 +421,39 @@ public class ComboMatch { for (ObjectLocation ol: object_list) { for (ObjectLocation ol: object_list) { System.out.println(ol.name+": "+ol.xy_meters[0]+"/"+ol.xy_meters[1]); System.out.println(ol.name+": "+ol.xy_meters[0]+"/"+ol.xy_meters[1]); } } int [] indices = null; int [][] bounds = maps_collection.getBoundsPixels( // should be for rectified, {-bounds[0][0], -bounds[0][1]} - exact center zool_lev_objects, indices); int width = bounds[0][1] - bounds[0][0]; // bounds[x][0] - negative int height = bounds[1][1] - bounds[1][0]; if ((width != imp_sel.getWidth()) || (height != imp_sel.getHeight())) { System.out.println("Marked image ("+imp_sel.getWidth()+"x"+imp_sel.getHeight()+") does not match the full map size ("+ width+"x"+height+"), will try just for a pair of the first two slices"); String [] labels = imp_sel.getStack().getSliceLabels(); indices = new int [2]; for (int i = 0; i < indices.length; i++) { indices[i] = maps_collection.getIndex(labels[i].substring(0, 17)); } bounds = maps_collection.getBoundsPixels( // should be for rectified, {-bounds[0][0], -bounds[0][1]} - exact center zool_lev_objects, indices); width = bounds[0][1] - bounds[0][0]; // bounds[x][0] - negative height = bounds[1][1] - bounds[1][0]; if ((width != imp_sel.getWidth()) || (height != imp_sel.getHeight())) { System.out.println("Marked image ("+imp_sel.getWidth()+"x"+imp_sel.getHeight()+") does not match the 2-image map size ("+ width+"x"+height+") either.Giving up"); return false; } else { System.out.println("Marked image ("+imp_sel.getWidth()+"x"+imp_sel.getHeight()+") does match the 2-image map size ("+ width+"x"+height+"). Using it."); } } maps_collection.reverseRender( maps_collection.reverseRender( object_list, // ArrayList<ObjectLocation> objects, object_list, // ArrayList<ObjectLocation> objects, zool_lev_objects); // int zoom_level){ zool_lev_objects, // int zoom_level){ indices); // int [] indices){ // null or selected image indices System.out.println("Object coordinates in source images: "); System.out.println("Object coordinates in source images: "); for (ObjectLocation ol: object_list) { for (ObjectLocation ol: object_list) { System.out.println(ol.name+": "+ol.getPixels()[0]+"/"+ol.getPixels()[1]); System.out.println(ol.name+": "+ol.getPixels()[0]+"/"+ol.getPixels()[1]); Loading @@ -416,11 +468,14 @@ public class ComboMatch { extr_size); extr_size); } } ImagePlus imp_obj = ShowDoubleFloatArrays.makeArrays( ImagePlus imp_obj = ShowDoubleFloatArrays.makeArrays( object_stack, object_stack, extr_size, extr_size, extr_size, extr_size, OrthoMap.removeKnownExtension(imp_sel.getTitle())+"-OBJECT_"+extr_size+"x"+extr_size+".tiff", OrthoMap.removeKnownExtension(imp_sel.getTitle())+ OrthoMap.removeKnownExtension(pattern_file)+":"+sub_pattern_index+ "-OBJECT_"+extr_size+"x"+extr_size+".tiff", object_titles); // test_titles, object_titles); // test_titles, imp_obj.show(); imp_obj.show(); Loading Loading @@ -448,8 +503,10 @@ public class ComboMatch { } } double [] kernel = OrthoMap.getConvolutionKernel(default_kernel); double [] kernel = OrthoMap.getConvolutionKernel(default_kernel); double [][] centers = new double [object_stack.length][]; double [][] centers = new double [object_stack.length][]; double [][] corr_ret = new double [object_stack.length][corr_size*corr_size]; for (int i = 0; i < object_stack.length; i++) { for (int i = 0; i < object_stack.length; i++) { String dbg_prefix = "corr_patt_"+i; String dbg_prefix = "corr_patt_"+i+"-"+OrthoMap.removeKnownExtension(pattern_file)+":"+sub_pattern_index; ObjectLocation ol = object_list.get(i); ObjectLocation ol = object_list.get(i); centers[i] = ObjectLocation.getPatternCenter( centers[i] = ObjectLocation.getPatternCenter( object_stack[i], // double [] data, object_stack[i], // double [] data, Loading @@ -460,6 +517,7 @@ public class ComboMatch { min_corr, // double min_corr, min_corr, // double min_corr, radius_search, // int radius_search, radius_search, // int radius_search, radius_centroid, // int radius_centroid, radius_centroid, // int radius_centroid, corr_ret[i], //double [] corr_ret, // null or double[corr_size*corr_size] dbg_prefix, // String dbg_prefix, dbg_prefix, // String dbg_prefix, debugLevel); // int debugLevel) debugLevel); // int debugLevel) System.out.println(i+": center at "+centers[i][0]+"/"+centers[i][1]+", strength="+centers[i][2]); System.out.println(i+": center at "+centers[i][0]+"/"+centers[i][1]+", strength="+centers[i][2]); Loading @@ -470,6 +528,35 @@ public class ComboMatch { roi.addPoint(centers[i][0]+extr_size/2, centers[i][1]+extr_size/2, i+1); // ,1); roi.addPoint(centers[i][0]+extr_size/2, centers[i][1]+extr_size/2, i+1); // ,1); } } imp_obj.setRoi(roi); imp_obj.setRoi(roi); // calculate statistics for cor_ret[i] double [][] stats = new double [object_stack.length][]; double search_rad = 15.0; double frac_max = 0.5; double other_rad = 25; for (int i = 0; i < object_stack.length; i++) { double [] a_cent= {corr_size/2+centers[i][0],corr_size/2+centers[i][1]}; stats[i]=ObjectLocation.getMaxLocArea( corr_ret[i], // double [] data, // square data a_cent, // centers[i], // double [] cent_xy, // if null, use center of the square search_rad, // double radius, // search for maximum within this radius frac_max, // double frac_max, other_rad, 0); // int debugLevel) } System.out.println("\nUsing pattern file: "+pattern_path+", subpattern="+sub_pattern_index); System.out.println(String.format("%2s (%9s): %7s %7s %7s %7s %7s %7s %17s", "#"," X/Y ","strengh", "radius", " elong ", " dist ", " dx "," dy ", "image timestamp")); for (int i = 0; i < object_stack.length; i++) { ObjectLocation ol = object_list.get(i); System.out.println(String.format("%2d (%4d/%4d): %7.5f %7.3f %7.3f %7.3f %7.3f %7.3f %17s", i, ol.getPixels()[0], ol.getPixels()[1], stats[i][0],stats[i][1],stats[i][2],stats[i][3],stats[i][4]+centers[i][0],stats[i][5]+centers[i][1], ol.getName())); } System.out.println(); if (only_correlate) { if (only_correlate) { System.out.println("testPatternCorrelate(): correlation DONE, only_correlate is set to true, exiting"); System.out.println("testPatternCorrelate(): correlation DONE, only_correlate is set to true, exiting"); return true; return true; Loading Loading @@ -797,7 +884,8 @@ public class ComboMatch { } } if (render_match) { if (render_match) { ImagePlus imp_img_pair = maps_collection.renderMulti ( ImagePlus imp_img_pair = maps_collection.renderMulti ( "multi_"+gpu_spair[0]+"-"+gpu_spair[1]+"-zoom_"+min_zoom_lev+"_"+zoom_lev, // String title, //_zoom<integer> is needed for opening with "Extract Objects" command "multi_"+gpu_spair[0]+"-"+gpu_spair[1]+"_zoom"+min_zoom_lev+"_"+zoom_lev, // String title, false, // boolean use_alt, false, // boolean use_alt, gpu_pair, // int [] indices, // null or which indices to use (normally just 2 for pairwise comparison) gpu_pair, // int [] indices, // null or which indices to use (normally just 2 for pairwise comparison) bounds_to_indices, // boolean bounds_to_indices, bounds_to_indices, // boolean bounds_to_indices, Loading @@ -824,6 +912,11 @@ public class ComboMatch { return true; return true; } } public void printSceneStats() { } /* /* double [][] affine1 = { double [][] affine1 = { {1,0,0}, {1,0,0}, Loading Loading @@ -1056,7 +1149,10 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341 int nSlices = stack_scenes.getSize(); int nSlices = stack_scenes.getSize(); String [] scene_names = new String [nSlices]; String [] scene_names = new String [nSlices]; for (int n = 0; n < scene_names.length; n++) { for (int n = 0; n < scene_names.length; n++) { scene_names[n] = stack_scenes.getSliceLabel(n+1).substring(0,17); scene_names[n] = stack_scenes.getSliceLabel(n+1); if (scene_names[n].length() >= 17) { scene_names[n] = scene_names[n].substring(0,17); } } } PointRoi pRoi = (PointRoi) imp.getRoi(); PointRoi pRoi = (PointRoi) imp.getRoi(); FloatPolygon fp = pRoi.getContainedFloatPoints(); FloatPolygon fp = pRoi.getContainedFloatPoints(); Loading src/main/java/com/elphel/imagej/orthomosaic/ObjectLocation.java +45 −5 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,7 @@ public class ObjectLocation { * @param cent_xy offset from the square center to search * @param cent_xy offset from the square center to search * @param radius search for maximum within this radius * @param radius search for maximum within this radius * @param frac_max fraction of maximum to measure area * @param frac_max fraction of maximum to measure area * @param other_radius measure maximal disconnected pixel fraction of the maximum within this radius * @return {maximum, area, dist, x, y}. No interpolation yet, each returned value is integer. * @return {maximum, area, dist, x, y}. No interpolation yet, each returned value is integer. * Returns null if no local maximum within area. x,y are offsets from the (provided) center * Returns null if no local maximum within area. x,y are offsets from the (provided) center */ */ Loading @@ -133,12 +134,14 @@ public class ObjectLocation { double [] cent_xy, // if null, use center of the square double [] cent_xy, // if null, use center of the square double radius, // search for maximum within this radius double radius, // search for maximum within this radius double frac_max, double frac_max, double other_radius, int debugLevel) { int debugLevel) { double [] rslt = getMaxLocArea( double [] rslt = getMaxLocArea( data, // square data data, // square data cent_xy, // if null, use center of the square cent_xy, // if null, use center of the square radius, // search for maximum within this radius radius, // search for maximum within this radius frac_max, frac_max, other_radius, debugLevel); debugLevel); if (rslt != null) { if (rslt != null) { return rslt; return rslt; Loading @@ -152,6 +155,7 @@ public class ObjectLocation { double [] cent_xy, // if null, use center of the square double [] cent_xy, // if null, use center of the square double radius, // search for maximum within this radius double radius, // search for maximum within this radius double frac_max, double frac_max, double other_radius, int debugLevel) { int debugLevel) { boolean debug = debugLevel > 1; boolean debug = debugLevel > 1; int size = (int) Math.sqrt(data.length); int size = (int) Math.sqrt(data.length); Loading Loading @@ -201,8 +205,11 @@ public class ObjectLocation { false); // boolean ordered) false); // boolean ordered) int center_cluster = clusters[best_indx]; int center_cluster = clusters[best_indx]; double xc = best_indx % size - cent_xy[0]; int best_x = best_indx % size; double yc = best_indx / size - cent_xy[1]; int best_y = best_indx / size; double xc = best_x - cent_xy[0]; double yc = best_y - cent_xy[1]; double s0=0, sx=0, sy=0, sx2 = 0, sy2=0, sxy = 0; double s0=0, sx=0, sy=0, sx2 = 0, sy2=0, sxy = 0; for (int i = 0; i < clusters.length; i++) { for (int i = 0; i < clusters.length; i++) { Loading Loading @@ -233,6 +240,35 @@ public class ObjectLocation { double elong = Math.sqrt(eigval[1]/eigval[0]); double elong = Math.sqrt(eigval[1]/eigval[0]); double eff_rad = Math.sqrt(Math.sqrt(eigval[1]*eigval[0])); double eff_rad = Math.sqrt(Math.sqrt(eigval[1]*eigval[0])); double dist = Math.sqrt(cent_offs[0]*cent_offs[0] + cent_offs[1]*cent_offs[1]); double dist = Math.sqrt(cent_offs[0]*cent_offs[0] + cent_offs[1]*cent_offs[1]); double max_other = 0.0; if (other_radius > 0) { // only calculate if asked for double or2 = other_radius*other_radius; min_x = Math.max(1, (int) Math.floor(best_x-other_radius)); min_y = Math.max(1, (int) Math.floor(best_y-other_radius)); max_x = Math.min(size-2, (int) Math.ceil(best_x+other_radius)); max_y = Math.min(size-2, (int) Math.ceil(best_y+other_radius)); for (int y = min_y; y <= max_y; y++) { // do not search on very edges double dy = (y-best_y); double y2 = dy*dy; if (y2 < or2) { for (int x = min_x; x <= max_x; x++) { double dx = x - best_x; double r2 = y2 + dx*dx; if (r2 < or2) { int indx = y * size + x; if (clusters[indx] != center_cluster) { // only disconnected from the central area double d = data[indx]; if (d > max_other) { max_other = d; } } } } } } max_other /= best_d; } if (debug) { if (debug) { System.out.println("\ncenter offset ["+(sx/s0)+","+(sy/s0)+"] , from center: ["+cent_offs[0]+","+cent_offs[1]+"]"); System.out.println("\ncenter offset ["+(sx/s0)+","+(sy/s0)+"] , from center: ["+cent_offs[0]+","+cent_offs[1]+"]"); System.out.println("Covariance matrix:"); System.out.println("Covariance matrix:"); Loading @@ -241,11 +277,11 @@ public class ObjectLocation { eig.getV().print(8, 6); eig.getV().print(8, 6); System.out.println("eig.getD()"); System.out.println("eig.getD()"); eig.getD().print(8, 6); eig.getD().print(8, 6); System.out.println(String.format("best_d=%7.5f, rad=%6.3f, elong=%6.3f, dist=%6.3f, dx=%6.3f, dy=%6.3f", System.out.println(String.format("best_d=%7.5f, rad=%6.3f, elong=%6.3f, dist=%6.3f, dx=%6.3f, dy=%6.3f, mo=%5.3f", best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1])); best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1], max_other)); } } return new double [] {best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1]} ; return new double [] {best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1], max_other} ; } } Loading Loading @@ -326,6 +362,7 @@ public class ObjectLocation { double min_corr, double min_corr, int radius_search, int radius_search, int radius_centroid, int radius_centroid, double [] corr_ret, // null or double[corr_size*corr_size] String dbg_prefix, String dbg_prefix, int debugLevel){ int debugLevel){ int refine = 1; int refine = 1; Loading Loading @@ -393,6 +430,9 @@ public class ObjectLocation { false, // final boolean convolve, // convolve, not correlate false, // final boolean convolve, // convolve, not correlate phaseCoeff, // final double phaseCoeff, phaseCoeff, // final double phaseCoeff, debugLevel); // final int debugLevel) debugLevel); // final int debugLevel) if (corr_ret != null) { System.arraycopy(corr_out, 0, corr_ret, 0, corr_out.length); } int data_width = 2 *radius_search + 1; int data_width = 2 *radius_search + 1; int offs = corr_size/2 - radius_search; int offs = corr_size/2 - radius_search; Loading src/main/java/com/elphel/imagej/orthomosaic/OrthoMap.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -3841,7 +3841,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ if (ipix1 >= 0) { if (ipix1 >= 0) { bestcorr[ipix1] = corrs[patt][ipix1]; bestcorr[ipix1] = corrs[patt][ipix1]; if (combine_full) { if (combine_full) { bestcorr[ipix1] *= corrs[full_patt_indx][ipix1]/corrs[full_patt_indx][ipix]; bestcorr[ipix1] *= Math.max(0, corrs[full_patt_indx][ipix1]/corrs[full_patt_indx][ipix]); } } bestpatt[ipix1] = patt; bestpatt[ipix1] = patt; } } Loading Loading
src/main/java/com/elphel/imagej/orthomosaic/ComboMatch.java +103 −7 Original line number Original line Diff line number Diff line Loading @@ -327,7 +327,29 @@ public class ComboMatch { "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or45.0_oe20.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or45.0_oe20.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or40.0_oe20.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or40.0_oe20.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or35.0_oe15.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e25.0_ir10.0_ie8.0_is0.0_or35.0_oe15.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r20.0_e20.0_ir10.0_ie8.0_is0.0_or35.0_oe15.0_os-1.0_h8_w0.6_s-60.0_200x200.tif" "patterns_r20.0_e20.0_ir10.0_ie8.0_is0.0_or35.0_oe15.0_os-1.0_h8_w0.6_s-60.0_200x200.tif", "patterns_r30.0_e15.0_ir15.0ie8.0_is-0.05_h8_w0.6_s-200.0_200x200.tiff", // morning used "--- 30, 28 edge 10 --", "patterns_r30.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r30.0_e10.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r28.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r28.0_e10.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "--- 26, 32 edge 10 --", "patterns_r26.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e10.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", // "patterns_r32.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-170.0_200x200.tif", "patterns_r32.0_e10.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r32.0_e10.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "---- 30, 26 edge 6 ---", "patterns_r30.0_e6.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r30.0_e6.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e6.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e6.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "---- 30, 26 edge 8 ---", "patterns_r30.0_e8.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r30.0_e8.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e8.0_ir15.0_ie8.0_is-0.05_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif", "patterns_r26.0_e8.0_ir15.0_ie8.0_is-0.3_or42.0_oe6.0_os0.0_h8_w0.6_s-200.0_200x200.tif" }; }; Loading Loading @@ -399,9 +421,39 @@ public class ComboMatch { for (ObjectLocation ol: object_list) { for (ObjectLocation ol: object_list) { System.out.println(ol.name+": "+ol.xy_meters[0]+"/"+ol.xy_meters[1]); System.out.println(ol.name+": "+ol.xy_meters[0]+"/"+ol.xy_meters[1]); } } int [] indices = null; int [][] bounds = maps_collection.getBoundsPixels( // should be for rectified, {-bounds[0][0], -bounds[0][1]} - exact center zool_lev_objects, indices); int width = bounds[0][1] - bounds[0][0]; // bounds[x][0] - negative int height = bounds[1][1] - bounds[1][0]; if ((width != imp_sel.getWidth()) || (height != imp_sel.getHeight())) { System.out.println("Marked image ("+imp_sel.getWidth()+"x"+imp_sel.getHeight()+") does not match the full map size ("+ width+"x"+height+"), will try just for a pair of the first two slices"); String [] labels = imp_sel.getStack().getSliceLabels(); indices = new int [2]; for (int i = 0; i < indices.length; i++) { indices[i] = maps_collection.getIndex(labels[i].substring(0, 17)); } bounds = maps_collection.getBoundsPixels( // should be for rectified, {-bounds[0][0], -bounds[0][1]} - exact center zool_lev_objects, indices); width = bounds[0][1] - bounds[0][0]; // bounds[x][0] - negative height = bounds[1][1] - bounds[1][0]; if ((width != imp_sel.getWidth()) || (height != imp_sel.getHeight())) { System.out.println("Marked image ("+imp_sel.getWidth()+"x"+imp_sel.getHeight()+") does not match the 2-image map size ("+ width+"x"+height+") either.Giving up"); return false; } else { System.out.println("Marked image ("+imp_sel.getWidth()+"x"+imp_sel.getHeight()+") does match the 2-image map size ("+ width+"x"+height+"). Using it."); } } maps_collection.reverseRender( maps_collection.reverseRender( object_list, // ArrayList<ObjectLocation> objects, object_list, // ArrayList<ObjectLocation> objects, zool_lev_objects); // int zoom_level){ zool_lev_objects, // int zoom_level){ indices); // int [] indices){ // null or selected image indices System.out.println("Object coordinates in source images: "); System.out.println("Object coordinates in source images: "); for (ObjectLocation ol: object_list) { for (ObjectLocation ol: object_list) { System.out.println(ol.name+": "+ol.getPixels()[0]+"/"+ol.getPixels()[1]); System.out.println(ol.name+": "+ol.getPixels()[0]+"/"+ol.getPixels()[1]); Loading @@ -416,11 +468,14 @@ public class ComboMatch { extr_size); extr_size); } } ImagePlus imp_obj = ShowDoubleFloatArrays.makeArrays( ImagePlus imp_obj = ShowDoubleFloatArrays.makeArrays( object_stack, object_stack, extr_size, extr_size, extr_size, extr_size, OrthoMap.removeKnownExtension(imp_sel.getTitle())+"-OBJECT_"+extr_size+"x"+extr_size+".tiff", OrthoMap.removeKnownExtension(imp_sel.getTitle())+ OrthoMap.removeKnownExtension(pattern_file)+":"+sub_pattern_index+ "-OBJECT_"+extr_size+"x"+extr_size+".tiff", object_titles); // test_titles, object_titles); // test_titles, imp_obj.show(); imp_obj.show(); Loading Loading @@ -448,8 +503,10 @@ public class ComboMatch { } } double [] kernel = OrthoMap.getConvolutionKernel(default_kernel); double [] kernel = OrthoMap.getConvolutionKernel(default_kernel); double [][] centers = new double [object_stack.length][]; double [][] centers = new double [object_stack.length][]; double [][] corr_ret = new double [object_stack.length][corr_size*corr_size]; for (int i = 0; i < object_stack.length; i++) { for (int i = 0; i < object_stack.length; i++) { String dbg_prefix = "corr_patt_"+i; String dbg_prefix = "corr_patt_"+i+"-"+OrthoMap.removeKnownExtension(pattern_file)+":"+sub_pattern_index; ObjectLocation ol = object_list.get(i); ObjectLocation ol = object_list.get(i); centers[i] = ObjectLocation.getPatternCenter( centers[i] = ObjectLocation.getPatternCenter( object_stack[i], // double [] data, object_stack[i], // double [] data, Loading @@ -460,6 +517,7 @@ public class ComboMatch { min_corr, // double min_corr, min_corr, // double min_corr, radius_search, // int radius_search, radius_search, // int radius_search, radius_centroid, // int radius_centroid, radius_centroid, // int radius_centroid, corr_ret[i], //double [] corr_ret, // null or double[corr_size*corr_size] dbg_prefix, // String dbg_prefix, dbg_prefix, // String dbg_prefix, debugLevel); // int debugLevel) debugLevel); // int debugLevel) System.out.println(i+": center at "+centers[i][0]+"/"+centers[i][1]+", strength="+centers[i][2]); System.out.println(i+": center at "+centers[i][0]+"/"+centers[i][1]+", strength="+centers[i][2]); Loading @@ -470,6 +528,35 @@ public class ComboMatch { roi.addPoint(centers[i][0]+extr_size/2, centers[i][1]+extr_size/2, i+1); // ,1); roi.addPoint(centers[i][0]+extr_size/2, centers[i][1]+extr_size/2, i+1); // ,1); } } imp_obj.setRoi(roi); imp_obj.setRoi(roi); // calculate statistics for cor_ret[i] double [][] stats = new double [object_stack.length][]; double search_rad = 15.0; double frac_max = 0.5; double other_rad = 25; for (int i = 0; i < object_stack.length; i++) { double [] a_cent= {corr_size/2+centers[i][0],corr_size/2+centers[i][1]}; stats[i]=ObjectLocation.getMaxLocArea( corr_ret[i], // double [] data, // square data a_cent, // centers[i], // double [] cent_xy, // if null, use center of the square search_rad, // double radius, // search for maximum within this radius frac_max, // double frac_max, other_rad, 0); // int debugLevel) } System.out.println("\nUsing pattern file: "+pattern_path+", subpattern="+sub_pattern_index); System.out.println(String.format("%2s (%9s): %7s %7s %7s %7s %7s %7s %17s", "#"," X/Y ","strengh", "radius", " elong ", " dist ", " dx "," dy ", "image timestamp")); for (int i = 0; i < object_stack.length; i++) { ObjectLocation ol = object_list.get(i); System.out.println(String.format("%2d (%4d/%4d): %7.5f %7.3f %7.3f %7.3f %7.3f %7.3f %17s", i, ol.getPixels()[0], ol.getPixels()[1], stats[i][0],stats[i][1],stats[i][2],stats[i][3],stats[i][4]+centers[i][0],stats[i][5]+centers[i][1], ol.getName())); } System.out.println(); if (only_correlate) { if (only_correlate) { System.out.println("testPatternCorrelate(): correlation DONE, only_correlate is set to true, exiting"); System.out.println("testPatternCorrelate(): correlation DONE, only_correlate is set to true, exiting"); return true; return true; Loading Loading @@ -797,7 +884,8 @@ public class ComboMatch { } } if (render_match) { if (render_match) { ImagePlus imp_img_pair = maps_collection.renderMulti ( ImagePlus imp_img_pair = maps_collection.renderMulti ( "multi_"+gpu_spair[0]+"-"+gpu_spair[1]+"-zoom_"+min_zoom_lev+"_"+zoom_lev, // String title, //_zoom<integer> is needed for opening with "Extract Objects" command "multi_"+gpu_spair[0]+"-"+gpu_spair[1]+"_zoom"+min_zoom_lev+"_"+zoom_lev, // String title, false, // boolean use_alt, false, // boolean use_alt, gpu_pair, // int [] indices, // null or which indices to use (normally just 2 for pairwise comparison) gpu_pair, // int [] indices, // null or which indices to use (normally just 2 for pairwise comparison) bounds_to_indices, // boolean bounds_to_indices, bounds_to_indices, // boolean bounds_to_indices, Loading @@ -824,6 +912,11 @@ public class ComboMatch { return true; return true; } } public void printSceneStats() { } /* /* double [][] affine1 = { double [][] affine1 = { {1,0,0}, {1,0,0}, Loading Loading @@ -1056,7 +1149,10 @@ adjusted affines[1] for a pair: 1694564291_293695/1694564778_589341 int nSlices = stack_scenes.getSize(); int nSlices = stack_scenes.getSize(); String [] scene_names = new String [nSlices]; String [] scene_names = new String [nSlices]; for (int n = 0; n < scene_names.length; n++) { for (int n = 0; n < scene_names.length; n++) { scene_names[n] = stack_scenes.getSliceLabel(n+1).substring(0,17); scene_names[n] = stack_scenes.getSliceLabel(n+1); if (scene_names[n].length() >= 17) { scene_names[n] = scene_names[n].substring(0,17); } } } PointRoi pRoi = (PointRoi) imp.getRoi(); PointRoi pRoi = (PointRoi) imp.getRoi(); FloatPolygon fp = pRoi.getContainedFloatPoints(); FloatPolygon fp = pRoi.getContainedFloatPoints(); Loading
src/main/java/com/elphel/imagej/orthomosaic/ObjectLocation.java +45 −5 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,7 @@ public class ObjectLocation { * @param cent_xy offset from the square center to search * @param cent_xy offset from the square center to search * @param radius search for maximum within this radius * @param radius search for maximum within this radius * @param frac_max fraction of maximum to measure area * @param frac_max fraction of maximum to measure area * @param other_radius measure maximal disconnected pixel fraction of the maximum within this radius * @return {maximum, area, dist, x, y}. No interpolation yet, each returned value is integer. * @return {maximum, area, dist, x, y}. No interpolation yet, each returned value is integer. * Returns null if no local maximum within area. x,y are offsets from the (provided) center * Returns null if no local maximum within area. x,y are offsets from the (provided) center */ */ Loading @@ -133,12 +134,14 @@ public class ObjectLocation { double [] cent_xy, // if null, use center of the square double [] cent_xy, // if null, use center of the square double radius, // search for maximum within this radius double radius, // search for maximum within this radius double frac_max, double frac_max, double other_radius, int debugLevel) { int debugLevel) { double [] rslt = getMaxLocArea( double [] rslt = getMaxLocArea( data, // square data data, // square data cent_xy, // if null, use center of the square cent_xy, // if null, use center of the square radius, // search for maximum within this radius radius, // search for maximum within this radius frac_max, frac_max, other_radius, debugLevel); debugLevel); if (rslt != null) { if (rslt != null) { return rslt; return rslt; Loading @@ -152,6 +155,7 @@ public class ObjectLocation { double [] cent_xy, // if null, use center of the square double [] cent_xy, // if null, use center of the square double radius, // search for maximum within this radius double radius, // search for maximum within this radius double frac_max, double frac_max, double other_radius, int debugLevel) { int debugLevel) { boolean debug = debugLevel > 1; boolean debug = debugLevel > 1; int size = (int) Math.sqrt(data.length); int size = (int) Math.sqrt(data.length); Loading Loading @@ -201,8 +205,11 @@ public class ObjectLocation { false); // boolean ordered) false); // boolean ordered) int center_cluster = clusters[best_indx]; int center_cluster = clusters[best_indx]; double xc = best_indx % size - cent_xy[0]; int best_x = best_indx % size; double yc = best_indx / size - cent_xy[1]; int best_y = best_indx / size; double xc = best_x - cent_xy[0]; double yc = best_y - cent_xy[1]; double s0=0, sx=0, sy=0, sx2 = 0, sy2=0, sxy = 0; double s0=0, sx=0, sy=0, sx2 = 0, sy2=0, sxy = 0; for (int i = 0; i < clusters.length; i++) { for (int i = 0; i < clusters.length; i++) { Loading Loading @@ -233,6 +240,35 @@ public class ObjectLocation { double elong = Math.sqrt(eigval[1]/eigval[0]); double elong = Math.sqrt(eigval[1]/eigval[0]); double eff_rad = Math.sqrt(Math.sqrt(eigval[1]*eigval[0])); double eff_rad = Math.sqrt(Math.sqrt(eigval[1]*eigval[0])); double dist = Math.sqrt(cent_offs[0]*cent_offs[0] + cent_offs[1]*cent_offs[1]); double dist = Math.sqrt(cent_offs[0]*cent_offs[0] + cent_offs[1]*cent_offs[1]); double max_other = 0.0; if (other_radius > 0) { // only calculate if asked for double or2 = other_radius*other_radius; min_x = Math.max(1, (int) Math.floor(best_x-other_radius)); min_y = Math.max(1, (int) Math.floor(best_y-other_radius)); max_x = Math.min(size-2, (int) Math.ceil(best_x+other_radius)); max_y = Math.min(size-2, (int) Math.ceil(best_y+other_radius)); for (int y = min_y; y <= max_y; y++) { // do not search on very edges double dy = (y-best_y); double y2 = dy*dy; if (y2 < or2) { for (int x = min_x; x <= max_x; x++) { double dx = x - best_x; double r2 = y2 + dx*dx; if (r2 < or2) { int indx = y * size + x; if (clusters[indx] != center_cluster) { // only disconnected from the central area double d = data[indx]; if (d > max_other) { max_other = d; } } } } } } max_other /= best_d; } if (debug) { if (debug) { System.out.println("\ncenter offset ["+(sx/s0)+","+(sy/s0)+"] , from center: ["+cent_offs[0]+","+cent_offs[1]+"]"); System.out.println("\ncenter offset ["+(sx/s0)+","+(sy/s0)+"] , from center: ["+cent_offs[0]+","+cent_offs[1]+"]"); System.out.println("Covariance matrix:"); System.out.println("Covariance matrix:"); Loading @@ -241,11 +277,11 @@ public class ObjectLocation { eig.getV().print(8, 6); eig.getV().print(8, 6); System.out.println("eig.getD()"); System.out.println("eig.getD()"); eig.getD().print(8, 6); eig.getD().print(8, 6); System.out.println(String.format("best_d=%7.5f, rad=%6.3f, elong=%6.3f, dist=%6.3f, dx=%6.3f, dy=%6.3f", System.out.println(String.format("best_d=%7.5f, rad=%6.3f, elong=%6.3f, dist=%6.3f, dx=%6.3f, dy=%6.3f, mo=%5.3f", best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1])); best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1], max_other)); } } return new double [] {best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1]} ; return new double [] {best_d, eff_rad, elong, dist, cent_offs[0], cent_offs[1], max_other} ; } } Loading Loading @@ -326,6 +362,7 @@ public class ObjectLocation { double min_corr, double min_corr, int radius_search, int radius_search, int radius_centroid, int radius_centroid, double [] corr_ret, // null or double[corr_size*corr_size] String dbg_prefix, String dbg_prefix, int debugLevel){ int debugLevel){ int refine = 1; int refine = 1; Loading Loading @@ -393,6 +430,9 @@ public class ObjectLocation { false, // final boolean convolve, // convolve, not correlate false, // final boolean convolve, // convolve, not correlate phaseCoeff, // final double phaseCoeff, phaseCoeff, // final double phaseCoeff, debugLevel); // final int debugLevel) debugLevel); // final int debugLevel) if (corr_ret != null) { System.arraycopy(corr_out, 0, corr_ret, 0, corr_out.length); } int data_width = 2 *radius_search + 1; int data_width = 2 *radius_search + 1; int offs = corr_size/2 - radius_search; int offs = corr_size/2 - radius_search; Loading
src/main/java/com/elphel/imagej/orthomosaic/OrthoMap.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -3841,7 +3841,7 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{ if (ipix1 >= 0) { if (ipix1 >= 0) { bestcorr[ipix1] = corrs[patt][ipix1]; bestcorr[ipix1] = corrs[patt][ipix1]; if (combine_full) { if (combine_full) { bestcorr[ipix1] *= corrs[full_patt_indx][ipix1]/corrs[full_patt_indx][ipix]; bestcorr[ipix1] *= Math.max(0, corrs[full_patt_indx][ipix1]/corrs[full_patt_indx][ipix]); } } bestpatt[ipix1] = patt; bestpatt[ipix1] = patt; } } Loading