Commit 8667ae4b authored by Andrey Filippov's avatar Andrey Filippov

Object matching in different flights

parent 02845a72
...@@ -849,6 +849,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ...@@ -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);
...@@ -5708,7 +5709,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ...@@ -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) {
...@@ -5729,6 +5730,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener { ...@@ -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();
......
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;
}
}
...@@ -46,6 +46,7 @@ public class ComboMatch { ...@@ -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;
...@@ -85,11 +86,13 @@ public class ComboMatch { ...@@ -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
...@@ -133,10 +136,16 @@ public class ComboMatch { ...@@ -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
} }
...@@ -149,6 +158,13 @@ public class ComboMatch { ...@@ -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");
...@@ -174,18 +190,24 @@ public class ComboMatch { ...@@ -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();
...@@ -214,6 +236,7 @@ public class ComboMatch { ...@@ -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 {
...@@ -222,6 +245,11 @@ public class ComboMatch { ...@@ -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
} }
...@@ -266,6 +294,7 @@ public class ComboMatch { ...@@ -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();
} }
...@@ -276,10 +305,11 @@ public class ComboMatch { ...@@ -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>();
...@@ -409,40 +439,26 @@ public class ComboMatch { ...@@ -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();
*/
} }
} }
} }
......
...@@ -5,6 +5,7 @@ import java.awt.Rectangle; ...@@ -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;
...@@ -60,7 +61,7 @@ public class FineXYCorr { ...@@ -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);
...@@ -82,8 +83,8 @@ public class FineXYCorr { ...@@ -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];
......
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;
}
}
package com.elphel.imagej.orthomosaic;
public class ObjectLocation {
String name;
double [] xy_meters;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment