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();
......
......@@ -14,6 +14,9 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
......@@ -33,10 +36,15 @@ import ij.ImagePlus;
import ij.ImageStack;
import ij.gui.PointRoi;
import ij.process.FloatPolygon;
import ij.text.TextWindow;
public class OrthoMapsCollection implements Serializable{
private static final long serialVersionUID = 1L;
public static final int MODE_IMAGE = 0;
public static final int MODE_ALT = 1;
public static final int MODE_MASK = 2;
public static final String [] KEY_DIRS= {"rootDirectory", // from EyesisCorrectionParameters
"sourceDirectory","linkedModels","videoDirectory","x3dDirectory","resultsDirectory","scenesDirectory",
"kernelsDirectory", "patternsDirectory"};
......@@ -195,6 +203,20 @@ public class OrthoMapsCollection implements Serializable{
}
}
public void updateNumberScenes() {
for (int n = 0; n < ortho_maps.length; n++) {
ortho_maps[n].num_scenes = -1;
ortho_maps[n].num_scenes = ortho_maps[n].getNumberScenes();
}
}
public void updateSfmGain() {
for (int n = 0; n < ortho_maps.length; n++) {
ortho_maps[n].sfm_gain = Double.NaN;
ortho_maps[n].sfm_gain = ortho_maps[n].getSfmGain();
}
}
/*
public static String[] getPathsFromSorceList(
String files_list) {
......@@ -461,14 +483,16 @@ public class OrthoMapsCollection implements Serializable{
public ImagePlus renderMulti (
String title,
boolean use_alt,
// boolean use_alt,
int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask
boolean show_centers,
int zoom_level,
int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct
int [] origin){
return renderMulti (
title, // String title,
use_alt, // boolean use_alt,
// use_alt, // boolean use_alt,'
mode, // int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask
null, // int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
false, // bounds_to_indices, // boolean bounds_to_indices,
temp_mode, // int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct
......@@ -481,7 +505,8 @@ public class OrthoMapsCollection implements Serializable{
public ImagePlus renderMulti (
String title,
boolean use_alt,
// boolean use_alt,
int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask
int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
boolean bounds_to_indices,
int temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct
......@@ -491,10 +516,10 @@ public class OrthoMapsCollection implements Serializable{
int zoom_level,
int [] origin){
int [] wh = new int[2];
// boolean bounds_to_indices = true;
double [][] centers = new double [(indices !=null)? indices.length: ortho_maps.length][];
float [][] multi = renderMulti (
use_alt, // boolean use_alt,
// use_alt, // boolean use_alt,
mode, // int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask
indices, // int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
bounds_to_indices, // boolean bounds_to_indices,
affines, // double [][][] affines, // null or [indices.length][2][3]
......@@ -504,8 +529,7 @@ public class OrthoMapsCollection implements Serializable{
origin, // int [] origin){ // maps[0] as a reference
centers); // double [][] centers)
int num_images = (indices != null)? indices.length : ortho_maps.length;
// String [] map_names = new String[(indices != null) ? indices.length : ortho_maps.length];
String [] map_names = new String[num_images + ((num_images==2)? 1 : 0)];
String [] map_names = new String[num_images + (((num_images==2) && (mode == MODE_IMAGE))? 1 : 0)];
float [][] extra_multi = new float [map_names.length][];
for (int n = 0; n <num_images; n++) {
int mapn= (indices != null)? indices[n] : n;
......@@ -513,10 +537,10 @@ public class OrthoMapsCollection implements Serializable{
map_names[n] += String.format(" raw=%7.1f", ortho_maps[mapn].getTemperature());
extra_multi[n] = multi[n];
}
if (map_names.length>num_images) { // inefficient way, only for display
if (map_names.length > num_images) { // inefficient way, only for display
// correct(offset) pixel values relative to multi[0]
int map0= (indices != null)? indices[0] : 0;
if (!use_alt) {
if (mode == MODE_IMAGE) {
for (int n = 1; n < num_images; n++) {
//temp_mode, // 0 - do nothing, 1 - equalize average,2 - try to correct
int mapn= (indices != null)? indices[n] : n;
......@@ -542,12 +566,29 @@ public class OrthoMapsCollection implements Serializable{
extra_multi[num_images][i] = extra_multi[1][i]-extra_multi[0][i];
}
}
ImageStack stack = ShowDoubleFloatArrays.makeStack(
ImageStack stack;
if (mode == MODE_MASK) {
title +="-MASK";
byte [][] byte_pix = new byte[multi.length][]; // multi[0].length];
for (int n = 0; n < multi.length; n++) { // slow
byte_pix[n] = new byte[multi[n].length];
for (int i = 0; i < multi[n].length; i++) {
byte_pix[n][i] = (byte) (Float.isNaN(multi[n][i]) ? 0 : 0xff);
}
}
stack = ShowDoubleFloatArrays.makeStack(
byte_pix,
wh[0],
wh[1],
map_names);
} else {
stack = ShowDoubleFloatArrays.makeStack(
extra_multi,
wh[0],
wh[1],
map_names,
false);
}
ImagePlus imp = new ImagePlus(title, stack);
if (show_centers) {
PointRoi roi = new PointRoi();
......@@ -575,14 +616,15 @@ public class OrthoMapsCollection implements Serializable{
* @return
*/
public float [][] renderMulti (
boolean use_alt,
// OrthoMap [] maps,
// boolean use_alt,
int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask
int zoom_level,
int [] wh,
int [] origin, // maps[0] as a reference
double [][] centers){
return renderMulti (
use_alt, // boolean use_alt,
// use_alt, // boolean use_alt,
mode, // int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask
null, // int [] indices,
false, // boolean bounds_to_indices,
null, // double [][][] affines,
......@@ -594,7 +636,8 @@ public class OrthoMapsCollection implements Serializable{
}
public float [][] renderMulti (
boolean use_alt,
// boolean use_alt,
int mode, // 0 - regular image, 1 - altitudes, 2 - black/white mask
int [] indices, // null or which indices to use (normally just 2 for pairwise comparison)
boolean bounds_to_indices,
double [][][] affines, // null or [indices.length][2][3]
......@@ -603,6 +646,7 @@ public class OrthoMapsCollection implements Serializable{
int [] wh,
int [] origin, // maps[0] as a reference
double [][] centers){
final boolean use_alt = mode == MODE_ALT;
final int dbg_x=2783, dbg_y=-5228;
int [][] bounds = getBoundsPixels( // should be for rectified, {-bounds[0][0], -bounds[0][1]} - exact center
zoom_level,
......@@ -1737,7 +1781,7 @@ public class OrthoMapsCollection implements Serializable{
// double [][] filt_elongation = {{1.5,1.5},{1.7,1.7}}; // [second/main][full/half] ellipse axis ratio
double [][] filt_elongation = {{1.7,1.7},{1.7,1.7}}; // [second/main][full/half] ellipse axis ratio
double filt_other_rad = 25; // should be no disconnected high peaks in this radius (only for halves multiplied)
double [] filt_other_frac = {0.8,0.8}; // no pixels around max at filt_other_rad should be higher than this fraction of max
double [] filt_other_frac = {0.8,0.68}; // -.8}; // no pixels around max at filt_other_rad should be higher than this fraction of max
// double [] filt_dist = {8.0,5.0}; // full offset and perpendicular to images offsets
// make conditional distance - decrease if small offset (increase for large to accommodate +30/-10cm
......@@ -3017,5 +3061,97 @@ public class OrthoMapsCollection implements Serializable{
}
}
public boolean showScenesStats(boolean select_all) {
String [] lines = new String [ortho_maps.length];
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss.SS zzz");// may be VV instead of zzz
String time_zone_name = "Europe/Kyiv";
for (int indx = 0; indx < ortho_maps.length; indx++) {
OrthoMap map = ortho_maps[indx];
LocalDateTime ldt = map.getLocalDateTime();
ZonedDateTime zonedUTC = ldt.atZone(ZoneId.of("UTC")); // that time is UTC
ZonedDateTime zonedDateTime = zonedUTC.withZoneSameInstant(ZoneId.of("Europe/Kyiv"));
String sdt = zonedDateTime.format(formatter);
String name = map.getName();
double agl = map.getAGL();
lines[indx]=String.format(
"%3d %17s %26s %6.2f",indx, name, sdt, agl);
}
boolean [] selection = new boolean [lines.length];
if (select_all) {
Arrays.fill(selection, true);
}
select_all = false;
GenericJTabbedDialog gd = new GenericJTabbedDialog("Select scenes to generate stats ",1200,1000);
gd.addCheckbox ("Select all maps", select_all, "Select all scenes, reopen this dialog.");
for (int i = 0; i < lines.length; i++) {
gd.addCheckbox (lines[i], selection[i], "Select scene number "+i);
}
gd.showDialog();
if (gd.wasCanceled()) return false;
select_all= gd.getNextBoolean();
if (select_all) {
return showScenesStats(select_all);
}
int num_sel = 0;
for (int i = 0; i < selection.length; i++) {
selection[i] = gd.getNextBoolean();
if (selection[i]) {
num_sel++;
}
}
int [] indices = new int [num_sel];
int indx=0;
for (int i = 0; i < selection.length; i++) if (selection[i]) {
indices[indx++] = i;
}
String [] stats = getScenesStats(indices, time_zone_name); // int [] indices)
new TextWindow("Ortho_images_stats", stats[0], stats[1], 1250,1000);
return true;
}
public String[] getScenesStats(int [] indices, String time_zone_name) {
if (indices == null) {
indices = new int [ortho_maps.length];
for (int i = 0; i < indices.length; i++) {
indices[i] = i;
}
}
String [] stats = new String[2]; // header, body
StringBuffer sb = new StringBuffer();
// String head_fmt = "%3s\t%17s\t%26s\t%13s\t%13s\t%7s\t%6s\t%7s\t%6s\t%6s\t%6s\t%6s\n";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss.SS zzz");// may be VV instead of zzz
//
stats [0] = String.format(
"%3s\t%17s\t%26s\t%11s\t%11s\t%7s\t"+
"%6s\t%7s\t%6s\t%6s\t%6s\t%6s\t"+
"%6s\t%6s",
"#", "timestamp", "date/time", "latitude", "longitude", "GND-ASL",
"AGL","pix(cm)", "width", "height","vert_x","vert_y",
"scenes", "sfm");
for (int indx:indices) {
OrthoMap map = ortho_maps[indx];
LocalDateTime ldt = map.getLocalDateTime();
ZonedDateTime zonedUTC = ldt.atZone(ZoneId.of("UTC")); // that time is UTC
ZonedDateTime zonedDateTime = zonedUTC.withZoneSameInstant(ZoneId.of(time_zone_name));
String sdt = zonedDateTime.format(formatter);
String name = map.getName();
double [] lla = map.getLLA();
double agl = map.getAGL();
double pix_size_cm = 100*map.getOrigPixMeters();
int width = map.getWidth();
int height = map.getHeight();
int [] vert_pix = map.getVertPixels();
double sfm_gain = map.getSfmGain();
int scenes = map.getNumberScenes();
sb.append(String.format(
"%3d\t%17s\t%26s\t%11.6f\t%11.6f\t%7.2f\t"+
"%6.2f\t%7.4f\t%6d\t%6d\t%6d\t%6d\t"+
"%6d\t%6.2f\n",
indx, name, sdt, lla[0], lla[1], lla[2] - agl,// ground level
agl,pix_size_cm, width, height,vert_pix[0],vert_pix[1],
scenes, sfm_gain));
}
stats[1] = sb.toString();
return stats;
}
}
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