Loading src/main/java/com/elphel/imagej/correction/Eyesis_Correction.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -849,6 +849,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { addButton("Read Tiff", panelLWIRWorld, color_process); addButton("Read Tiff", panelLWIRWorld, color_process); addButton("Test video", panelLWIRWorld, color_process); addButton("Test video", panelLWIRWorld, color_process); addButton("Ortho Pairs", panelLWIRWorld, color_process); addButton("Ortho Pairs", panelLWIRWorld, color_process); addButton("Extract Objects", panelLWIRWorld, color_process); addButton("Mismatched resolutions", panelLWIRWorld, color_process); addButton("Mismatched resolutions", panelLWIRWorld, color_process); addButton("Generate DATI", panelLWIRWorld, color_process); addButton("Generate DATI", panelLWIRWorld, color_process); addButton("Create mine", panelLWIRWorld, color_process); addButton("Create mine", panelLWIRWorld, color_process); Loading Loading @@ -5708,7 +5709,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { e.printStackTrace(); e.printStackTrace(); } } // ComboMatch.testReadTiff(); // ComboMatch.testReadTiff(); } else if (label.equals("Ortho Pairs")) { } else if (label.equals("Ortho Pairs") || label.equals("Extract Objects")) { DEBUG_LEVEL = MASTER_DEBUG_LEVEL; DEBUG_LEVEL = MASTER_DEBUG_LEVEL; EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL); EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL); if (GPU_TILE_PROCESSOR == null) { if (GPU_TILE_PROCESSOR == null) { Loading @@ -5729,6 +5730,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ComboMatch.openTestPairGps( ComboMatch.openTestPairGps( CLT_PARAMETERS, // CLTParameters clt_parameters, CLT_PARAMETERS, // CLTParameters clt_parameters, GPU_TILE_PROCESSOR, GPU_TILE_PROCESSOR, label.equals("Extract Objects"), // boolean extract_mines, DEBUG_LEVEL); DEBUG_LEVEL); } else if (label.equals("Test video")) { } else if (label.equals("Test video")) { ImagePlus imp_sel = WindowManager.getCurrentImage(); ImagePlus imp_sel = WindowManager.getCurrentImage(); Loading src/main/java/com/elphel/imagej/orthomosaic/AltitudeMismatchKernel.java 0 → 100644 +72 −0 Original line number Original line Diff line number Diff line package com.elphel.imagej.orthomosaic; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import ij.Prefs; public class AltitudeMismatchKernel implements Serializable{ private static final long serialVersionUID = 1L; public static String kernels_directory; public int zoom_level; public double agl_from; public double agl_to; public String filename; public AltitudeMismatchKernel ( String filename, int zoom_level, double agl_from, double agl_to) { this.filename = filename; this.zoom_level = zoom_level; this.agl_from = agl_from; this.agl_to = agl_to; } private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); } public static void setKernelsDirectory( String directory) { while (directory.endsWith(Prefs.getFileSeparator())){ directory=directory.substring(0, directory.length()-1); } kernels_directory = directory; } public static String getKernelsDirectory() { return kernels_directory; } public String getKernelPath() { return kernels_directory+Prefs.getFileSeparator()+filename; } public static AltitudeMismatchKernel getKernel( int zoom_level, double agl_from, double agl_to, ArrayList<AltitudeMismatchKernel> kernels) { double tolerance = 0.15; double agl_from_min = agl_from * (1.0 - tolerance); double agl_from_max = agl_from * (1.0 + tolerance); double agl_to_min = agl_to * (1.0 - tolerance); double agl_to_max = agl_to * (1.0 + tolerance); for (AltitudeMismatchKernel kernel:kernels) { if (zoom_level == kernel.zoom_level) { if ( (kernel.agl_from >= agl_from_min) && (kernel.agl_from <= agl_from_max) && (kernel.agl_to >= agl_to_min) && (kernel.agl_to <= agl_to_max)) return kernel; } } return null; } } src/main/java/com/elphel/imagej/orthomosaic/ComboMatch.java +50 −34 Original line number Original line Diff line number Diff line Loading @@ -46,6 +46,7 @@ public class ComboMatch { public static boolean openTestPairGps( public static boolean openTestPairGps( CLTParameters clt_parameters, CLTParameters clt_parameters, GPUTileProcessor gpu_tile_processor, // initialized by the caller GPUTileProcessor gpu_tile_processor, // initialized by the caller boolean extract_mines, int debugLevel) { int debugLevel) { GPU_TILE_PROCESSOR = gpu_tile_processor; GPU_TILE_PROCESSOR = gpu_tile_processor; PairwiseOrthoMatch pairwiseOrthoMatch = null; PairwiseOrthoMatch pairwiseOrthoMatch = null; Loading Loading @@ -85,11 +86,13 @@ public class ComboMatch { // String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m.list"; // String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m.list"; // String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m.data"; // String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m.data"; String [] files_lists_paths = { String [] files_lists_paths = { "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_sep12-13_50-25-50-75-100m", "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m", "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m", "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75"}; "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75", "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_sep12-50m"}; String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75.list"; // String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75.list"; String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75.data"; // String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75.data"; //maps_nov3_50-75 //maps_nov3_50-75 //maps_19_sep13.list //maps_19_sep13.list //maps_09_short.list //maps_09_short.list Loading Loading @@ -133,10 +136,16 @@ public class ComboMatch { boolean process_correlation = true; // use false to save new version of data boolean process_correlation = true; // use false to save new version of data boolean update_match = true; // use false to save new version of data boolean update_match = true; // use false to save new version of data boolean render_match = true; boolean render_match = true; boolean pattern_match = false; boolean bounds_to_indices = true; int temp_mode = 1; boolean restore_temp = true; boolean restore_temp = true; double frac_remove = 0.15; double frac_remove = 0.15; double metric_error = 0.05; // 0.02;// 2 cm double metric_error = 0.05; // 0.02;// 2 cm boolean update_lla = false; // re-read file metadata boolean update_lla = false; // re-read file metadata boolean update_kernel_patterns = false; if (!use_marked_image) { if (!use_marked_image) { process_correlation=false; // use already adjusted by default process_correlation=false; // use already adjusted by default } } Loading @@ -149,6 +158,13 @@ public class ComboMatch { gd.addCheckbox ("Process correlations", process_correlation, "false to skip to just regenerate new save file."); gd.addCheckbox ("Process correlations", process_correlation, "false to skip to just regenerate new save file."); gd.addCheckbox ("Update match if calculated", update_match, "Will update correlation match for a pair if found."); gd.addCheckbox ("Update match if calculated", update_match, "Will update correlation match for a pair if found."); gd.addCheckbox ("Render match", render_match, "Render a pair of matched images."); gd.addCheckbox ("Render match", render_match, "Render a pair of matched images."); gd.addCheckbox ("Pattern match", pattern_match, "Search for patterns for both images in a pair, first is primary."); gd.addCheckbox ("Bounds to selected images", bounds_to_indices, "Set combo image bounds to selected images only. False - all images."); gd.addNumericField("Temp mode", temp_mode, 0,4,"", "O - do not modify average pixels, 1 - equalize second image to first, 2 - try to account for raw average"); //temp_mode /* /* for (int n = 0; n < image_enuatr.length; n++) { for (int n = 0; n < image_enuatr.length; n++) { gd.addMessage("image["+n+"] pose"); gd.addMessage("image["+n+"] pose"); Loading @@ -174,18 +190,24 @@ public class ComboMatch { if (use_marked_image ) { if (use_marked_image ) { gd.addCheckbox ("Use marked image data", true, "Use markes from the selected image"); gd.addCheckbox ("Use marked image data", true, "Use markes from the selected image"); } } gd.addCheckbox ("Update files metadata", update_lla, "Re-read files metadata (ifd it was modified)"); gd.addCheckbox ("Update files metadata", update_lla, "Re-read files metadata (if it was modified)"); gd.addCheckbox ("Update kernels/patterns", update_kernel_patterns, "Re-read kernels and patterns from *.list file"); // update_kernel_patterns gd.showDialog(); gd.showDialog(); if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false; int choice_index = gd.getNextChoiceIndex(); int choice_index = gd.getNextChoiceIndex(); files_list_path = files_lists_paths[choice_index]+".list"; String files_list_path = files_lists_paths[choice_index]+".list"; orthoMapsCollection_path =files_lists_paths[choice_index]+".data"; String orthoMapsCollection_path =files_lists_paths[choice_index]+".data"; use_saved_collection = gd.getNextBoolean(); use_saved_collection = gd.getNextBoolean(); save_collection = gd.getNextBoolean(); save_collection = gd.getNextBoolean(); process_correlation= gd.getNextBoolean(); process_correlation= gd.getNextBoolean(); update_match= gd.getNextBoolean(); update_match= gd.getNextBoolean(); render_match= gd.getNextBoolean(); render_match= gd.getNextBoolean(); pattern_match= gd.getNextBoolean(); bounds_to_indices= gd.getNextBoolean(); temp_mode = (int) gd.getNextNumber(); /* /* for (int n = 0; n < image_enuatr.length; n++) { for (int n = 0; n < image_enuatr.length; n++) { image_enuatr[n][0][0] = gd.getNextNumber(); image_enuatr[n][0][0] = gd.getNextNumber(); Loading Loading @@ -214,6 +236,7 @@ public class ComboMatch { use_marked_image= gd.getNextBoolean(); use_marked_image= gd.getNextBoolean(); } } update_lla= gd.getNextBoolean(); update_lla= gd.getNextBoolean(); update_kernel_patterns= gd.getNextBoolean(); OrthoMapsCollection maps_collection=null; OrthoMapsCollection maps_collection=null; if (use_saved_collection) { if (use_saved_collection) { try { try { Loading @@ -222,6 +245,11 @@ public class ComboMatch { // TODO Auto-generated catch block // TODO Auto-generated catch block e.printStackTrace(); e.printStackTrace(); } } //files_list_path if (update_kernel_patterns) { maps_collection.updateKernels(files_list_path); maps_collection.updatePatterns(files_list_path); } } else { } else { maps_collection = new OrthoMapsCollection(files_list_path); // should have ".list" extension maps_collection = new OrthoMapsCollection(files_list_path); // should have ".list" extension } } Loading Loading @@ -266,6 +294,7 @@ public class ComboMatch { false, // boolean use_alt, false, // boolean use_alt, show_centers, // boolean show_centers, show_centers, // boolean show_centers, zoom_lev, // int zoom_level, zoom_lev, // int zoom_level, temp_mode, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct origin); // int [] origin){ origin); // int [] origin){ imp_img.show(); imp_img.show(); } } Loading @@ -276,10 +305,11 @@ public class ComboMatch { true, // boolean use_alt, true, // boolean use_alt, show_centers, // boolean show_centers, show_centers, // boolean show_centers, zoom_lev, // int zoom_level, zoom_lev, // int zoom_level, 0, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct origin); // int [] origin){ origin); // int [] origin){ imp_alt.show(); imp_alt.show(); } } if (process_correlation || render_match ) { if (process_correlation || render_match || pattern_match) { // int [] gpu_pair; // int [] gpu_pair; if (gpu_spair == null) { if (gpu_spair == null) { ArrayList<Point> pairs_list = new ArrayList<Point>(); ArrayList<Point> pairs_list = new ArrayList<Point>(); Loading Loading @@ -409,40 +439,26 @@ public class ComboMatch { System.out.println(); System.out.println(); } } } } if (render_match) { if (pattern_match) { ImagePlus imp_img_pair = maps_collection.renderMulti ( ImagePlus imp_pat_match = maps_collection.patterMatchDualWrap ( "multi_"+gpu_spair[0]+"-"+gpu_spair[1]+"-zoom_"+min_zoom_lev+"_"+zoom_lev, // String title, 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) affines, // double [][][] affines, // null or [indices.length][2][3] affines, // double [][][] affines, // null or [indices.length][2][3] warp, // FineXYCorr warp, warp); // FineXYCorr warp) show_centers, // boolean show_centers, // imp_pat_match.show(); min_zoom_lev, // int zoom_level, } origin); // int [] origin){ if (render_match) { imp_img_pair.show(); /* int gpu_tilesX = gpu_width/GPUTileProcessor.DTT_SIZE; Rectangle tile_woi = OrthoMapsCollection.scaleRectangle (woi, GPUTileProcessor.DTT_SIZE); double [][] vector_field_interpolated = interpolateVectorField( vector_field, // final double [][] vector_field, // sparse {vx,vy,strength} gpu_tilesX, // final int gpu_tilesX, // 512 tile_woi, // final Rectangle tile_woi, // only width, height are used top-left corners are the same scale, // final double scale, 1); // final int debugLevel); 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, "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, temp_mode, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct affines, // double [][][] affines, // null or [indices.length][2][3] affines, // double [][][] affines, // null or [indices.length][2][3] warp, // FineXYCorr warp, show_centers, // boolean show_centers, show_centers, // boolean show_centers, min_zoom_lev, // int zoom_level, min_zoom_lev, // int zoom_level, origin); // int [] origin){ origin); // int [] origin){ imp_img_pair.show(); imp_img_pair.show(); */ } } } } } } Loading src/main/java/com/elphel/imagej/orthomosaic/FineXYCorr.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -5,6 +5,7 @@ import java.awt.Rectangle; import com.elphel.imagej.gpu.GPUTileProcessor; import com.elphel.imagej.gpu.GPUTileProcessor; public class FineXYCorr { public class FineXYCorr { public double scale_warp = 1.0; public double [] top_left_metric; // relative to the reference image vertical point, normally negative public double [] top_left_metric; // relative to the reference image vertical point, normally negative public int width_tiles; public int width_tiles; public int height_tiles; public int height_tiles; Loading Loading @@ -60,7 +61,7 @@ public class FineXYCorr { * Apply warping to the x,y pair * Apply warping to the x,y pair * @param xy {X,Y} before and after warping * @param xy {X,Y} before and after warping */ */ public void warpXY(// in render pixels public void warpXY(// in render pixels NOT_USED double [] xy) { // no interpolation - using nearest double [] xy) { // no interpolation - using nearest int ix = (int) Math.round((xy[0] - render_tl[0]) * render_div_tile); int ix = (int) Math.round((xy[0] - render_tl[0]) * render_div_tile); int iy = (int) Math.round((xy[1] - render_tl[1]) * render_div_tile); int iy = (int) Math.round((xy[1] - render_tl[1]) * render_div_tile); Loading @@ -82,8 +83,8 @@ public class FineXYCorr { double [] dxdy = warp_xy[ix + width_tiles * iy]; double [] dxdy = warp_xy[ix + width_tiles * iy]; if (dxdy != null) { if (dxdy != null) { return new double [] { return new double [] { dxdy[0]*pix_div_render, dxdy[0]*pix_div_render*scale_warp, dxdy[1]*pix_div_render}; dxdy[1]*pix_div_render*scale_warp}; } } } } return new double [2]; return new double [2]; Loading src/main/java/com/elphel/imagej/orthomosaic/GroundObjectPattern.java 0 → 100644 +105 −0 Original line number Original line Diff line number Diff line package com.elphel.imagej.orthomosaic; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.time.LocalDateTime; import java.util.ArrayList; import ij.Prefs; public class GroundObjectPattern implements Serializable { private static final long serialVersionUID = 1L; public static long UTC_EAST_HRS = 3; public static String patterns_directory; //public LocalDateTime plusHours(long hours) public int zoom_level; // 1 for 5mm/pix public String object_type; // like "TM62" // public String object_version; // just change config LocalDateTime utcDateTime; // UTC public String filename; // should be square public GroundObjectPattern( String filename, int zoom_level, String object_type, LocalDateTime utcDateTime) { this.filename = filename; this.zoom_level = zoom_level; this.object_type = object_type; this.utcDateTime = utcDateTime; } private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); } public static void setPatternsDirectory( String directory) { while (directory.endsWith(Prefs.getFileSeparator())){ directory=directory.substring(0, directory.length()-1); } patterns_directory = directory; } public String getPatternPath() { return patterns_directory+Prefs.getFileSeparator()+filename; } public static String getPatternsDirectory() { return patterns_directory; } public static GroundObjectPattern getPattern( String object_type, LocalDateTime utcDateTime, ArrayList<GroundObjectPattern> patterns) { GroundObjectPattern best_gop = null; long best_hrs_diff = 24; for (GroundObjectPattern gop:patterns) { if ((object_type == null) || object_type.equals(gop.object_type)) { if (utcDateTime != null) { long hrs_diff = Math.abs(utcDateTime.getHour()-gop.utcDateTime.getHour()); if (hrs_diff > 12) { hrs_diff = 24 -hrs_diff; } if (hrs_diff < best_hrs_diff) { best_gop = gop; best_hrs_diff = hrs_diff; } } else { best_gop = gop; // use latest } } } return best_gop; } public LocalDateTime getUTC() { return utcDateTime; } public LocalDateTime getLocalDT() { return utcDateTime.plusHours(UTC_EAST_HRS); } public boolean isEvening() { return getLocalDT().getHour() >= 12; } public double getAGL() { double agl = 50; // zoom 0 for 50m AGL for (int z = zoom_level; z > 0; z--) { agl /=2; } for (int z = zoom_level; z < 0; z++) { agl *=2; } return agl; } public int getZoomLevel() { return zoom_level; } } Loading
src/main/java/com/elphel/imagej/correction/Eyesis_Correction.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -849,6 +849,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { addButton("Read Tiff", panelLWIRWorld, color_process); addButton("Read Tiff", panelLWIRWorld, color_process); addButton("Test video", panelLWIRWorld, color_process); addButton("Test video", panelLWIRWorld, color_process); addButton("Ortho Pairs", panelLWIRWorld, color_process); addButton("Ortho Pairs", panelLWIRWorld, color_process); addButton("Extract Objects", panelLWIRWorld, color_process); addButton("Mismatched resolutions", panelLWIRWorld, color_process); addButton("Mismatched resolutions", panelLWIRWorld, color_process); addButton("Generate DATI", panelLWIRWorld, color_process); addButton("Generate DATI", panelLWIRWorld, color_process); addButton("Create mine", panelLWIRWorld, color_process); addButton("Create mine", panelLWIRWorld, color_process); Loading Loading @@ -5708,7 +5709,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { e.printStackTrace(); e.printStackTrace(); } } // ComboMatch.testReadTiff(); // ComboMatch.testReadTiff(); } else if (label.equals("Ortho Pairs")) { } else if (label.equals("Ortho Pairs") || label.equals("Extract Objects")) { DEBUG_LEVEL = MASTER_DEBUG_LEVEL; DEBUG_LEVEL = MASTER_DEBUG_LEVEL; EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL); EYESIS_CORRECTIONS.setDebug(DEBUG_LEVEL); if (GPU_TILE_PROCESSOR == null) { if (GPU_TILE_PROCESSOR == null) { Loading @@ -5729,6 +5730,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ComboMatch.openTestPairGps( ComboMatch.openTestPairGps( CLT_PARAMETERS, // CLTParameters clt_parameters, CLT_PARAMETERS, // CLTParameters clt_parameters, GPU_TILE_PROCESSOR, GPU_TILE_PROCESSOR, label.equals("Extract Objects"), // boolean extract_mines, DEBUG_LEVEL); DEBUG_LEVEL); } else if (label.equals("Test video")) { } else if (label.equals("Test video")) { ImagePlus imp_sel = WindowManager.getCurrentImage(); ImagePlus imp_sel = WindowManager.getCurrentImage(); Loading
src/main/java/com/elphel/imagej/orthomosaic/AltitudeMismatchKernel.java 0 → 100644 +72 −0 Original line number Original line Diff line number Diff line package com.elphel.imagej.orthomosaic; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import ij.Prefs; public class AltitudeMismatchKernel implements Serializable{ private static final long serialVersionUID = 1L; public static String kernels_directory; public int zoom_level; public double agl_from; public double agl_to; public String filename; public AltitudeMismatchKernel ( String filename, int zoom_level, double agl_from, double agl_to) { this.filename = filename; this.zoom_level = zoom_level; this.agl_from = agl_from; this.agl_to = agl_to; } private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); } public static void setKernelsDirectory( String directory) { while (directory.endsWith(Prefs.getFileSeparator())){ directory=directory.substring(0, directory.length()-1); } kernels_directory = directory; } public static String getKernelsDirectory() { return kernels_directory; } public String getKernelPath() { return kernels_directory+Prefs.getFileSeparator()+filename; } public static AltitudeMismatchKernel getKernel( int zoom_level, double agl_from, double agl_to, ArrayList<AltitudeMismatchKernel> kernels) { double tolerance = 0.15; double agl_from_min = agl_from * (1.0 - tolerance); double agl_from_max = agl_from * (1.0 + tolerance); double agl_to_min = agl_to * (1.0 - tolerance); double agl_to_max = agl_to * (1.0 + tolerance); for (AltitudeMismatchKernel kernel:kernels) { if (zoom_level == kernel.zoom_level) { if ( (kernel.agl_from >= agl_from_min) && (kernel.agl_from <= agl_from_max) && (kernel.agl_to >= agl_to_min) && (kernel.agl_to <= agl_to_max)) return kernel; } } return null; } }
src/main/java/com/elphel/imagej/orthomosaic/ComboMatch.java +50 −34 Original line number Original line Diff line number Diff line Loading @@ -46,6 +46,7 @@ public class ComboMatch { public static boolean openTestPairGps( public static boolean openTestPairGps( CLTParameters clt_parameters, CLTParameters clt_parameters, GPUTileProcessor gpu_tile_processor, // initialized by the caller GPUTileProcessor gpu_tile_processor, // initialized by the caller boolean extract_mines, int debugLevel) { int debugLevel) { GPU_TILE_PROCESSOR = gpu_tile_processor; GPU_TILE_PROCESSOR = gpu_tile_processor; PairwiseOrthoMatch pairwiseOrthoMatch = null; PairwiseOrthoMatch pairwiseOrthoMatch = null; Loading Loading @@ -85,11 +86,13 @@ public class ComboMatch { // String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m.list"; // String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m.list"; // String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m.data"; // String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m.data"; String [] files_lists_paths = { String [] files_lists_paths = { "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_sep12-13_50-25-50-75-100m", "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m", "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_19_sep13_25-50-75-100m", "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75"}; "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75", "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_sep12-50m"}; String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75.list"; // String files_list_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75.list"; String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75.data"; // String orthoMapsCollection_path = "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_nov3_50-75.data"; //maps_nov3_50-75 //maps_nov3_50-75 //maps_19_sep13.list //maps_19_sep13.list //maps_09_short.list //maps_09_short.list Loading Loading @@ -133,10 +136,16 @@ public class ComboMatch { boolean process_correlation = true; // use false to save new version of data boolean process_correlation = true; // use false to save new version of data boolean update_match = true; // use false to save new version of data boolean update_match = true; // use false to save new version of data boolean render_match = true; boolean render_match = true; boolean pattern_match = false; boolean bounds_to_indices = true; int temp_mode = 1; boolean restore_temp = true; boolean restore_temp = true; double frac_remove = 0.15; double frac_remove = 0.15; double metric_error = 0.05; // 0.02;// 2 cm double metric_error = 0.05; // 0.02;// 2 cm boolean update_lla = false; // re-read file metadata boolean update_lla = false; // re-read file metadata boolean update_kernel_patterns = false; if (!use_marked_image) { if (!use_marked_image) { process_correlation=false; // use already adjusted by default process_correlation=false; // use already adjusted by default } } Loading @@ -149,6 +158,13 @@ public class ComboMatch { gd.addCheckbox ("Process correlations", process_correlation, "false to skip to just regenerate new save file."); gd.addCheckbox ("Process correlations", process_correlation, "false to skip to just regenerate new save file."); gd.addCheckbox ("Update match if calculated", update_match, "Will update correlation match for a pair if found."); gd.addCheckbox ("Update match if calculated", update_match, "Will update correlation match for a pair if found."); gd.addCheckbox ("Render match", render_match, "Render a pair of matched images."); gd.addCheckbox ("Render match", render_match, "Render a pair of matched images."); gd.addCheckbox ("Pattern match", pattern_match, "Search for patterns for both images in a pair, first is primary."); gd.addCheckbox ("Bounds to selected images", bounds_to_indices, "Set combo image bounds to selected images only. False - all images."); gd.addNumericField("Temp mode", temp_mode, 0,4,"", "O - do not modify average pixels, 1 - equalize second image to first, 2 - try to account for raw average"); //temp_mode /* /* for (int n = 0; n < image_enuatr.length; n++) { for (int n = 0; n < image_enuatr.length; n++) { gd.addMessage("image["+n+"] pose"); gd.addMessage("image["+n+"] pose"); Loading @@ -174,18 +190,24 @@ public class ComboMatch { if (use_marked_image ) { if (use_marked_image ) { gd.addCheckbox ("Use marked image data", true, "Use markes from the selected image"); gd.addCheckbox ("Use marked image data", true, "Use markes from the selected image"); } } gd.addCheckbox ("Update files metadata", update_lla, "Re-read files metadata (ifd it was modified)"); gd.addCheckbox ("Update files metadata", update_lla, "Re-read files metadata (if it was modified)"); gd.addCheckbox ("Update kernels/patterns", update_kernel_patterns, "Re-read kernels and patterns from *.list file"); // update_kernel_patterns gd.showDialog(); gd.showDialog(); if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false; int choice_index = gd.getNextChoiceIndex(); int choice_index = gd.getNextChoiceIndex(); files_list_path = files_lists_paths[choice_index]+".list"; String files_list_path = files_lists_paths[choice_index]+".list"; orthoMapsCollection_path =files_lists_paths[choice_index]+".data"; String orthoMapsCollection_path =files_lists_paths[choice_index]+".data"; use_saved_collection = gd.getNextBoolean(); use_saved_collection = gd.getNextBoolean(); save_collection = gd.getNextBoolean(); save_collection = gd.getNextBoolean(); process_correlation= gd.getNextBoolean(); process_correlation= gd.getNextBoolean(); update_match= gd.getNextBoolean(); update_match= gd.getNextBoolean(); render_match= gd.getNextBoolean(); render_match= gd.getNextBoolean(); pattern_match= gd.getNextBoolean(); bounds_to_indices= gd.getNextBoolean(); temp_mode = (int) gd.getNextNumber(); /* /* for (int n = 0; n < image_enuatr.length; n++) { for (int n = 0; n < image_enuatr.length; n++) { image_enuatr[n][0][0] = gd.getNextNumber(); image_enuatr[n][0][0] = gd.getNextNumber(); Loading Loading @@ -214,6 +236,7 @@ public class ComboMatch { use_marked_image= gd.getNextBoolean(); use_marked_image= gd.getNextBoolean(); } } update_lla= gd.getNextBoolean(); update_lla= gd.getNextBoolean(); update_kernel_patterns= gd.getNextBoolean(); OrthoMapsCollection maps_collection=null; OrthoMapsCollection maps_collection=null; if (use_saved_collection) { if (use_saved_collection) { try { try { Loading @@ -222,6 +245,11 @@ public class ComboMatch { // TODO Auto-generated catch block // TODO Auto-generated catch block e.printStackTrace(); e.printStackTrace(); } } //files_list_path if (update_kernel_patterns) { maps_collection.updateKernels(files_list_path); maps_collection.updatePatterns(files_list_path); } } else { } else { maps_collection = new OrthoMapsCollection(files_list_path); // should have ".list" extension maps_collection = new OrthoMapsCollection(files_list_path); // should have ".list" extension } } Loading Loading @@ -266,6 +294,7 @@ public class ComboMatch { false, // boolean use_alt, false, // boolean use_alt, show_centers, // boolean show_centers, show_centers, // boolean show_centers, zoom_lev, // int zoom_level, zoom_lev, // int zoom_level, temp_mode, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct origin); // int [] origin){ origin); // int [] origin){ imp_img.show(); imp_img.show(); } } Loading @@ -276,10 +305,11 @@ public class ComboMatch { true, // boolean use_alt, true, // boolean use_alt, show_centers, // boolean show_centers, show_centers, // boolean show_centers, zoom_lev, // int zoom_level, zoom_lev, // int zoom_level, 0, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct origin); // int [] origin){ origin); // int [] origin){ imp_alt.show(); imp_alt.show(); } } if (process_correlation || render_match ) { if (process_correlation || render_match || pattern_match) { // int [] gpu_pair; // int [] gpu_pair; if (gpu_spair == null) { if (gpu_spair == null) { ArrayList<Point> pairs_list = new ArrayList<Point>(); ArrayList<Point> pairs_list = new ArrayList<Point>(); Loading Loading @@ -409,40 +439,26 @@ public class ComboMatch { System.out.println(); System.out.println(); } } } } if (render_match) { if (pattern_match) { ImagePlus imp_img_pair = maps_collection.renderMulti ( ImagePlus imp_pat_match = maps_collection.patterMatchDualWrap ( "multi_"+gpu_spair[0]+"-"+gpu_spair[1]+"-zoom_"+min_zoom_lev+"_"+zoom_lev, // String title, 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) affines, // double [][][] affines, // null or [indices.length][2][3] affines, // double [][][] affines, // null or [indices.length][2][3] warp, // FineXYCorr warp, warp); // FineXYCorr warp) show_centers, // boolean show_centers, // imp_pat_match.show(); min_zoom_lev, // int zoom_level, } origin); // int [] origin){ if (render_match) { imp_img_pair.show(); /* int gpu_tilesX = gpu_width/GPUTileProcessor.DTT_SIZE; Rectangle tile_woi = OrthoMapsCollection.scaleRectangle (woi, GPUTileProcessor.DTT_SIZE); double [][] vector_field_interpolated = interpolateVectorField( vector_field, // final double [][] vector_field, // sparse {vx,vy,strength} gpu_tilesX, // final int gpu_tilesX, // 512 tile_woi, // final Rectangle tile_woi, // only width, height are used top-left corners are the same scale, // final double scale, 1); // final int debugLevel); 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, "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, temp_mode, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct affines, // double [][][] affines, // null or [indices.length][2][3] affines, // double [][][] affines, // null or [indices.length][2][3] warp, // FineXYCorr warp, show_centers, // boolean show_centers, show_centers, // boolean show_centers, min_zoom_lev, // int zoom_level, min_zoom_lev, // int zoom_level, origin); // int [] origin){ origin); // int [] origin){ imp_img_pair.show(); imp_img_pair.show(); */ } } } } } } Loading
src/main/java/com/elphel/imagej/orthomosaic/FineXYCorr.java +4 −3 Original line number Original line Diff line number Diff line Loading @@ -5,6 +5,7 @@ import java.awt.Rectangle; import com.elphel.imagej.gpu.GPUTileProcessor; import com.elphel.imagej.gpu.GPUTileProcessor; public class FineXYCorr { public class FineXYCorr { public double scale_warp = 1.0; public double [] top_left_metric; // relative to the reference image vertical point, normally negative public double [] top_left_metric; // relative to the reference image vertical point, normally negative public int width_tiles; public int width_tiles; public int height_tiles; public int height_tiles; Loading Loading @@ -60,7 +61,7 @@ public class FineXYCorr { * Apply warping to the x,y pair * Apply warping to the x,y pair * @param xy {X,Y} before and after warping * @param xy {X,Y} before and after warping */ */ public void warpXY(// in render pixels public void warpXY(// in render pixels NOT_USED double [] xy) { // no interpolation - using nearest double [] xy) { // no interpolation - using nearest int ix = (int) Math.round((xy[0] - render_tl[0]) * render_div_tile); int ix = (int) Math.round((xy[0] - render_tl[0]) * render_div_tile); int iy = (int) Math.round((xy[1] - render_tl[1]) * render_div_tile); int iy = (int) Math.round((xy[1] - render_tl[1]) * render_div_tile); Loading @@ -82,8 +83,8 @@ public class FineXYCorr { double [] dxdy = warp_xy[ix + width_tiles * iy]; double [] dxdy = warp_xy[ix + width_tiles * iy]; if (dxdy != null) { if (dxdy != null) { return new double [] { return new double [] { dxdy[0]*pix_div_render, dxdy[0]*pix_div_render*scale_warp, dxdy[1]*pix_div_render}; dxdy[1]*pix_div_render*scale_warp}; } } } } return new double [2]; return new double [2]; Loading
src/main/java/com/elphel/imagej/orthomosaic/GroundObjectPattern.java 0 → 100644 +105 −0 Original line number Original line Diff line number Diff line package com.elphel.imagej.orthomosaic; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.time.LocalDateTime; import java.util.ArrayList; import ij.Prefs; public class GroundObjectPattern implements Serializable { private static final long serialVersionUID = 1L; public static long UTC_EAST_HRS = 3; public static String patterns_directory; //public LocalDateTime plusHours(long hours) public int zoom_level; // 1 for 5mm/pix public String object_type; // like "TM62" // public String object_version; // just change config LocalDateTime utcDateTime; // UTC public String filename; // should be square public GroundObjectPattern( String filename, int zoom_level, String object_type, LocalDateTime utcDateTime) { this.filename = filename; this.zoom_level = zoom_level; this.object_type = object_type; this.utcDateTime = utcDateTime; } private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); } public static void setPatternsDirectory( String directory) { while (directory.endsWith(Prefs.getFileSeparator())){ directory=directory.substring(0, directory.length()-1); } patterns_directory = directory; } public String getPatternPath() { return patterns_directory+Prefs.getFileSeparator()+filename; } public static String getPatternsDirectory() { return patterns_directory; } public static GroundObjectPattern getPattern( String object_type, LocalDateTime utcDateTime, ArrayList<GroundObjectPattern> patterns) { GroundObjectPattern best_gop = null; long best_hrs_diff = 24; for (GroundObjectPattern gop:patterns) { if ((object_type == null) || object_type.equals(gop.object_type)) { if (utcDateTime != null) { long hrs_diff = Math.abs(utcDateTime.getHour()-gop.utcDateTime.getHour()); if (hrs_diff > 12) { hrs_diff = 24 -hrs_diff; } if (hrs_diff < best_hrs_diff) { best_gop = gop; best_hrs_diff = hrs_diff; } } else { best_gop = gop; // use latest } } } return best_gop; } public LocalDateTime getUTC() { return utcDateTime; } public LocalDateTime getLocalDT() { return utcDateTime.plusHours(UTC_EAST_HRS); } public boolean isEvening() { return getLocalDT().getHour() >= 12; } public double getAGL() { double agl = 50; // zoom 0 for 50m AGL for (int z = zoom_level; z > 0; z--) { agl /=2; } for (int z = zoom_level; z < 0; z++) { agl *=2; } return agl; } public int getZoomLevel() { return zoom_level; } }