Commit c1e50a2a authored by Andrey Filippov's avatar Andrey Filippov

Tuning classifier

parent cc9dbf30
......@@ -268,6 +268,22 @@ import ij.process.ImageProcessor;
return array_stack;
}
public static ImageStack makeStack(byte[][] pixels, int width, int height, String [] titles) {
ImageStack array_stack=new ImageStack(width,height);
for (int i=0;i<pixels.length;i++) if (pixels[i]!=null) {
if (pixels[i].length!=(width*height)){
System.out.println("showArrays(): pixels["+i+"].length="+pixels[i].length+" != width (+"+width+") * height("+height+")="+(width*height));
return null;
}
if (titles!=null){
array_stack.addSlice(titles[i], pixels[i]);
} else {
array_stack.addSlice("chn-"+i, pixels[i]);
}
}
return array_stack;
}
public static ImagePlus [] makeArrays(double[][] pixels, int width, int height, String title) {
int i,j;
......
......@@ -103,7 +103,8 @@ public class ComboMatch {
"/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_nov3_50-75",
"/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_sep12-50m"};
"/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_sep12-50m",
"/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/maps_sep12-13_50-25-50-75-100m-SUBSET"};
int default_list_choice = 0; // files_lists_paths.length-1;
// 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";
......@@ -142,11 +143,13 @@ public class ComboMatch {
int gpu_width= clt_parameters.imp.rln_gpu_width; // 3008;
int gpu_height= clt_parameters.imp.rln_gpu_height; // 3008;
int zoom_lev = -3; // 0; // +1 - zoom in twice, -1 - zoom out twice
boolean show_combo_map = false; // true;
boolean use_alt = false;
boolean show_centers = true;
boolean show_map_stats = false;
boolean show_combo_map = false; // true;
boolean show_combo_mask = false; // generate image mas (where it is defined)_
boolean use_alt = false;
boolean show_centers = true;
boolean use_saved_collection = true; // false;
boolean save_collection = true;
boolean save_collection = true;
boolean process_correlation = true; // use false to save new version of data
int num_tries_fit = 10;
boolean update_match = true; // use false to save new version of data
......@@ -164,6 +167,10 @@ public class ComboMatch {
if (!use_marked_image) {
process_correlation=false; // use already adjusted by default
}
if (process_correlation) {
render_match = true; // default
pattern_match = false;
}
GenericJTabbedDialog gd = new GenericJTabbedDialog("Set image pair",1200,900);
......@@ -200,8 +207,10 @@ public class ComboMatch {
"GPU image width");
gd.addNumericField("GPU image height", gpu_height, 0,4,"",
"GPU image height");
gd.addCheckbox ("Show transformation centers", show_centers, "Mark verticals from the UAS on the ground.");
gd.addCheckbox ("Show combo image map", show_combo_map, "Load and process altitude maps.");
gd.addCheckbox ("Show transformation centers", show_centers, "Mark verticals from the UAS on the ground.");
gd.addCheckbox ("Show statistics for ortho images", show_map_stats, "Generate and show statistics for ortho maps.");
gd.addCheckbox ("Show combo image map", show_combo_map, "Load and process altitude maps.");
gd.addCheckbox ("Show combo image mask", show_combo_mask, "Display combo binary image.");
gd.addCheckbox ("Show altitude combo image", use_alt, "Load and process altitude maps.");
gd.addNumericField("Remove fraction of worst matches", frac_remove, 3,7,"", "When fitting scenes remove this fraction of worst match.");
gd.addNumericField("Maximal metric error", metric_error, 3,7,"m", "Maximal tolerable fitting error caused by elevation variations.");
......@@ -244,7 +253,9 @@ public class ComboMatch {
OrthoMap.setGPUWidthHeight(gpu_width,gpu_height);
show_centers = gd.getNextBoolean();
show_map_stats = gd.getNextBoolean();
show_combo_map = gd.getNextBoolean();
show_combo_mask = gd.getNextBoolean();
use_alt = gd.getNextBoolean();
// gpu_spair[0] = gd.getNextString();
......@@ -271,12 +282,14 @@ public class ComboMatch {
}
} else {
maps_collection = new OrthoMapsCollection(files_list_path); // should have ".list" extension
maps_collection.updateNumberScenes();
maps_collection.updateSfmGain();
}
String [] names = maps_collection.getNames();
String [] names = maps_collection.getNames(); // null
if (object_list != null) {
int corr_size = 128;
int extr_size = 200; // 256;
int zoomout = 2; // 1; //2; // 1; 2 for simulated,1 - for extracted
int zoomout = 2; // 1; //2; // 1; 2 for simulated,1 - for extracted
int patt_choice = 3;
double phaseCoeff = 0.98;
double min_corr = 0.01; // 0.0025; // real max >0.005 with scale -500000;
......@@ -298,7 +311,6 @@ public class ComboMatch {
double inv_blur_center = 1.0; // cosine blur (in original pixels) in the center (<blur_radius) area
double inv_blur_radius =100.0; // constant blur radius
double inv_blur_rate = 0.2; // blur increase outside of blur_radius
// String pattern_dir= "/media/elphel/SSD3-4GB/lwir16-proc/ortho_videos/debug/mines/pattern_25m_zoom1/synthetic/";
......@@ -392,8 +404,6 @@ public class ComboMatch {
if (gdo.wasCanceled()) return false;
corr_size = (int) gdo.getNextNumber();
extr_size = (int) gdo.getNextNumber();
// OrthoMap.pattern_dir= gdo.getNextString();
// String pattern_file = OrthoMap.pattern_files[gdo.getNextChoiceIndex()];
pattern_dir= gdo.getNextString();
String pattern_file = pattern_files[gdo.getNextChoiceIndex()];
zoomout= (int) gdo.getNextNumber();
......@@ -718,16 +728,27 @@ public class ComboMatch {
if (update_lla) {
System.out.println("Updating map files metadata");
maps_collection.updateLLa();
maps_collection.updateNumberScenes();
maps_collection.updateSfmGain();
}
// which pair to compare
// String [] gpu_spair = {names[gpu_ipair[0]],names[gpu_ipair[1]]};
int [] origin = new int[2];
ImagePlus imp_img = null;
if (show_map_stats) {
boolean ok = maps_collection.showScenesStats(false); // boolean select_all)
if (!ok) {
return false;
}
// System.out.println("Exiting after generating stats");
// return true; // do not process anything else
}
if (show_combo_map) {
imp_img = maps_collection.renderMulti (
"multi_zoom"+zoom_lev, // String title,
false, // boolean use_alt,
OrthoMapsCollection.MODE_IMAGE, // int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask // boolean use_alt,
show_centers, // boolean show_centers,
zoom_lev, // int zoom_level,
temp_mode, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct
......@@ -738,7 +759,19 @@ public class ComboMatch {
if (use_alt) {
imp_alt =maps_collection.renderMulti (
"multi_alt_zoom"+zoom_lev, // String title,
true, // boolean use_alt,
// true, // boolean use_alt,
OrthoMapsCollection.MODE_ALT, // int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask // boolean use_alt,
show_centers, // boolean show_centers,
zoom_lev, // int zoom_level,
0, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct
origin); // int [] origin){
imp_alt.show();
}
if (show_combo_mask) {
imp_alt =maps_collection.renderMulti (
"multi_alt_zoom"+zoom_lev, // String title,
// true, // boolean use_alt,
OrthoMapsCollection.MODE_MASK, // int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask // boolean use_alt,
show_centers, // boolean show_centers,
zoom_lev, // int zoom_level,
0, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct
......@@ -886,7 +919,8 @@ public class ComboMatch {
ImagePlus imp_img_pair = maps_collection.renderMulti (
//_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,
OrthoMapsCollection.MODE_IMAGE, // int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask // boolean use_alt,
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
......@@ -910,10 +944,6 @@ public class ComboMatch {
System.out.println("Saved data to "+ orthoMapsCollection_path);
}
return true;
}
public void printSceneStats() {
}
......
......@@ -34,6 +34,7 @@ import com.elphel.imagej.readers.ElphelTiffReader;
import com.elphel.imagej.readers.ImagejJp4Tiff;
import com.elphel.imagej.tileprocessor.ImageDtt;
import com.elphel.imagej.tileprocessor.IntersceneMatchParameters;
import com.elphel.imagej.tileprocessor.OpticalFlow;
import com.elphel.imagej.tileprocessor.QuadCLT;
import com.elphel.imagej.tileprocessor.TileNeibs;
......@@ -54,6 +55,8 @@ import loci.formats.FormatException;
public class OrthoMap implements Comparable <OrthoMap>, Serializable{
private static final long serialVersionUID = 1L;
public static final String DSI_SUFFIX = "-INTER-INTRA-LMA.tiff";
public static final String MERGED_SUFFIX = "-MERGED.tiff";
public static boolean FIX_VERT_Y = false; // true; // temporarily fix vertical Y coordinate bug (use -GCORR in the filename?)
public static int gpu_width = 4096;
public static int gpu_height = 4096;
......@@ -84,12 +87,9 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
public static final String ALT_SUFFIX = "-ALT";
// public transient final String name; // timestamp
// public transient final double ts;
public transient String name; // timestamp
public transient double ts;
public transient String path; // full path to the model directory (including /vXX?)
// public transient String scenes_path; // full path to the model directory (including /vXX?)
public double [] lla; // lat/long/alt
public LocalDateTime dt;
// affine convert (input) rectified coordinates (meters) relative to vert_meters to source image
......@@ -109,7 +109,9 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
transient HashMap <Integer, FloatImageData> images;
HashMap <String, PairwiseOrthoMatch> pairwise_matches;
public transient SensorTemperatureData[] temp_data;
public transient double agl = Double.NaN;
public transient double agl = Double.NaN;
public transient int num_scenes = -1;; // number of scenes that made up this image
public transient double sfm_gain = Double.NaN; // maximal SfM gain of this map
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(path);
......@@ -130,9 +132,13 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
// pairwise_matches is not transient
oos.writeObject(temp_data); // temporary, while transient
oos.writeObject(agl);
oos.writeObject(num_scenes);
oos.writeObject(sfm_gain);
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
// sfm_gain = Double.NaN;
// num_scenes = -1;
ois.defaultReadObject();
path = (String) ois.readObject();
name = getNameFromPath(path);
......@@ -149,8 +155,8 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
// alt_image was not saved
temp_data = (SensorTemperatureData[]) ois.readObject();
agl = (double) ois.readObject();
num_scenes = (int) ois.readObject();
sfm_gain = (double) ois.readObject();
images = new HashMap <Integer, FloatImageData>(); // field images was not saved
averageImagePixel = Double.NaN; // average image pixel value (to combine with raw)
......@@ -210,6 +216,78 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
public String getScenesPath() {
return getModelPathFromPath(this.path)+"/jp4";
}
/**
* Get number of scenes used to generate this ortho image. Looks in subdirectories of the directory
* where the image file is stored (currently they are v01, vo2, ...) and in subdirectories finds the
* latest *-MERGED.tiff file. Each scene has a slice in this file
* @return number of scenes that made this ortho image, also sets the num_scenes (saved in database)
* so next time reading files will not be needed
*/
public int getNumberScenes() {
if (num_scenes < 0) {
String merged_path = getLatestFilePath(MERGED_SUFFIX);
if (merged_path != null) {
ImagePlus imp_merged = new ImagePlus(merged_path);
if (imp_merged.getWidth() > 0) {
num_scenes = imp_merged.getImageStack().getSize();
}
}
}
return num_scenes;
}
/**
* Get maximal "SfM gain" - ratio between used interscene offset and the camera baseline.
* Looks in subdirectories of the directory where the image file is stored (currently they are
* v01, vo2, ...) and in subdirectories finds the latest *-INTER-INTRA-LMA.tiff file.
* Those files have a slice (OpticalFlow.COMBO_DSN_INDX_SFM_GAIN + 1 as slices a numbered from 1)
* that contains per-tile SfM gain.
* @return Maximal SfM gain
*/
public double getSfmGain() {
if (Double.isNaN(sfm_gain)) {
String dsi_path = getLatestFilePath(DSI_SUFFIX);
if (dsi_path != null) {
ImagePlus imp_dsi = new ImagePlus(dsi_path);
if (imp_dsi.getWidth() > 0) {
float [] pixels = (float[]) imp_dsi.getImageStack().getPixels(OpticalFlow.COMBO_DSN_INDX_SFM_GAIN + 1);
sfm_gain = 0;
for (int i = 0; i < pixels.length; i++) {
if (pixels[i] > sfm_gain) {
sfm_gain = pixels[i];
}
}
}
}
}
return sfm_gain;
}
public String getLatestFilePath(String suffix) {
String model_dir = getModelPathFromPath(this.path);
File [] subdirs = (new File(model_dir)).listFiles();
long latest_ms = 0;
File latest_file = null;
for (File subdir:subdirs) if (subdir.isDirectory()) {
File [] file_vers = subdir.listFiles();
for (File file:file_vers) if (file.isFile() && file.toString().endsWith(suffix)){
long modified = file.lastModified();
if (modified > latest_ms) {
latest_ms = modified;
latest_file = file;
}
}
}
if (latest_file != null) {
return latest_file.getPath();
}
return null;
}
public void updateLLA() {
Properties imp_prop = null;
......@@ -520,6 +598,41 @@ public class OrthoMap implements Comparable <OrthoMap>, Serializable{
return agl;
}
/**
* Get coordinates and altitude
* @return {latitude(deg), longitude(deg), altitude(m)}
*/
public double [] getLLA() {
return lla;
}
/**
* Get original image resolution as pixel size in meters
* @return image pixel size in meters
*/
public double getOrigPixMeters() {
return orig_pix_meters;
}
/**
* Get vertical point offset from the top-left corner of the original orthoimage in meters
* @return vertical point X,Y offset in meters from the top-left image corner
*/
public double [] getVertMeters() {
return vert_meters;
}
/**
* Get vertical point offset from the top-left corner of the original orthoimage in pixels
* of the original resolution
* @return vertical point X,Y offset in pixels from the top-left image corner in original resolution
*/
public int [] getVertPixels() {
return new int [] {
(int) Math.round(vert_meters[0]/orig_pix_meters),
(int) Math.round(vert_meters[0]/orig_pix_meters)};
}
public ImagePlus getOriginalImage(boolean show_markers) {
FloatImageData orig_image = getImageData();
......
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