Commit af9b88ff authored by Andrey Filippov's avatar Andrey Filippov

Implemented configurable parameters for ground plane rendering. Added

disabling ERS in the inter-scene LMA if there is not enough data (not in
all 4 quadrants)
parent 4e3cc252
...@@ -466,6 +466,24 @@ public class CLTParameters { ...@@ -466,6 +466,24 @@ public class CLTParameters {
public boolean gltf_emissive = false; // true; // Use emissive textures public boolean gltf_emissive = false; // true; // Use emissive textures
public boolean gltf_alpha_blend = false; // true; // Use alpha blend (false - opaque) public boolean gltf_alpha_blend = false; // true; // Use alpha blend (false - opaque)
// parameters for ground maps generation
public boolean gmap_render_hdr = true; // generate textures w/o normalization to generate undistorted
public boolean gmap_en = true; // generate ground map from a drone (enables gmap_render_hdr)
// extracting ground projection plane
public boolean gmap_use_lma = true; // ;
public double gmap_discard_low = 0.01; // fraction of all pixels
public double gmap_discard_high = 0.5; // fraction of all pixels
public double gmap_discard_adisp = 0.2; // discard above/below this fraction of average height
public double gmap_discard_rdisp = 0.02; // discard above/below this fraction of average height
public double gmap_pix_size = 0.005; // hdr_x0y0, // in meters
public int gmap_max_image_width = 4000; // 3200; // increase pixel size as a power of 2 until image fits
public boolean gmap_crop_empty = true;
public int gmap_crop_extra = 20;
public int [] gmap_tex_pals = {0,1,2};
public boolean show_textures = true; // show generated textures public boolean show_textures = true; // show generated textures
public boolean debug_filters = false;// show intermediate results of filtering public boolean debug_filters = false;// show intermediate results of filtering
...@@ -1592,6 +1610,19 @@ public class CLTParameters { ...@@ -1592,6 +1610,19 @@ public class CLTParameters {
properties.setProperty(prefix+"gltf_emissive", this.gltf_emissive+""); properties.setProperty(prefix+"gltf_emissive", this.gltf_emissive+"");
properties.setProperty(prefix+"gltf_alpha_blend", this.gltf_alpha_blend+""); properties.setProperty(prefix+"gltf_alpha_blend", this.gltf_alpha_blend+"");
properties.setProperty(prefix+"gmap_render_hdr", this.gmap_render_hdr+""); // boolean
properties.setProperty(prefix+"gmap_en", this.gmap_en+""); // boolean
properties.setProperty(prefix+"gmap_use_lma", this.gmap_use_lma+""); // boolean
properties.setProperty(prefix+"gmap_discard_low", this.gmap_discard_low+""); // double
properties.setProperty(prefix+"gmap_discard_high", this.gmap_discard_high+""); // double
properties.setProperty(prefix+"gmap_discard_adisp", this.gmap_discard_adisp+""); // double
properties.setProperty(prefix+"gmap_discard_rdisp", this.gmap_discard_rdisp+""); // double
properties.setProperty(prefix+"gmap_pix_size", this.gmap_pix_size+""); // double
properties.setProperty(prefix+"gmap_max_image_width", this.gmap_max_image_width+""); // int
properties.setProperty(prefix+"gmap_crop_empty", this.gmap_crop_empty+""); // boolean
properties.setProperty(prefix+"gmap_crop_extra", this.gmap_crop_extra+""); // int
properties.setProperty(prefix+"gmap_tex_pals", CLTParameters.arr_to_str(this.gmap_tex_pals)); // int[]
properties.setProperty(prefix+"show_textures", this.show_textures+""); properties.setProperty(prefix+"show_textures", this.show_textures+"");
properties.setProperty(prefix+"debug_filters", this.debug_filters+""); properties.setProperty(prefix+"debug_filters", this.debug_filters+"");
...@@ -2595,6 +2626,19 @@ public class CLTParameters { ...@@ -2595,6 +2626,19 @@ public class CLTParameters {
if (properties.getProperty(prefix+"gltf_emissive")!=null) this.gltf_emissive=Boolean.parseBoolean(properties.getProperty(prefix+"gltf_emissive")); if (properties.getProperty(prefix+"gltf_emissive")!=null) this.gltf_emissive=Boolean.parseBoolean(properties.getProperty(prefix+"gltf_emissive"));
if (properties.getProperty(prefix+"gltf_alpha_blend")!=null) this.gltf_alpha_blend=Boolean.parseBoolean(properties.getProperty(prefix+"gltf_alpha_blend")); if (properties.getProperty(prefix+"gltf_alpha_blend")!=null) this.gltf_alpha_blend=Boolean.parseBoolean(properties.getProperty(prefix+"gltf_alpha_blend"));
if (properties.getProperty(prefix+"gmap_render_hdr")!=null) this.gmap_render_hdr=Boolean.parseBoolean(properties.getProperty(prefix+ "gmap_render_hdr"));
if (properties.getProperty(prefix+"gmap_en")!=null) this.gmap_en=Boolean.parseBoolean(properties.getProperty(prefix+ "gmap_en"));
if (properties.getProperty(prefix+"gmap_use_lma")!=null) this.gmap_use_lma=Boolean.parseBoolean(properties.getProperty(prefix+ "gmap_use_lma"));
if (properties.getProperty(prefix+"gmap_discard_low")!=null) this.gmap_discard_low=Double.parseDouble(properties.getProperty(prefix+ "gmap_discard_low"));
if (properties.getProperty(prefix+"gmap_discard_high")!=null) this.gmap_discard_high=Double.parseDouble(properties.getProperty(prefix+ "gmap_discard_high"));
if (properties.getProperty(prefix+"gmap_discard_adisp")!=null) this.gmap_discard_adisp=Double.parseDouble(properties.getProperty(prefix+ "gmap_discard_adisp"));
if (properties.getProperty(prefix+"gmap_discard_rdisp")!=null) this.gmap_discard_rdisp=Double.parseDouble(properties.getProperty(prefix+ "gmap_discard_rdisp"));
if (properties.getProperty(prefix+"gmap_pix_size")!=null) this.gmap_pix_size=Double.parseDouble(properties.getProperty(prefix+ "gmap_pix_size"));
if (properties.getProperty(prefix+"gmap_max_image_width")!=null) this.gmap_max_image_width=Integer.parseInt(properties.getProperty(prefix+ "gmap_max_image_width"));
if (properties.getProperty(prefix+"gmap_crop_empty")!=null) this.gmap_crop_empty=Boolean.parseBoolean(properties.getProperty(prefix+ "gmap_crop_empty"));
if (properties.getProperty(prefix+"gmap_crop_extra")!=null) this.gmap_crop_extra=Integer.parseInt(properties.getProperty(prefix+ "gmap_crop_extra"));// int
if (properties.getProperty(prefix+"gmap_tex_pals")!=null) this.gmap_tex_pals=CLTParameters.str_to_iarr(properties.getProperty(prefix+"gmap_tex_pals"));
if (properties.getProperty(prefix+"show_textures")!=null) this.show_textures=Boolean.parseBoolean(properties.getProperty(prefix+"show_textures")); if (properties.getProperty(prefix+"show_textures")!=null) this.show_textures=Boolean.parseBoolean(properties.getProperty(prefix+"show_textures"));
if (properties.getProperty(prefix+"debug_filters")!=null) this.debug_filters=Boolean.parseBoolean(properties.getProperty(prefix+"debug_filters")); if (properties.getProperty(prefix+"debug_filters")!=null) this.debug_filters=Boolean.parseBoolean(properties.getProperty(prefix+"debug_filters"));
...@@ -3827,6 +3871,33 @@ public class CLTParameters { ...@@ -3827,6 +3871,33 @@ public class CLTParameters {
gd.addMessage ("glTF export"); gd.addMessage ("glTF export");
gd.addCheckbox ("glTF use emissive textures", this.gltf_emissive); gd.addCheckbox ("glTF use emissive textures", this.gltf_emissive);
gd.addCheckbox ("glTF use alpha blend", this.gltf_alpha_blend); gd.addCheckbox ("glTF use alpha blend", this.gltf_alpha_blend);
gd.addMessage ("Ground map export");
gd.addCheckbox ("Generate/save linear 32-bit textures", this.gmap_render_hdr, // true; // enable change FG pixel to opaque from transparent
"Generate and save textures w/o normalization as 32-bit Tiff files. This option will be automatically activated if ground plane maps are used.");
gd.addCheckbox ("Render ground-plane maps", this.gmap_en, // true; // enable change FG pixel to opaque from transparent
"Render fixed-scale projection of the 3D model to a ground plane, such as for the UAS-generated imagery.");
gd.addCheckbox ("Use only LMA disparity for ground", this.gmap_use_lma, // true; // enable change FG pixel to opaque from transparent
"Use only LMA-generated disparity to find the ground plane to project the map.");
gd.addNumericField("Discard low fraction", this.gmap_discard_low, 4,6,"",
"Discard lowest tiles (ditches) up to this fraction of all available tiles when finding the ground plane for the map projection.");
gd.addNumericField("Discard high fraction", this.gmap_discard_high, 4,6,"",
"Discard highest tiles (vegetation, structure) up to this fraction of all available tiles when finding the ground plane for the map projection.");
gd.addNumericField("Disparity absolute range", this.gmap_discard_adisp, 4,6,"",
"Discard tiles with the absolute value of the absolute disparity difference to the ground plane exceeds this value.");
gd.addNumericField("Disparity absolute range", this.gmap_discard_rdisp, 4,6,"",
"Discard tiles with the absolute value of the relative (to the ground plane disparity) disparity difference to the ground plane exceeds this value.");
gd.addNumericField("Rendered map pixel size", this.gmap_pix_size, 4,6,"m",
"Rendered absolute pixel size in meters.");
gd.addNumericField("Maximal rendered image width", this.gmap_max_image_width, 0,3,"",
"Maximal output image size in pixels. Increase pixel size in the power-of-two ratio if calculated image width exceeds this value.");
gd.addCheckbox ("Crop empty map areas", this.gmap_crop_empty, // true; // enable change FG pixel to opaque from transparent
"Crop the map output from four directions while only undefined pixels are removed.");
gd.addNumericField("Crop maps extra", this.gmap_crop_extra, 0,3,"pix", // minimal neighbors to keep alpha
"Additionally crop map by this number of pixels from each of the four directions.");
gd.addStringField ("LWIR palettes to render the maps", CLTParameters.arr_to_str(this.gmap_tex_pals), 40,
"Enter space-separated list of the palette numbers, such as, such as '0 1 2'");
gd.addMessage ("Earlier 3D generation parameters"); gd.addMessage ("Earlier 3D generation parameters");
gd.addCheckbox ("Show generated textures", this.show_textures); gd.addCheckbox ("Show generated textures", this.show_textures);
...@@ -5027,6 +5098,20 @@ public class CLTParameters { ...@@ -5027,6 +5098,20 @@ public class CLTParameters {
this.gltf_emissive= gd.getNextBoolean(); this.gltf_emissive= gd.getNextBoolean();
this.gltf_alpha_blend= gd.getNextBoolean(); this.gltf_alpha_blend= gd.getNextBoolean();
this.gmap_render_hdr= gd.getNextBoolean();
this.gmap_en= gd.getNextBoolean();
this.gmap_use_lma= gd.getNextBoolean();
this.gmap_discard_low= gd.getNextNumber();
this.gmap_discard_high= gd.getNextNumber();
this.gmap_discard_adisp= gd.getNextNumber();
this.gmap_discard_rdisp= gd.getNextNumber();
gmap_pix_size= gd.getNextNumber();
this.gmap_max_image_width= (int) gd.getNextNumber();
this.gmap_crop_empty= gd.getNextBoolean();
this.gmap_crop_extra= (int) gd.getNextNumber();
this.gmap_tex_pals = CLTParameters.str_to_iarr(gd.getNextString());
this.show_textures= gd.getNextBoolean(); this.show_textures= gd.getNextBoolean();
this.debug_filters= gd.getNextBoolean(); this.debug_filters= gd.getNextBoolean();
this.min_smth= gd.getNextNumber(); this.min_smth= gd.getNextNumber();
...@@ -5889,4 +5974,98 @@ public class CLTParameters { ...@@ -5889,4 +5974,98 @@ public class CLTParameters {
} }
return true; return true;
} }
// conversion of multiple parameters in a line
public static String arr_to_str(int [] arr) {
String s = "";
for (int c:arr) s+=c+" ";
return s.trim();
}
public static String arr_to_str(double [] arr) {
String s = "";
for (double c:arr) s+=c+" ";
return s.trim();
}
public static String arr_to_str(boolean [] arr) {
String s = "";
for (boolean c:arr) s+= (c?1:0)+" ";
return s.trim();
}
public static String arr_to_str(String [] arr) {
String s = "";
for (int i = 0; i < arr.length; i++) {
s += arr[i].trim();
if (i < (arr.length - 1)){
s += ",";
}
}
return s;
}
public static boolean [] str_to_barr(String s) {
int [] iarr = str_to_iarr(s);
if (iarr == null) return null;
boolean [] barr = new boolean [iarr.length];
for (int i = 0; i < barr.length; i++) {
barr[i] = iarr[i] != 0;
}
return barr;
}
public static int [] str_to_iarr(String s) {
String [] sa;
if (s.indexOf(",") >= 0) {
sa = s.trim().split(",");
} else {
sa = s.trim().split(" ");
}
int [] iarr = new int [sa.length];
for (int i = 0; i < sa.length; i++) {
iarr[i]=Integer.parseInt(sa[i].trim());
}
return iarr;
}
public static double [] str_to_darr(String s) {
String [] sa;
if (s.indexOf(",") >= 0) {
sa = s.trim().split(",");
} else {
sa = s.trim().split(" ");
}
double [] darr = new double [sa.length];
for (int i = 0; i < sa.length; i++) {
darr[i]=Double.parseDouble(sa[i].trim());
}
return darr;
}
public static String [] str_to_sarr(String s) {
String [] sa;
if (s.indexOf(",") >= 0) {
sa = s.trim().split(",");
} else {
sa = s.trim().split(" ");
}
String [] sarr = new String [sa.length];
for (int i = 0; i < sa.length; i++) {
sarr[i]=sa[i].trim();
}
return sarr;
}
} }
\ No newline at end of file
...@@ -30,6 +30,7 @@ import java.io.File; ...@@ -30,6 +30,7 @@ import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.util.Properties; import java.util.Properties;
import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.common.GenericJTabbedDialog; import com.elphel.imagej.common.GenericJTabbedDialog;
import com.elphel.imagej.readers.EyesisTiff; import com.elphel.imagej.readers.EyesisTiff;
...@@ -106,18 +107,18 @@ public class LwirReaderParameters { ...@@ -106,18 +107,18 @@ public class LwirReaderParameters {
} }
public int [] getLwirChannels(boolean absolote) { public int [] getLwirChannels(boolean absolute) {
int [] absolute_chn = new int [lwir_channels.length]; int [] absolute_chn = new int [lwir_channels.length];
for (int i = 0; i < absolute_chn.length; i++) { for (int i = 0; i < absolute_chn.length; i++) {
absolute_chn[i] = lwir_channels[i] + (absolote? getLwirChn0() : 0); absolute_chn[i] = lwir_channels[i] + (absolute? getLwirChn0() : 0);
} }
return absolute_chn; return absolute_chn;
} }
public int [] getEoChannels(boolean absolote) { public int [] getEoChannels(boolean absolute) {
int [] absolute_chn = new int [eo_channels.length]; int [] absolute_chn = new int [eo_channels.length];
for (int i = 0; i < absolute_chn.length; i++) { for (int i = 0; i < absolute_chn.length; i++) {
absolute_chn[i] = eo_channels[i] + (absolote? getEoChn0():0); absolute_chn[i] = eo_channels[i] + (absolute? getEoChn0():0);
} }
return absolute_chn; return absolute_chn;
} }
...@@ -297,10 +298,10 @@ public class LwirReaderParameters { ...@@ -297,10 +298,10 @@ public class LwirReaderParameters {
properties.setProperty(prefix+"ffc_groups", this.ffc_groups+""); properties.setProperty(prefix+"ffc_groups", this.ffc_groups+"");
properties.setProperty(prefix+"acquire_delay", this.acquire_delay+""); properties.setProperty(prefix+"acquire_delay", this.acquire_delay+"");
properties.setProperty(prefix+"avg_all", this.avg_all+""); properties.setProperty(prefix+"avg_all", this.avg_all+"");
properties.setProperty(prefix+"lwir_ips", arr_to_str(this.lwir_ips)); // this.lwir_ip+"");; this.lwir_ip+""); properties.setProperty(prefix+"lwir_ips", CLTParameters.arr_to_str(this.lwir_ips)); // this.lwir_ip+"");; this.lwir_ip+"");
properties.setProperty(prefix+"eo_ip", this.eo_ip+""); properties.setProperty(prefix+"eo_ip", this.eo_ip+"");
properties.setProperty(prefix+"lwir_channels", arr_to_str(this.lwir_channels)); properties.setProperty(prefix+"lwir_channels", CLTParameters.arr_to_str(this.lwir_channels));
properties.setProperty(prefix+"eo_channels", arr_to_str(this.eo_channels)); properties.setProperty(prefix+"eo_channels", CLTParameters.arr_to_str(this.eo_channels));
properties.setProperty(prefix+"lwir_telemetry", this.lwir_telemetry+""); properties.setProperty(prefix+"lwir_telemetry", this.lwir_telemetry+"");
properties.setProperty(prefix+"eo_full_window", this.eo_full_window+""); properties.setProperty(prefix+"eo_full_window", this.eo_full_window+"");
properties.setProperty(prefix+"eo_quality", this.eo_quality+""); properties.setProperty(prefix+"eo_quality", this.eo_quality+"");
...@@ -312,14 +313,14 @@ public class LwirReaderParameters { ...@@ -312,14 +313,14 @@ public class LwirReaderParameters {
properties.setProperty(prefix+"eo_gain_g", this.eo_gain_g+""); properties.setProperty(prefix+"eo_gain_g", this.eo_gain_g+"");
properties.setProperty(prefix+"eo_gain_rg", this.eo_gain_rg+""); properties.setProperty(prefix+"eo_gain_rg", this.eo_gain_rg+"");
properties.setProperty(prefix+"eo_gain_bg", this.eo_gain_bg+""); properties.setProperty(prefix+"eo_gain_bg", this.eo_gain_bg+"");
properties.setProperty(prefix+"eo_exp_corr", arr_to_str(this.eo_exp_corr)); properties.setProperty(prefix+"eo_exp_corr", CLTParameters.arr_to_str(this.eo_exp_corr));
properties.setProperty(prefix+"eo_gcorr_rbgb", arr_to_str(this.eo_gcorr_rbgb)); properties.setProperty(prefix+"eo_gcorr_rbgb", CLTParameters.arr_to_str(this.eo_gcorr_rbgb));
properties.setProperty(prefix+"lwir_trig_dly", this.lwir_trig_dly+""); properties.setProperty(prefix+"lwir_trig_dly", this.lwir_trig_dly+"");
properties.setProperty(prefix+"eo_lag", this.eo_lag+""); properties.setProperty(prefix+"eo_lag", this.eo_lag+"");
properties.setProperty(prefix+"max_mismatch_ms", this.max_mismatch_ms+""); properties.setProperty(prefix+"max_mismatch_ms", this.max_mismatch_ms+"");
properties.setProperty(prefix+"max_frame_diff", this.max_frame_diff+""); properties.setProperty(prefix+"max_frame_diff", this.max_frame_diff+"");
properties.setProperty(prefix+"debug_level", this.debug_level+""); properties.setProperty(prefix+"debug_level", this.debug_level+"");
properties.setProperty(prefix+"selected_channels", arr_to_str(this.selected_channels)); properties.setProperty(prefix+"selected_channels", CLTParameters.arr_to_str(this.selected_channels));
properties.setProperty(prefix+"show_images", this.show_images+""); properties.setProperty(prefix+"show_images", this.show_images+"");
} }
...@@ -334,7 +335,7 @@ public class LwirReaderParameters { ...@@ -334,7 +335,7 @@ public class LwirReaderParameters {
setDefaultChannels(); // modifies lwir_IPs, eo_ip, channels, setDefaultChannels(); // modifies lwir_IPs, eo_ip, channels,
} }
if (properties.getProperty(prefix+"vnir_ip")!=null) this.eo_ip= properties.getProperty(prefix+"vnir_ip"); if (properties.getProperty(prefix+"vnir_ip")!=null) this.eo_ip= properties.getProperty(prefix+"vnir_ip");
if (properties.getProperty(prefix+"vnir_channels")!=null) this.eo_channels=str_to_iarr(properties.getProperty(prefix+"vnir_channels")); if (properties.getProperty(prefix+"vnir_channels")!=null) this.eo_channels=CLTParameters.str_to_iarr(properties.getProperty(prefix+"vnir_channels"));
if (properties.getProperty(prefix+"vnir_quality")!=null) this.eo_quality=Double.parseDouble(properties.getProperty(prefix+"vnir_quality")); if (properties.getProperty(prefix+"vnir_quality")!=null) this.eo_quality=Double.parseDouble(properties.getProperty(prefix+"vnir_quality"));
if (properties.getProperty(prefix+"vnir_scale")!=null) this.eo_scale= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_scale")); if (properties.getProperty(prefix+"vnir_scale")!=null) this.eo_scale= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_scale"));
if (properties.getProperty(prefix+"vnir_autoexp")!=null) this.eo_autoexp= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_autoexp")); if (properties.getProperty(prefix+"vnir_autoexp")!=null) this.eo_autoexp= Boolean.parseBoolean(properties.getProperty(prefix+"vnir_autoexp"));
...@@ -344,8 +345,8 @@ public class LwirReaderParameters { ...@@ -344,8 +345,8 @@ public class LwirReaderParameters {
if (properties.getProperty(prefix+"vnir_gain_g")!=null) this.eo_gain_g=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_g")); if (properties.getProperty(prefix+"vnir_gain_g")!=null) this.eo_gain_g=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_g"));
if (properties.getProperty(prefix+"vnir_gain_rg")!=null) this.eo_gain_rg=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_rg")); if (properties.getProperty(prefix+"vnir_gain_rg")!=null) this.eo_gain_rg=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_rg"));
if (properties.getProperty(prefix+"vnir_gain_bg")!=null) this.eo_gain_bg=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_bg")); if (properties.getProperty(prefix+"vnir_gain_bg")!=null) this.eo_gain_bg=Double.parseDouble(properties.getProperty(prefix+"vnir_gain_bg"));
if (properties.getProperty(prefix+"vnir_exp_corr")!=null) this.eo_exp_corr=str_to_darr(properties.getProperty(prefix+"vnir_exp_corr")); if (properties.getProperty(prefix+"vnir_exp_corr")!=null) this.eo_exp_corr=CLTParameters.str_to_darr(properties.getProperty(prefix+"vnir_exp_corr"));
if (properties.getProperty(prefix+"vnir_gcorr_rbgb")!=null) this.eo_gcorr_rbgb=str_to_darr(properties.getProperty(prefix+"vnir_gcorr_rbgb")); if (properties.getProperty(prefix+"vnir_gcorr_rbgb")!=null) this.eo_gcorr_rbgb=CLTParameters.str_to_darr(properties.getProperty(prefix+"vnir_gcorr_rbgb"));
if (properties.getProperty(prefix+"vnir_lag")!=null) this.eo_lag=Integer.parseInt(properties.getProperty(prefix+"vnir_lag")); // old version if (properties.getProperty(prefix+"vnir_lag")!=null) this.eo_lag=Integer.parseInt(properties.getProperty(prefix+"vnir_lag")); // old version
if (properties.getProperty(prefix+"avg_number")!=null) this.avg_number=Integer.parseInt(properties.getProperty(prefix+"avg_number")); if (properties.getProperty(prefix+"avg_number")!=null) this.avg_number=Integer.parseInt(properties.getProperty(prefix+"avg_number"));
if (properties.getProperty(prefix+"avg_number_eo")!=null) this.avg_number_eo=Integer.parseInt(properties.getProperty(prefix+"avg_number_eo")); if (properties.getProperty(prefix+"avg_number_eo")!=null) this.avg_number_eo=Integer.parseInt(properties.getProperty(prefix+"avg_number_eo"));
...@@ -357,10 +358,10 @@ public class LwirReaderParameters { ...@@ -357,10 +358,10 @@ public class LwirReaderParameters {
if (properties.getProperty(prefix+"acquire_delay")!=null) this.acquire_delay=Double.parseDouble(properties.getProperty(prefix+"acquire_delay")); if (properties.getProperty(prefix+"acquire_delay")!=null) this.acquire_delay=Double.parseDouble(properties.getProperty(prefix+"acquire_delay"));
if (properties.getProperty(prefix+"avg_all")!=null) this.avg_all= Boolean.parseBoolean(properties.getProperty(prefix+"avg_all")); if (properties.getProperty(prefix+"avg_all")!=null) this.avg_all= Boolean.parseBoolean(properties.getProperty(prefix+"avg_all"));
if (properties.getProperty(prefix+"lwir_ip")!=null) this.lwir_ips[0]= properties.getProperty(prefix+"lwir_ip"); if (properties.getProperty(prefix+"lwir_ip")!=null) this.lwir_ips[0]= properties.getProperty(prefix+"lwir_ip");
if (properties.getProperty(prefix+"lwir_ips")!=null) this.lwir_ips= str_to_sarr(properties.getProperty(prefix+"lwir_ips")); if (properties.getProperty(prefix+"lwir_ips")!=null) this.lwir_ips= CLTParameters.str_to_sarr(properties.getProperty(prefix+"lwir_ips"));
if (properties.getProperty(prefix+"eo_ip")!=null) this.eo_ip= properties.getProperty(prefix+"eo_ip"); if (properties.getProperty(prefix+"eo_ip")!=null) this.eo_ip= properties.getProperty(prefix+"eo_ip");
if (properties.getProperty(prefix+"lwir_channels")!=null) this.lwir_channels=str_to_iarr(properties.getProperty(prefix+"lwir_channels")); if (properties.getProperty(prefix+"lwir_channels")!=null) this.lwir_channels=CLTParameters.str_to_iarr(properties.getProperty(prefix+"lwir_channels"));
if (properties.getProperty(prefix+"eo_channels")!=null) this.eo_channels=str_to_iarr(properties.getProperty(prefix+"eo_channels")); if (properties.getProperty(prefix+"eo_channels")!=null) this.eo_channels=CLTParameters.str_to_iarr(properties.getProperty(prefix+"eo_channels"));
if (properties.getProperty(prefix+"lwir_telemetry")!=null) this.lwir_telemetry= Boolean.parseBoolean(properties.getProperty(prefix+"lwir_telemetry")); if (properties.getProperty(prefix+"lwir_telemetry")!=null) this.lwir_telemetry= Boolean.parseBoolean(properties.getProperty(prefix+"lwir_telemetry"));
if (properties.getProperty(prefix+"eo_full_window")!=null) this.eo_full_window= Boolean.parseBoolean(properties.getProperty(prefix+"eo_full_window")); if (properties.getProperty(prefix+"eo_full_window")!=null) this.eo_full_window= Boolean.parseBoolean(properties.getProperty(prefix+"eo_full_window"));
if (properties.getProperty(prefix+"eo_quality")!=null) this.eo_quality=Double.parseDouble(properties.getProperty(prefix+"eo_quality")); if (properties.getProperty(prefix+"eo_quality")!=null) this.eo_quality=Double.parseDouble(properties.getProperty(prefix+"eo_quality"));
...@@ -372,14 +373,14 @@ public class LwirReaderParameters { ...@@ -372,14 +373,14 @@ public class LwirReaderParameters {
if (properties.getProperty(prefix+"eo_gain_g")!=null) this.eo_gain_g=Double.parseDouble(properties.getProperty(prefix+"eo_gain_g")); if (properties.getProperty(prefix+"eo_gain_g")!=null) this.eo_gain_g=Double.parseDouble(properties.getProperty(prefix+"eo_gain_g"));
if (properties.getProperty(prefix+"eo_gain_rg")!=null) this.eo_gain_rg=Double.parseDouble(properties.getProperty(prefix+"eo_gain_rg")); if (properties.getProperty(prefix+"eo_gain_rg")!=null) this.eo_gain_rg=Double.parseDouble(properties.getProperty(prefix+"eo_gain_rg"));
if (properties.getProperty(prefix+"eo_gain_bg")!=null) this.eo_gain_bg=Double.parseDouble(properties.getProperty(prefix+"eo_gain_bg")); if (properties.getProperty(prefix+"eo_gain_bg")!=null) this.eo_gain_bg=Double.parseDouble(properties.getProperty(prefix+"eo_gain_bg"));
if (properties.getProperty(prefix+"eo_exp_corr")!=null) this.eo_exp_corr=str_to_darr(properties.getProperty(prefix+"eo_exp_corr")); if (properties.getProperty(prefix+"eo_exp_corr")!=null) this.eo_exp_corr=CLTParameters.str_to_darr(properties.getProperty(prefix+"eo_exp_corr"));
if (properties.getProperty(prefix+"eo_gcorr_rbgb")!=null) this.eo_gcorr_rbgb=str_to_darr(properties.getProperty(prefix+"eo_gcorr_rbgb")); if (properties.getProperty(prefix+"eo_gcorr_rbgb")!=null) this.eo_gcorr_rbgb=CLTParameters.str_to_darr(properties.getProperty(prefix+"eo_gcorr_rbgb"));
if (properties.getProperty(prefix+"lwir_trig_dly")!=null) this.lwir_trig_dly=Integer.parseInt(properties.getProperty(prefix+"lwir_trig_dly")); if (properties.getProperty(prefix+"lwir_trig_dly")!=null) this.lwir_trig_dly=Integer.parseInt(properties.getProperty(prefix+"lwir_trig_dly"));
if (properties.getProperty(prefix+"eo_lag")!=null) this.eo_lag=Integer.parseInt(properties.getProperty(prefix+"eo_lag")); if (properties.getProperty(prefix+"eo_lag")!=null) this.eo_lag=Integer.parseInt(properties.getProperty(prefix+"eo_lag"));
if (properties.getProperty(prefix+"max_mismatch_ms")!=null) this.max_mismatch_ms=Double.parseDouble(properties.getProperty(prefix+"max_mismatch_ms")); if (properties.getProperty(prefix+"max_mismatch_ms")!=null) this.max_mismatch_ms=Double.parseDouble(properties.getProperty(prefix+"max_mismatch_ms"));
if (properties.getProperty(prefix+"max_frame_diff")!=null) this.max_frame_diff=Integer.parseInt(properties.getProperty(prefix+"max_frame_diff")); if (properties.getProperty(prefix+"max_frame_diff")!=null) this.max_frame_diff=Integer.parseInt(properties.getProperty(prefix+"max_frame_diff"));
if (properties.getProperty(prefix+"debug_level")!=null) this.debug_level=Integer.parseInt(properties.getProperty(prefix+"debug_level")); if (properties.getProperty(prefix+"debug_level")!=null) this.debug_level=Integer.parseInt(properties.getProperty(prefix+"debug_level"));
if (properties.getProperty(prefix+"selected_channels")!=null) this.selected_channels=str_to_barr(properties.getProperty(prefix+"selected_channels")); if (properties.getProperty(prefix+"selected_channels")!=null) this.selected_channels=CLTParameters.str_to_barr(properties.getProperty(prefix+"selected_channels"));
if (properties.getProperty(prefix+"show_images")!=null) this.show_images= Boolean.parseBoolean(properties.getProperty(prefix+"show_images")); if (properties.getProperty(prefix+"show_images")!=null) this.show_images= Boolean.parseBoolean(properties.getProperty(prefix+"show_images"));
parameters_updated = true; parameters_updated = true;
} }
...@@ -492,8 +493,8 @@ public class LwirReaderParameters { ...@@ -492,8 +493,8 @@ public class LwirReaderParameters {
result = prime * result + ip.hashCode(); result = prime * result + ip.hashCode();
} }
result = prime * result + eo_ip.hashCode(); result = prime * result + eo_ip.hashCode();
result = prime * result + arr_to_str(lwir_channels).hashCode(); result = prime * result + CLTParameters.arr_to_str(lwir_channels).hashCode();
result = prime * result + arr_to_str(eo_channels).hashCode(); result = prime * result + CLTParameters.arr_to_str(eo_channels).hashCode();
result = prime * result + (lwir_telemetry?1:0); result = prime * result + (lwir_telemetry?1:0);
result = prime * result + (eo_full_window?1:0); result = prime * result + (eo_full_window?1:0);
result = prime * result + ((Double) eo_quality).hashCode(); result = prime * result + ((Double) eo_quality).hashCode();
...@@ -505,10 +506,10 @@ public class LwirReaderParameters { ...@@ -505,10 +506,10 @@ public class LwirReaderParameters {
result = prime * result + ((Double) eo_gain_g).hashCode(); result = prime * result + ((Double) eo_gain_g).hashCode();
result = prime * result + ((Double) eo_gain_rg).hashCode(); result = prime * result + ((Double) eo_gain_rg).hashCode();
result = prime * result + ((Double) eo_gain_bg).hashCode(); result = prime * result + ((Double) eo_gain_bg).hashCode();
result = prime * result + arr_to_str(eo_exp_corr).hashCode(); result = prime * result + CLTParameters.arr_to_str(eo_exp_corr).hashCode();
result = prime * result + arr_to_str(eo_gcorr_rbgb).hashCode(); result = prime * result + CLTParameters.arr_to_str(eo_gcorr_rbgb).hashCode();
result = prime * result + ((Integer) lwir_trig_dly).hashCode(); result = prime * result + ((Integer) lwir_trig_dly).hashCode();
result = prime * result + arr_to_str(selected_channels).hashCode(); result = prime * result + CLTParameters.arr_to_str(selected_channels).hashCode();
// next are not needed to be programmed to the cameras // next are not needed to be programmed to the cameras
// result = prime * result + (new Integer(eo_lag)).hashCode(); // result = prime * result + (new Integer(eo_lag)).hashCode();
// result = prime * result + (new Double(max_mismatch_ms)).hashCode(); // result = prime * result + (new Double(max_mismatch_ms)).hashCode();
...@@ -540,8 +541,8 @@ public class LwirReaderParameters { ...@@ -540,8 +541,8 @@ public class LwirReaderParameters {
gd.addStringField ("LWIR IP"+i, this.lwir_ips[i], 20, "LWIR camera "+(i+((i==0)?" (master)":""))+" IP address"); gd.addStringField ("LWIR IP"+i, this.lwir_ips[i], 20, "LWIR camera "+(i+((i==0)?" (master)":""))+" IP address");
} }
gd.addStringField ("EO IP", this.eo_ip, 20, "Visible range high resolution camera IP address"); gd.addStringField ("EO IP", this.eo_ip, 20, "Visible range high resolution camera IP address");
gd.addStringField ("LWIR channels", arr_to_str(this.lwir_channels), 40, "Space-separated list of used LWIR camera channels, such as '0 1 2 3'"); gd.addStringField ("LWIR channels", CLTParameters.arr_to_str(this.lwir_channels), 40, "Space-separated list of used LWIR camera channels, such as '0 1 2 3'");
gd.addStringField ("EO channels", arr_to_str(this.eo_channels), 20, "Space-separated list of used visible range camera channels, such as '0 1 2 3'"); gd.addStringField ("EO channels", CLTParameters.arr_to_str(this.eo_channels), 20, "Space-separated list of used visible range camera channels, such as '0 1 2 3'");
gd.addCheckbox ("LWIR telemetry",this.lwir_telemetry, "Set LWIR sesnors to provide telemetry data in the last 2 lines (may become mandatory later)"); gd.addCheckbox ("LWIR telemetry",this.lwir_telemetry, "Set LWIR sesnors to provide telemetry data in the last 2 lines (may become mandatory later)");
gd.addCheckbox ("EO full window",this.eo_full_window, "Set EO to full window, disregarding preset margins (need reset to restore original)"); gd.addCheckbox ("EO full window",this.eo_full_window, "Set EO to full window, disregarding preset margins (need reset to restore original)");
gd.addNumericField("EO quality", this.eo_quality, 3,6,"%", "Visible range camera JPEG compression quality (all channels)"); gd.addNumericField("EO quality", this.eo_quality, 3,6,"%", "Visible range camera JPEG compression quality (all channels)");
...@@ -553,14 +554,14 @@ public class LwirReaderParameters { ...@@ -553,14 +554,14 @@ public class LwirReaderParameters {
gd.addNumericField("EO gain G", this.eo_gain_g, 3,6,"","Analog gain for green channel for all visible range camera channels (normally 2.0)"); gd.addNumericField("EO gain G", this.eo_gain_g, 3,6,"","Analog gain for green channel for all visible range camera channels (normally 2.0)");
gd.addNumericField("EO gain R/G", this.eo_gain_rg, 3,6,"","Red to green gain ratio for all visible range camera channels"); gd.addNumericField("EO gain R/G", this.eo_gain_rg, 3,6,"","Red to green gain ratio for all visible range camera channels");
gd.addNumericField("EO gain B/G", this.eo_gain_bg, 3,6,"","Blue to green gain ratio for all visible range camera channels"); gd.addNumericField("EO gain B/G", this.eo_gain_bg, 3,6,"","Blue to green gain ratio for all visible range camera channels");
gd.addStringField ("EO exposure corrections", arr_to_str(this.eo_exp_corr), 50, "Fine corrections of channel exposures (4 channel relative exposures)"); gd.addStringField ("EO exposure corrections", CLTParameters.arr_to_str(this.eo_exp_corr), 50, "Fine corrections of channel exposures (4 channel relative exposures)");
gd.addStringField ("EO gain corrections", arr_to_str(this.eo_gcorr_rbgb), 100, "Fine corrections to per channel, per color gains:'r0 b0 gb0 r1 b1 gb1 ...'"); gd.addStringField ("EO gain corrections", CLTParameters.arr_to_str(this.eo_gcorr_rbgb), 100, "Fine corrections to per channel, per color gains:'r0 b0 gb0 r1 b1 gb1 ...'");
gd.addNumericField("LWIR trig dly", this.lwir_trig_dly, 0,10,"x10ns","Output trigger delay, should eventually match Lepton+FPGA latency to trigger EO exactly 1 frame after LWIR. 0 does not work with current FPGA - usec do not match sec in transmitted timestamp"); gd.addNumericField("LWIR trig dly", this.lwir_trig_dly, 0,10,"x10ns","Output trigger delay, should eventually match Lepton+FPGA latency to trigger EO exactly 1 frame after LWIR. 0 does not work with current FPGA - usec do not match sec in transmitted timestamp");
gd.addNumericField("EO lag", this.eo_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one"); gd.addNumericField("EO lag", this.eo_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one");
gd.addNumericField("Max mismatch", this.max_mismatch_ms, 3,6,"ms","Maximal mismatch between image timestamps. Larger mismatch requires LWIR sinsor reinitialization"); gd.addNumericField("Max mismatch", this.max_mismatch_ms, 3,6,"ms","Maximal mismatch between image timestamps. Larger mismatch requires LWIR sinsor reinitialization");
gd.addNumericField("Max frame diff",this.max_frame_diff, 0,3,"","Maximal difference in frames between simultaneously acquired channels as calculated from the timestamps"); gd.addNumericField("Max frame diff",this.max_frame_diff, 0,3,"","Maximal difference in frames between simultaneously acquired channels as calculated from the timestamps");
gd.addNumericField("Debug level", this.debug_level, 0,3,"","Image acquisition log level: -3: OFF, -2:FATAL, -1:ERROR, 0:WARN, 1:INFO, 2:DEBUG"); gd.addNumericField("Debug level", this.debug_level, 0,3,"","Image acquisition log level: -3: OFF, -2:FATAL, -1:ERROR, 0:WARN, 1:INFO, 2:DEBUG");
gd.addStringField ("Selected channels", arr_to_str(this.selected_channels), 40, "Space-separated channel selection (1 - selected, 0 - unselected)"); gd.addStringField ("Selected channels", CLTParameters.arr_to_str(this.selected_channels), 40, "Space-separated channel selection (1 - selected, 0 - unselected)");
gd.addCheckbox ("Show images", this.show_images, "Show acquired images after averaging)"); gd.addCheckbox ("Show images", this.show_images, "Show acquired images after averaging)");
} }
...@@ -582,8 +583,8 @@ public class LwirReaderParameters { ...@@ -582,8 +583,8 @@ public class LwirReaderParameters {
} }
this.eo_ip = gd.getNextString(); this.eo_ip = gd.getNextString();
this.lwir_channels = str_to_iarr(gd.getNextString()); this.lwir_channels = CLTParameters.str_to_iarr(gd.getNextString());
this.eo_channels = str_to_iarr(gd.getNextString()); this.eo_channels = CLTParameters.str_to_iarr(gd.getNextString());
this.lwir_telemetry = gd.getNextBoolean(); this.lwir_telemetry = gd.getNextBoolean();
this.eo_full_window = gd.getNextBoolean(); this.eo_full_window = gd.getNextBoolean();
this.eo_quality = gd.getNextNumber(); this.eo_quality = gd.getNextNumber();
...@@ -595,14 +596,14 @@ public class LwirReaderParameters { ...@@ -595,14 +596,14 @@ public class LwirReaderParameters {
this.eo_gain_g = gd.getNextNumber(); this.eo_gain_g = gd.getNextNumber();
this.eo_gain_rg = gd.getNextNumber(); this.eo_gain_rg = gd.getNextNumber();
this.eo_gain_bg = gd.getNextNumber(); this.eo_gain_bg = gd.getNextNumber();
this.eo_exp_corr = str_to_darr(gd.getNextString()); this.eo_exp_corr = CLTParameters.str_to_darr(gd.getNextString());
this.eo_gcorr_rbgb = str_to_darr(gd.getNextString()); this.eo_gcorr_rbgb = CLTParameters.str_to_darr(gd.getNextString());
this.lwir_trig_dly = (int) gd.getNextNumber(); this.lwir_trig_dly = (int) gd.getNextNumber();
this.eo_lag = (int) gd.getNextNumber(); this.eo_lag = (int) gd.getNextNumber();
this.max_mismatch_ms = gd.getNextNumber(); this.max_mismatch_ms = gd.getNextNumber();
this.max_frame_diff = (int) gd.getNextNumber(); this.max_frame_diff = (int) gd.getNextNumber();
this.debug_level = (int) gd.getNextNumber(); this.debug_level = (int) gd.getNextNumber();
this.selected_channels = str_to_barr(gd.getNextString()); this.selected_channels = CLTParameters.str_to_barr(gd.getNextString());
this.show_images = gd.getNextBoolean(); this.show_images = gd.getNextBoolean();
if (!this.camera_name.equals(new_camera_name)) { if (!this.camera_name.equals(new_camera_name)) {
this.camera_name = new_camera_name; // in the very end to to disturb the number of items this.camera_name = new_camera_name; // in the very end to to disturb the number of items
...@@ -706,7 +707,8 @@ public class LwirReaderParameters { ...@@ -706,7 +707,8 @@ public class LwirReaderParameters {
// --- internal methods // --- internal methods
// Moved as static methods to CLTParameters
/*
private String arr_to_str(int [] arr) { private String arr_to_str(int [] arr) {
String s = ""; String s = "";
for (int c:arr) s+=c+" "; for (int c:arr) s+=c+" ";
...@@ -789,7 +791,7 @@ public class LwirReaderParameters { ...@@ -789,7 +791,7 @@ public class LwirReaderParameters {
return sarr; return sarr;
} }
*/
public boolean [] selectSourceChannels(){ public boolean [] selectSourceChannels(){
return selectSourceChannels(selected_channels); return selectSourceChannels(selected_channels);
} }
......
...@@ -181,8 +181,12 @@ public class ErsCorrection extends GeometryCorrection { ...@@ -181,8 +181,12 @@ public class ErsCorrection extends GeometryCorrection {
static final int DP_DSX = 24; // dw_dx, (m) static final int DP_DSX = 24; // dw_dx, (m)
static final int DP_DSY = 25; // dw_dy, (m) static final int DP_DSY = 25; // dw_dy, (m)
static final int DP_DSZ = 26; // dw_dz}; (m) static final int DP_DSZ = 26; // dw_dz}; (m)
static final int DP_NUM_PARS = DP_DSZ+1; static final int DP_NUM_PARS = DP_DSZ+1;
static final int [] DP_ERS_INDICES=
{ DP_DVAZ, DP_DVTL, DP_DVRL,
DP_DVX, DP_DVY, DP_DVZ,
DP_DSVAZ, DP_DSVTL, DP_DSVRL,
DP_DSVX, DP_DSVY, DP_DSVZ};
static final RotationConvention ROT_CONV = RotationConvention.FRAME_TRANSFORM; static final RotationConvention ROT_CONV = RotationConvention.FRAME_TRANSFORM;
static final double THRESHOLD = 1E-10; static final double THRESHOLD = 1E-10;
static final double LINE_ERR = 0.001; // line accuracy for ERS when converting from world to pixels. static final double LINE_ERR = 0.001; // line accuracy for ERS when converting from world to pixels.
......
...@@ -33,6 +33,13 @@ public class IntersceneLmaParameters { ...@@ -33,6 +33,13 @@ public class IntersceneLmaParameters {
public double ilma_disparity_weight = 2.0; // disparity component weight compared to dX and dY public double ilma_disparity_weight = 2.0; // disparity component weight compared to dX and dY
public boolean ilma_3d_lma = false; // Use LMA for disparity in 3D pose matching mode public boolean ilma_3d_lma = false; // Use LMA for disparity in 3D pose matching mode
public boolean ilma_3d_tilt_only = true; // remove disparity average, use tilts only public boolean ilma_3d_tilt_only = true; // remove disparity average, use tilts only
public double ilma_per_scene = 1.0; // (Not yet used) disable ers terms if per-scene pixel offset is smaller
public boolean ilma_ers_quads = true; // Disable ERS fitting if not enough data
public double ilma_gap_frac = 0.25; // remove this center fraction of width/height when evaluating quads
public int ilma_min_quad_tiles = 10; // minimal number of defined tiles in each quad for using ERS
public double ilma_min_quad_weight = 0.01; // minimal fraction of total tiles weight in each quad for using ERS
public boolean ilma_thread_invariant = true; // Do not use DoubleAdder, provide results not dependent on threads public boolean ilma_thread_invariant = true; // Do not use DoubleAdder, provide results not dependent on threads
public boolean [] ilma_lma_select = new boolean [ErsCorrection.DP_NUM_PARS]; // first three will not be used public boolean [] ilma_lma_select = new boolean [ErsCorrection.DP_NUM_PARS]; // first three will not be used
public double [] ilma_regularization_weights = new double [ErsCorrection.DP_NUM_PARS]; // first three will not be used public double [] ilma_regularization_weights = new double [ErsCorrection.DP_NUM_PARS]; // first three will not be used
...@@ -116,13 +123,27 @@ public class IntersceneLmaParameters { ...@@ -116,13 +123,27 @@ public class IntersceneLmaParameters {
gd.addMessage("Interframe LMA parameters selection"); gd.addMessage("Interframe LMA parameters selection");
gd.addCheckbox ("3D mode (use disparity)", this.ilma_3d, gd.addCheckbox ("3D mode (use disparity)", this.ilma_3d,
"Use disparity for interscene matching (as for UAS imagery)" ); "Use disparity for interscene matching (as for UAS imagery)" );
gd.addNumericField("Disparity weight", this.ilma_disparity_weight, 6,8,"", gd.addNumericField("Disparity weight", this.ilma_disparity_weight, 6,8,"",
"Disparity component weight compared to dX and dY"); "Disparity component weight compared to dX and dY");
gd.addCheckbox ("LMA in 3D mode", this.ilma_3d_lma, gd.addCheckbox ("LMA in 3D mode", this.ilma_3d_lma,
"Use LMA disparity for interscene matching (as for UAS imagery)" ); "Use LMA disparity for interscene matching (as for UAS imagery)" );
gd.addCheckbox ("Remove average disparity, use tilts only", this.ilma_3d_tilt_only, gd.addCheckbox ("Remove average disparity, use tilts only", this.ilma_3d_tilt_only,
"Calculate disparity for tilts only." ); "Calculate disparity for tilts only." );
gd.addNumericField("Per-scene offest or ERS", this.ilma_per_scene, 6,8,"pix",
"Disable ERS if per-scene pixel difference is lower (unused).");
gd.addMessage("Disable ERS fitting with LMA when data is insufficient");
gd.addCheckbox ("Enable ERS LMA filtering", this.ilma_ers_quads,
"Disable ERS fitting if not enough data." );
gd.addNumericField("Center inactive cross relative size", this.ilma_gap_frac, 6,8,"",
"Remove this center fraction of width/height when evaluating quads.");
gd.addNumericField("Minimal tiles in each quad", this.ilma_min_quad_tiles, 0,3,"",
"Minimal number of defined tiles in each quad for using ERS.");
gd.addNumericField("Minimal relative weight of each quad", this.ilma_min_quad_weight, 6,8,"",
"Minimal fraction of total tiles weight in each quad for using ERS.");
gd.addMessage("---");
gd.addCheckbox ("Thread-invariant execution", this.ilma_thread_invariant, gd.addCheckbox ("Thread-invariant execution", this.ilma_thread_invariant,
"Do not use DoubleAdder and provide results not dependent on threads" ); "Do not use DoubleAdder and provide results not dependent on threads" );
for (int i = ErsCorrection.DP_DVAZ; i < ErsCorrection.DP_NUM_PARS; i++) { for (int i = ErsCorrection.DP_DVAZ; i < ErsCorrection.DP_NUM_PARS; i++) {
...@@ -192,6 +213,13 @@ public class IntersceneLmaParameters { ...@@ -192,6 +213,13 @@ public class IntersceneLmaParameters {
this.ilma_disparity_weight = gd.getNextNumber(); this.ilma_disparity_weight = gd.getNextNumber();
this.ilma_3d_lma = gd.getNextBoolean(); this.ilma_3d_lma = gd.getNextBoolean();
this.ilma_3d_tilt_only = gd.getNextBoolean(); this.ilma_3d_tilt_only = gd.getNextBoolean();
this.ilma_per_scene = gd.getNextNumber();
this.ilma_ers_quads = gd.getNextBoolean();
this.ilma_gap_frac = gd.getNextNumber();
this.ilma_min_quad_tiles = (int) gd.getNextNumber();
this.ilma_min_quad_weight = gd.getNextNumber();
this.ilma_thread_invariant = gd.getNextBoolean(); this.ilma_thread_invariant = gd.getNextBoolean();
for (int i = ErsCorrection.DP_DVAZ; i < ErsCorrection.DP_NUM_PARS; i++) { for (int i = ErsCorrection.DP_DVAZ; i < ErsCorrection.DP_NUM_PARS; i++) {
this.ilma_lma_select[i] = gd.getNextBoolean(); this.ilma_lma_select[i] = gd.getNextBoolean();
...@@ -227,7 +255,14 @@ public class IntersceneLmaParameters { ...@@ -227,7 +255,14 @@ public class IntersceneLmaParameters {
properties.setProperty(prefix+"ilma_3d", this.ilma_3d+""); properties.setProperty(prefix+"ilma_3d", this.ilma_3d+"");
properties.setProperty(prefix+"ilma_disparity_weight", this.ilma_disparity_weight+""); properties.setProperty(prefix+"ilma_disparity_weight", this.ilma_disparity_weight+"");
properties.setProperty(prefix+"ilma_3d_lma", this.ilma_3d_lma+""); properties.setProperty(prefix+"ilma_3d_lma", this.ilma_3d_lma+"");
properties.setProperty(prefix+"ilma_3d_tilt_only", this.ilma_3d_tilt_only+""); properties.setProperty(prefix+"ilma_3d_tilt_only", this.ilma_3d_tilt_only+"");
properties.setProperty(prefix+"ilma_per_scene", this.ilma_per_scene+"");
properties.setProperty(prefix+"ilma_ers_quads", this.ilma_ers_quads+ ""); // boolean
properties.setProperty(prefix+"ilma_gap_frac", this.ilma_gap_frac+""); // double
properties.setProperty(prefix+"ilma_min_quad_tiles", this.ilma_min_quad_tiles+""); // int
properties.setProperty(prefix+"ilma_min_quad_weight", this.ilma_min_quad_weight+""); // double
properties.setProperty(prefix+"ilma_thread_invariant", this.ilma_thread_invariant+""); properties.setProperty(prefix+"ilma_thread_invariant", this.ilma_thread_invariant+"");
for (int i = ErsCorrection.DP_DVAZ; i < ErsCorrection.DP_NUM_PARS; i++) { for (int i = ErsCorrection.DP_DVAZ; i < ErsCorrection.DP_NUM_PARS; i++) {
properties.setProperty(prefix+ErsCorrection.DP_DERIV_NAMES[i]+"_sel", this.ilma_lma_select[i]+""); properties.setProperty(prefix+ErsCorrection.DP_DERIV_NAMES[i]+"_sel", this.ilma_lma_select[i]+"");
...@@ -259,6 +294,13 @@ public class IntersceneLmaParameters { ...@@ -259,6 +294,13 @@ public class IntersceneLmaParameters {
if (properties.getProperty(prefix+"ilma_disparity_weight")!=null) this.ilma_disparity_weight=Double.parseDouble(properties.getProperty(prefix+"ilma_disparity_weight")); if (properties.getProperty(prefix+"ilma_disparity_weight")!=null) this.ilma_disparity_weight=Double.parseDouble(properties.getProperty(prefix+"ilma_disparity_weight"));
if (properties.getProperty(prefix+"ilma_3d_lma")!=null) this.ilma_3d_lma=Boolean.parseBoolean(properties.getProperty(prefix+"ilma_3d_lma")); if (properties.getProperty(prefix+"ilma_3d_lma")!=null) this.ilma_3d_lma=Boolean.parseBoolean(properties.getProperty(prefix+"ilma_3d_lma"));
if (properties.getProperty(prefix+"ilma_3d_tilt_only")!=null) this.ilma_3d_tilt_only=Boolean.parseBoolean(properties.getProperty(prefix+"ilma_3d_tilt_only")); if (properties.getProperty(prefix+"ilma_3d_tilt_only")!=null) this.ilma_3d_tilt_only=Boolean.parseBoolean(properties.getProperty(prefix+"ilma_3d_tilt_only"));
if (properties.getProperty(prefix+"ilma_per_scene")!=null) this.ilma_per_scene=Double.parseDouble(properties.getProperty(prefix+"ilma_per_scene"));
if (properties.getProperty(prefix+"ilma_ers_quads")!=null) this.ilma_ers_quads=Boolean.parseBoolean(properties.getProperty(prefix+"ilma_ers_quads"));
if (properties.getProperty(prefix+"ilma_gap_frac")!=null) this.ilma_gap_frac=Double.parseDouble(properties.getProperty(prefix+"ilma_gap_frac"));
if (properties.getProperty(prefix+"ilma_min_quad_tiles")!=null) this.ilma_min_quad_tiles=Integer.parseInt(properties.getProperty(prefix+"ilma_min_quad_tiles"));
if (properties.getProperty(prefix+"ilma_min_quad_weight")!=null) this.ilma_min_quad_weight=Double.parseDouble(properties.getProperty(prefix+"ilma_min_quad_weight"));
if (properties.getProperty(prefix+"ilma_thread_invariant")!=null) this.ilma_thread_invariant=Boolean.parseBoolean(properties.getProperty(prefix+"ilma_thread_invariant")); if (properties.getProperty(prefix+"ilma_thread_invariant")!=null) this.ilma_thread_invariant=Boolean.parseBoolean(properties.getProperty(prefix+"ilma_thread_invariant"));
for (int i = ErsCorrection.DP_DVAZ; i < ErsCorrection.DP_NUM_PARS; i++) { for (int i = ErsCorrection.DP_DVAZ; i < ErsCorrection.DP_NUM_PARS; i++) {
String pn_sel = prefix+ErsCorrection.DP_DERIV_NAMES[i]+"_sel"; String pn_sel = prefix+ErsCorrection.DP_DERIV_NAMES[i]+"_sel";
...@@ -306,6 +348,11 @@ public class IntersceneLmaParameters { ...@@ -306,6 +348,11 @@ public class IntersceneLmaParameters {
ilp.ilma_disparity_weight = this.ilma_disparity_weight; ilp.ilma_disparity_weight = this.ilma_disparity_weight;
ilp.ilma_3d_lma = this.ilma_3d_lma; ilp.ilma_3d_lma = this.ilma_3d_lma;
ilp.ilma_3d_tilt_only = this.ilma_3d_tilt_only; ilp.ilma_3d_tilt_only = this.ilma_3d_tilt_only;
ilp.ilma_per_scene = this.ilma_per_scene;
ilp.ilma_ers_quads = this.ilma_ers_quads;
ilp.ilma_gap_frac = this.ilma_gap_frac;
ilp.ilma_min_quad_tiles = this.ilma_min_quad_tiles;
ilp.ilma_min_quad_weight = this.ilma_min_quad_weight;
ilp.ilma_thread_invariant = this.ilma_thread_invariant; ilp.ilma_thread_invariant = this.ilma_thread_invariant;
System.arraycopy(this.ilma_lma_select, 0, ilp.ilma_lma_select, 0, ilma_lma_select.length); System.arraycopy(this.ilma_lma_select, 0, ilp.ilma_lma_select, 0, ilma_lma_select.length);
System.arraycopy(this.ilma_regularization_weights, 0, ilp.ilma_regularization_weights, 0, ilma_regularization_weights.length); System.arraycopy(this.ilma_regularization_weights, 0, ilp.ilma_regularization_weights, 0, ilma_regularization_weights.length);
......
...@@ -5875,36 +5875,6 @@ public class OpticalFlow { ...@@ -5875,36 +5875,6 @@ public class OpticalFlow {
int [] whs = new int[3]; int [] whs = new int[3];
double [] x0y0 = new double[2]; double [] x0y0 = new double[2];
if (export3d) { //combo_dsn_final had strength 1.0e-4 where it should not? Reset it? if (export3d) { //combo_dsn_final had strength 1.0e-4 where it should not? Reset it?
/*
boolean use_lma = true; // ;
double discard_low = 0.01; // fraction of all pixels
double discard_high = 0.5; // fraction of all pixels
double discard_adisp = 0.2; // discard above/below this fraction of average height
double discard_rdisp = 0.02; // discard above/below this fraction of average height
double pix_size = 0.005; // hdr_x0y0, // in meters
int max_image_width = 3200; // increase pixel size as a power of 2 until image fits
// boolean crop_empty = true;
// int crop_extra = 20;
// int [] tex_pals = {0,1,2};
// int tex_palette_start = 0; //
// int tex_palette_end = 12;
int [] hdr_whs = new int[3];
double [] hdr_x0y0 = new double[2];
double [][] to_ground_xyxatr = quadCLTs[ref_index].getGround(
use_lma, // boolean use_lma,
clt_parameters.imp.range_disparity_offset,// double range_disparity_offset
discard_low, // double discard_low, // fraction of all pixels
discard_high, // double discard_high, // fraction of all pixels
discard_adisp, // double discard_adisp, // discard above/below this fraction of average height
discard_rdisp, // double discard_rdisp // discard above/below this fraction of average height
pix_size, // double pix_size, // in meters
max_image_width, // int max_image_width // increase pixel size as a power of 2 until image fits
hdr_x0y0, // double [] x0y0, // initialize to double[2] to return width, height
hdr_whs, // int [] whs, // initialize to int[3] to return {width, height, scale reduction}
debugLevel); // int debug_level
*/
boolean ok_3d = TexturedModel.output3d( // quadCLTs have same image name, and everything else boolean ok_3d = TexturedModel.output3d( // quadCLTs have same image name, and everything else
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
...@@ -5923,10 +5893,6 @@ public class OpticalFlow { ...@@ -5923,10 +5893,6 @@ public class OpticalFlow {
if (export_images) { if (export_images) {
if (combo_dsn_final == null) { if (combo_dsn_final == null) {
/// combo_dsn_final = quadCLTs[ref_index].readDoubleArrayFromModelDirectory(
/// "-INTER-INTRA-LMA", // String suffix,
/// 0, // int num_slices, // (0 - all)
/// null); // int [] wh);
combo_dsn_final =quadCLTs[ref_index].restoreComboDSI(true); // also sets quadCLTs[ref_index].dsi and blue sky combo_dsn_final =quadCLTs[ref_index].restoreComboDSI(true); // also sets quadCLTs[ref_index].dsi and blue sky
} }
...@@ -13416,21 +13382,72 @@ public class OpticalFlow { ...@@ -13416,21 +13382,72 @@ public class OpticalFlow {
mvTitles); mvTitles);
} }
if (debug_level > 0){ if (debug_level > 0){
int num_defined = 0; double gap_frac = 0.25;
double sum_strength = 0.0; double [][] quad_strengths = getQuadStrengths(
for (int i = 0; i < coord_motion[1].length; i++) if (coord_motion[1][i] != null){ coord_motion, // double [][][] coord_motion,
sum_strength += coord_motion[1][i][2]; gap_frac, //double gap_frac, // 0.25
num_defined++; tilesX); // int tilesX);
}
System.out.println ("interCorrPair(): num_defined = "+num_defined+ // int num_defined = 0;
", sum_strength = "+sum_strength+", avg_strength = "+(sum_strength/num_defined)); // double sum_strength = 0.0;
System.out.println ("interCorrPair(): quad_defined = ["+quad_strengths[0][0]+","
+quad_strengths[0][1]+","+quad_strengths[0][2]+","+quad_strengths[0][3]+"]"
+"), rel_strengths = ["
+quad_strengths[1][0]+","+quad_strengths[1][1]+","
+quad_strengths[1][2]+","+quad_strengths[1][3]+"] ");
} }
if (fail_reason != null) { if (fail_reason != null) {
fail_reason[0]= 0; fail_reason[0]= 0;
} }
return coord_motion; // here non-null return coord_motion; // here non-null
} }
/**
* Calculates data availability in 4 corners (excluding center gap)
* To disable ERS calculation in LMA
* @param coord_motion interCorrPair() output - here only defined (non-null)
* and strength are used
* @param gap_frac fraction of width and height to remove in the center
* 0.25 - remove from 3/8 to 5/8 "cross" in the center
* @param tilesX number of tiles in a row
* @return [2][4] - [0][]: number of non-null tiles in each quadrant,
* [1][] - fraction of weight of total weight (total does not exclude center)
*/
public static double [][] getQuadStrengths(
double [][][] coord_motion,
double gap_frac, // 4
int tilesX) {
int tilesY = coord_motion[1].length/ tilesX;
int num_defined = 0;
double sum_strength = 0.0;
double [][] quad_strengths = new double[2][4];
int igapX = (int) (gap_frac * tilesX), igapY = (int) (gap_frac * tilesY);
int igapX0 = (tilesX - igapX)/2;
int igapX1 = igapX0 + igapX;
int igapY0 = (tilesY - igapY)/2;
int igapY1 = igapY0 + igapY;
for (int i = 0; i < coord_motion[1].length; i++) if (coord_motion[1][i] != null){
sum_strength += coord_motion[1][i][2];
num_defined++;
int ty = i / tilesX;
int tx = i % tilesX;
if (((ty > igapY0) && (ty < igapY1)) || ((tx > igapX0) && (tx < igapX1))) {
continue;
}
int iy = ty/(tilesY/2);
int ix = tx/(tilesX/2);
int ixy = 2*iy+ix;
quad_strengths[0][ixy] += 1.0;
quad_strengths[1][ixy] += coord_motion[1][i][2];
}
if (sum_strength > 0) {
for (int i = 0; i< quad_strengths[1].length; i++) {
// quad_strengths[0][i]/=num_defined;
quad_strengths[1][i]/=sum_strength;
}
}
return quad_strengths;
}
/** /**
* Equalize weights of the motion vectors to boost that of important buy weak one. * Equalize weights of the motion vectors to boost that of important buy weak one.
...@@ -15059,6 +15076,11 @@ public class OpticalFlow { ...@@ -15059,6 +15076,11 @@ public class OpticalFlow {
int debug_level) int debug_level)
{ {
boolean use3D = clt_parameters.ilp.ilma_3d; boolean use3D = clt_parameters.ilp.ilma_3d;
boolean filter_by_ers = clt_parameters.ilp.ilma_ers_quads;
double gap_frac = clt_parameters.ilp.ilma_gap_frac ; // 0.25;
int min_quad_tiles = clt_parameters.ilp.ilma_min_quad_tiles ; // 10;
double min_quad_weight = clt_parameters.ilp.ilma_min_quad_weight ; // 0.01;
// boolean use3D_lma = clt_parameters.ilp.ilma_3d_lma; // boolean use3D_lma = clt_parameters.ilp.ilma_3d_lma;
double disparity_weight = use3D? clt_parameters.ilp.ilma_disparity_weight : 0.0; double disparity_weight = use3D? clt_parameters.ilp.ilma_disparity_weight : 0.0;
int margin = clt_parameters.imp.margin; int margin = clt_parameters.imp.margin;
...@@ -15107,6 +15129,45 @@ public class OpticalFlow { ...@@ -15107,6 +15129,45 @@ public class OpticalFlow {
System.out.println("adjustPairsLMAInterscene() returned null"); System.out.println("adjustPairsLMAInterscene() returned null");
return null; return null;
} }
boolean ers_lma = false;
for (int i:ErsCorrection.DP_ERS_INDICES) {
ers_lma |= param_select[i];
}
boolean disable_ers=false;
boolean [] param_select_mod = param_select;
if (ers_lma && filter_by_ers) {
double [][] quad_strengths = getQuadStrengths(
coord_motion, // double [][][] coord_motion,
gap_frac, //double gap_frac, // 0.25
reference_QuadClt.getTileProcessor().getTilesX()); // int tilesX);
for (int i = 0; i < quad_strengths[0].length; i++) {
if ((quad_strengths[0][i] < min_quad_tiles) || (quad_strengths[1][i] < min_quad_weight)) {
disable_ers = true;
break;
}
}
if (disable_ers) {
param_select_mod = param_select.clone();
for (int i:ErsCorrection.DP_ERS_INDICES) {
param_select_mod[i] = false;
}
// now just copy ers from the reference
ErsCorrection ers_ref = reference_QuadClt.getErsCorrection();
ErsCorrection ers_scene = scene_QuadClt.getErsCorrection();
ers_scene.ers_watr_center_dt = ers_ref.ers_watr_center_dt.clone();
ers_scene.ers_wxyz_center_dt = ers_ref.ers_wxyz_center_dt.clone();
if (clt_parameters.imp.debug_level > -2) {
System.out.print("adjustPairsLMAInterscene(): insufficeinet data for ERS, skipping. ");
System.out.println ("quad_defined = ["+((int)quad_strengths[0][0])+","
+((int)quad_strengths[0][1])+","+((int)quad_strengths[0][2])+","+((int)quad_strengths[0][3])+"] (needed = "+
min_quad_tiles +"), rel_strengths = ["
+quad_strengths[1][0]+","+quad_strengths[1][1]+","
+quad_strengths[1][2]+","+quad_strengths[1][3]+"] (needed "
+min_quad_weight+")");
}
}
}
intersceneLma.prepareLMA( intersceneLma.prepareLMA(
camera_xyz0, // final double [] scene_xyz0, // camera center in world coordinates (or null to use instance) camera_xyz0, // final double [] scene_xyz0, // camera center in world coordinates (or null to use instance)
camera_atr0, // final double [] scene_atr0, // camera orientation relative to world frame (or null to use instance) camera_atr0, // final double [] scene_atr0, // camera orientation relative to world frame (or null to use instance)
...@@ -15115,7 +15176,7 @@ public class OpticalFlow { ...@@ -15115,7 +15176,7 @@ public class OpticalFlow {
// reference atr, xyz are considered 0.0 // reference atr, xyz are considered 0.0
scene_QuadClt, // final QuadCLT scene_QuadClt, scene_QuadClt, // final QuadCLT scene_QuadClt,
reference_QuadClt, // final QuadCLT reference_QuadClt, reference_QuadClt, // final QuadCLT reference_QuadClt,
param_select, // final boolean[] param_select, param_select_mod, // param_select, // final boolean[] param_select,
param_regweights, // final double [] param_regweights, param_regweights, // final double [] param_regweights,
coord_motion[1], // final double [][] vector_XYS, // optical flow X,Y, confidence obtained from the correlate2DIterate() coord_motion[1], // final double [][] vector_XYS, // optical flow X,Y, confidence obtained from the correlate2DIterate()
coord_motion[0], // final double [][] centers, // macrotile centers (in pixels and average disparities coord_motion[0], // final double [][] centers, // macrotile centers (in pixels and average disparities
......
...@@ -236,13 +236,9 @@ public class QuadCLTCPU { ...@@ -236,13 +236,9 @@ public class QuadCLTCPU {
) { ) {
double [] z_tilts = null; double [] z_tilts = null;
double normal_damping = 0.001; // pull to horizontal if not enough data double normal_damping = 0.001; // pull to horizontal if not enough data
// final int tilesX=getTileProcessor().getTilesX();
// final int tilesY=getTileProcessor().getTilesY();
double hist_rlow = 0.5; double hist_rlow = 0.5;
double hist_rhigh = 2.0; double hist_rhigh = 2.0;
int min_good = 20; //number of good tiles int min_good = 20; //number of good tiles
/// int min_good_quad = 20; // number of good tiles per quadrant to calculate tilts
/// int gap_frac2= 20;
double rel_hight = 0.2; // when calculating scale, ignore objects far from plane double rel_hight = 0.2; // when calculating scale, ignore objects far from plane
int num_bins = 1000; int num_bins = 1000;
double [][] dls = getDLS(); double [][] dls = getDLS();
...@@ -288,7 +284,6 @@ public class QuadCLTCPU { ...@@ -288,7 +284,6 @@ public class QuadCLTCPU {
if (sh >= dl) break; if (sh >= dl) break;
} }
double shp = sh- hist[indx]; double shp = sh- hist[indx];
// double thr_low = shp + (dl - shp)/(sh-shp);
// step back from the overshoot indx // step back from the overshoot indx
double thr_low = hist_low+ (indx - (sh - dl)/(sh-shp))/num_bins *(hist_high-hist_low); double thr_low = hist_low+ (indx - (sh - dl)/(sh-shp))/num_bins *(hist_high-hist_low);
indx = num_bins-1; indx = num_bins-1;
...@@ -300,8 +295,6 @@ public class QuadCLTCPU { ...@@ -300,8 +295,6 @@ public class QuadCLTCPU {
} }
} }
shp = sh- hist[indx]; shp = sh- hist[indx];
// double thr_high = shp - (dh-shp)/(sh - shp); // both negative
// double thr_high = hist_low+ (shp + (dh - shp)/(sh-shp))/num_bins *(hist_high-hist_low);
double thr_high = hist_low+ (indx + (sh - dh)/(sh-shp))/num_bins *(hist_high-hist_low); double thr_high = hist_low+ (indx + (sh - dh)/(sh-shp))/num_bins *(hist_high-hist_low);
int numgood = 0; int numgood = 0;
boolean [] good = new boolean[ds[0].length]; boolean [] good = new boolean[ds[0].length];
...@@ -321,189 +314,123 @@ public class QuadCLTCPU { ...@@ -321,189 +314,123 @@ public class QuadCLTCPU {
} }
return null; // too few good return null; // too few good
} }
// double z_avg= getGeometryCorrection().getZFromDisparity(swd/sw); // fit plane
/* double [] ref_disparity = ds[0].clone();
int gap_x_0 = tilesX/2 - tilesX/gap_frac2; for (int i = 0; i < ref_disparity.length; i++) {
int gap_x_1 = tilesX/2 + tilesX/gap_frac2; if (!good[i]) {
int gap_y_0 = tilesY/2 - tilesY/gap_frac2; ref_disparity[i] = Double.NaN;
int gap_y_1 = tilesY/2 + tilesY/gap_frac2;
int [][] num_good_quad = new int [2][2];
for (int i = 0; i < good.length; i++) if (good[i]){
int ty = i / tilesX;
if ((ty <= gap_y_0) || (ty >= gap_y_1)) {
int tx = i % tilesX;
if ((tx <= gap_x_0) || (tx >= gap_x_1)) {
int indx_y = (ty > tilesY/2)? 1:0;
int indx_x = (tx > tilesX/2)? 1:0;
num_good_quad[indx_y][indx_x]++;
}
} }
} }
int num_good_quads = 0;
for (int i = 0; i < num_good_quad.length; i++) { double [][] wxyz = OpticalFlow.transformToWorldXYZ(
for (int j = 0; j < num_good_quad[i].length; j++) { ref_disparity, // final double [] disparity_ref, // invalid tiles - NaN in disparity
if (num_good_quad[i][j] > min_good_quad) { (QuadCLT) this, // final QuadCLT quadClt, // now - may be null - for testing if scene is rotated ref
num_good_quads++; THREADS_MAX); // int threadsMax)
} numgood = 0;
} for (int i = 0; i < wxyz.length; i++) if (wxyz[i] != null) {
numgood++;
} }
if (num_good_quads < 3) { double [][][] mdata = new double [numgood][][];
if (debug_level > -3) { int mindx = 0;
System.out.println("There are less than 3 quadrants ("+num_good_quads+") having more than "+min_good_quad+" tiles"); for (int i = 0; i < wxyz.length; i++) if (wxyz[i] != null){
System.out.println("Using only level "+z_avg+", ignoring tilt."); mdata[mindx] = new double[3][];
} mdata[mindx][0] = new double [2];
z_tilts = new double[] {-z_avg, 0.0, 0.0}; // no tilts mdata[mindx][0][0] = wxyz[i][0];
// return new double[] {z_avg, 0.0, 0.0}; // no tilts mdata[mindx][0][1] = wxyz[i][1];
} else { mdata[mindx][1] = new double [1];
mdata[mindx][1][0] = wxyz[i][2];
*/ mdata[mindx][2] = new double [1];
// fit plane mdata[mindx][2][0] = ds[1][i];
double [] ref_disparity = ds[0].clone(); mindx++;
}
PolynomialApproximation pa = new PolynomialApproximation();
double [] damping = new double [] {normal_damping, normal_damping};
double[][] approx2d = pa.quadraticApproximation(
mdata,
true, // boolean forceLinear, // use linear approximation
damping, // double [] damping, null OK
-1); // debug level
z_tilts= new double [] { approx2d[0][2], approx2d[0][0], approx2d[0][1]};
if (debug_level > -3) {
System.out.println("Found ground plane: level="+z_tilts[0]+", tiltX="+z_tilts[1]+", tiltY="+z_tilts[2]);
}
double [][] ground_xyxatr = new double [][] {
{0, 0, z_tilts[0]},
{Math.asin(z_tilts[1]), -Math.asin(z_tilts[2]), 0.0}};
// It is approximate for small angles. OK for now
double [][] to_ground_xyxatr = ErsCorrection.invertXYZATR(ground_xyxatr);
// recalculate coordinates for all pixels including weak ones
ref_disparity = dls[0].clone();
for (int i = 0; i < ref_disparity.length; i++) { for (int i = 0; i < ref_disparity.length; i++) {
if (!good[i]) { if (Double.isNaN(ref_disparity[i])) ref_disparity[i] = 0.0;
ref_disparity[i] = Double.NaN; else {
ref_disparity[i] -= disparity_offset;
} }
} }
wxyz = OpticalFlow.transformToWorldXYZ(
double [][] wxyz = OpticalFlow.transformToWorldXYZ( ref_disparity, // final double [] disparity_ref, // invalid tiles - NaN in disparity
ref_disparity, // final double [] disparity_ref, // invalid tiles - NaN in disparity
(QuadCLT) this, // final QuadCLT quadClt, // now - may be null - for testing if scene is rotated ref (QuadCLT) this, // final QuadCLT quadClt, // now - may be null - for testing if scene is rotated ref
THREADS_MAX); // int threadsMax) THREADS_MAX); // int threadsMax)
numgood = 0; double [][] plane_xyz=new double[wxyz.length][];
double [] x_min_max = null; // new int[2];
double [] y_min_max = null; // new int[2];
for (int i = 0; i < wxyz.length; i++) if (wxyz[i] != null) { for (int i = 0; i < wxyz.length; i++) if (wxyz[i] != null) {
numgood++; double [] wxyz3=new double[] {wxyz[i][0],wxyz[i][1],wxyz[i][2]};
plane_xyz[i] =ErsCorrection.applyXYZATR(
to_ground_xyxatr, // double [][] reference_xyzatr,
wxyz3); // double [][] scene_xyzatr)
double x = plane_xyz[i][0];
double y = plane_xyz[i][1];
double z = plane_xyz[i][2];
if (Math.abs(z)/Math.abs(z_tilts[0]) > rel_hight){
continue; // outlier Z
}
if (x_min_max == null) x_min_max = new double[] {x,x};
if (y_min_max == null) y_min_max = new double[] {y,y};
if (x < x_min_max[0]) x_min_max[0] = x;
else if (x > x_min_max[1]) x_min_max[1] = x;
if (y < y_min_max[0]) y_min_max[0] = y;
else if (y > y_min_max[1]) y_min_max[1] = y;
} }
double [][][] mdata = new double [numgood][][]; if ((x_min_max == null) || (y_min_max == null)) {
int mindx = 0; return null; // no points at all?
for (int i = 0; i < wxyz.length; i++) if (wxyz[i] != null){
mdata[mindx] = new double[3][];
mdata[mindx][0] = new double [2];
mdata[mindx][0][0] = wxyz[i][0];
mdata[mindx][0][1] = wxyz[i][1];
mdata[mindx][1] = new double [1];
mdata[mindx][1][0] = wxyz[i][2];
mdata[mindx][2] = new double [1];
mdata[mindx][2][0] = ds[1][i];
mindx++;
}
PolynomialApproximation pa = new PolynomialApproximation();
double [] damping = new double [] {normal_damping, normal_damping};
double[][] approx2d = pa.quadraticApproximation(
mdata,
true, // boolean forceLinear, // use linear approximation
damping, // double [] damping, null OK
-1); // debug level
z_tilts= new double [] { approx2d[0][2], approx2d[0][0], approx2d[0][1]};
if (debug_level > -3) {
System.out.println("Found ground plane: level="+z_tilts[0]+", tiltX="+z_tilts[1]+", tiltY="+z_tilts[2]);
} }
if (x0y0!=null) {
/* } */ x0y0[0] = x_min_max[0]; // null
// ground - negative Z. picture right - positive X, picture up - positive Y x0y0[1] = y_min_max[0];
// positive tiltX - to the right higher ground (lower altitude above it) or camera tilted left
// positive tiltY - picture up - higher ground (or camera tilted back)
double [][] ground_xyxatr = new double [][] {
{0, 0, z_tilts[0]},
{Math.asin(z_tilts[1]), -Math.asin(z_tilts[2]), 0.0}};
// It is approximate for small angles. OK for now
double [][] to_ground_xyxatr = ErsCorrection.invertXYZATR(ground_xyxatr);
// recalculate coordinates for all pixels including weak ones
// double []
ref_disparity = dls[0].clone();
for (int i = 0; i < ref_disparity.length; i++) {
if (Double.isNaN(ref_disparity[i])) ref_disparity[i] = 0.0;
else {
ref_disparity[i] -= disparity_offset;
} }
} int scale = 0;
// double [][] double use_pix_size = pix_size;
wxyz = OpticalFlow.transformToWorldXYZ( int width, height;
ref_disparity, // final double [] disparity_ref, // invalid tiles - NaN in disparity do {
(QuadCLT) this, // final QuadCLT quadClt, // now - may be null - for testing if scene is rotated ref scale = (scale==0) ? 1 : scale * 2;
THREADS_MAX); // int threadsMax) use_pix_size = scale * pix_size;
double [][] plane_xyz=new double[wxyz.length][]; width = (int) Math.floor((x_min_max[1]-x_min_max[0])/use_pix_size) + 1;
double [] x_min_max = null; // new int[2]; height = (int) Math.floor((y_min_max[1]-y_min_max[0])/use_pix_size) + 1;
double [] y_min_max = null; // new int[2]; } while ((width > max_image_width) || (height > max_image_width));
for (int i = 0; i < wxyz.length; i++) if (wxyz[i] != null) { if (whs != null) {
double [] wxyz3=new double[] {wxyz[i][0],wxyz[i][1],wxyz[i][2]}; whs[0] = width;
plane_xyz[i] =ErsCorrection.applyXYZATR( whs[1] = height;
whs[2] = scale;
}
if (debug_level > -2) {
System.out.println("Parameters for rendering:top left corner=["+x0y0[0]+"m, "+x0y0[1]+"m]");
System.out.println(" : width="+whs[0]+"pix, height="+whs[1]+"pix, scale level="+whs[2]);
System.out.println(" : pixel size: ="+(1000*use_pix_size)+"mm");
}
double [] dronexyz =ErsCorrection.applyXYZATR(
to_ground_xyxatr, // double [][] reference_xyzatr, to_ground_xyxatr, // double [][] reference_xyzatr,
wxyz3); // double [][] scene_xyzatr) new double [3] ); // double [][] scene_xyzatr)
double x = plane_xyz[i][0]; if (debug_level > -2) {
double y = plane_xyz[i][1]; System.out.println("Drone position relative to the ground plane: x="+
double z = plane_xyz[i][2]; dronexyz[0]+"m, y="+dronexyz[1]+"m, z="+dronexyz[2]+"m");
if (Math.abs(z)/Math.abs(z_tilts[0]) > rel_hight){
continue; // outlier Z
} }
return to_ground_xyxatr; // from the camera coordinates to in-plane coordiantes
if (x_min_max == null) x_min_max = new double[] {x,x};
if (y_min_max == null) y_min_max = new double[] {y,y};
if (x < x_min_max[0]) x_min_max[0] = x;
else if (x > x_min_max[1]) x_min_max[1] = x;
if (y < y_min_max[0]) y_min_max[0] = y;
else if (y > y_min_max[1]) y_min_max[1] = y;
}
if ((x_min_max == null) || (y_min_max == null)) {
return null; // no points at all?
}
if (x0y0!=null) {
x0y0[0] = x_min_max[0]; // null
x0y0[1] = y_min_max[0];
}
int scale = 0;
double use_pix_size = pix_size;
int width, height;
do {
scale = (scale==0) ? 1 : scale * 2;
use_pix_size = scale * pix_size;
width = (int) Math.floor((x_min_max[1]-x_min_max[0])/use_pix_size) + 1;
height = (int) Math.floor((y_min_max[1]-y_min_max[0])/use_pix_size) + 1;
} while ((width > max_image_width) || (height > max_image_width));
if (whs != null) {
whs[0] = width;
whs[1] = height;
whs[2] = scale;
}
if (debug_level > -2) {
System.out.println("Parameters for rendering:top left corner=["+x0y0[0]+"m, "+x0y0[1]+"m]");
System.out.println(" : width="+whs[0]+"pix, height="+whs[1]+"pix, scale level="+whs[2]);
System.out.println(" : pixel size: ="+(1000*use_pix_size)+"mm");
}
double [] dronexyz =ErsCorrection.applyXYZATR(
to_ground_xyxatr, // double [][] reference_xyzatr,
new double [3] ); // double [][] scene_xyzatr)
if (debug_level > -2) {
System.out.println("Drone position relative to the ground plane: x="+
dronexyz[0]+"m, y="+dronexyz[1]+"m, z="+dronexyz[2]+"m");
}
// double pix_size, // in meters
// int max_image_width // increase pixel size as a power of 2 until image fits
// testing world coordinates -> plane coordinates
/*
mindx = 0;
for (int i = 0; i < wxyz.length; i++) if (wxyz[i] != null){
mdata[mindx] = new double[3][];
mdata[mindx][0] = new double [2];
mdata[mindx][0][0] = plane_xyz[i][0];
mdata[mindx][0][1] = plane_xyz[i][1];
mdata[mindx][1] = new double [1];
mdata[mindx][1][0] = plane_xyz[i][2];
mdata[mindx][2] = new double [1];
mdata[mindx][2][0] = ds[1][i];
mindx++;
}
double[][] approx2d_1 = pa.quadraticApproximation(
mdata,
true, // boolean forceLinear, // use linear approximation
null, // double [] damping, null OK
-1); // debug level
*/
return to_ground_xyxatr; // from the camera coordinates to in-plane coordiantes
} }
public double [][] getDLS(){ // get disparity, disparity_lma, strength public double [][] getDLS(){ // get disparity, disparity_lma, strength
......
...@@ -2451,7 +2451,20 @@ public class TexturedModel { ...@@ -2451,7 +2451,20 @@ public class TexturedModel {
final boolean updateStatus, final boolean updateStatus,
final int debugLevel) final int debugLevel)
{ {
final boolean render_hdr = true; //false; // true; // generate textures w/o normalization to generate undistorted final boolean map_en = clt_parameters.gmap_en;
final boolean render_hdr = clt_parameters.gmap_render_hdr || map_en;// true; //false; // true; // generate textures w/o normalization to generate undistorted
final boolean use_lma = clt_parameters.gmap_use_lma ; // true; // ;
final double discard_low = clt_parameters.gmap_discard_low ; //0.01; // fraction of all pixels
final double discard_high = clt_parameters.gmap_discard_high ; //0.5; // fraction of all pixels
final double discard_adisp = clt_parameters.gmap_discard_adisp ; //0.2; // discard above/below this fraction of average height
final double discard_rdisp = clt_parameters.gmap_discard_rdisp ; //0.02; // discard above/below this fraction of average height
final double pix_size = clt_parameters.gmap_pix_size ; //0.005; // hdr_x0y0, // in meters
final int max_image_width = clt_parameters.gmap_max_image_width ; //4000; // 3200; // increase pixel size as a power of 2 until image fits
final boolean crop_empty = clt_parameters.gmap_crop_empty ; //true;
final int crop_extra = clt_parameters.gmap_crop_extra ; //20;
final int [] tex_pals = clt_parameters.gmap_tex_pals ; //{0,1,2};
final double range_disparity_offset = clt_parameters.imp.range_disparity_offset;// double range_disparity_offset final double range_disparity_offset = clt_parameters.imp.range_disparity_offset;// double range_disparity_offset
final boolean batch_mode = clt_parameters.multiseq_run; // batch_run; final boolean batch_mode = clt_parameters.multiseq_run; // batch_run;
final boolean gltf_emissive = clt_parameters.gltf_emissive; final boolean gltf_emissive = clt_parameters.gltf_emissive;
...@@ -2984,21 +2997,6 @@ public class TexturedModel { ...@@ -2984,21 +2997,6 @@ public class TexturedModel {
// if (imp_textures[nslice] != null) // if (imp_textures[nslice] != null)
} // for (int nslice = 0; nslice < tileClusters.length; nslice++){ } // for (int nslice = 0; nslice < tileClusters.length; nslice++){
if (render_hdr) { if (render_hdr) {
boolean use_lma = true; // ;
double discard_low = 0.01; // fraction of all pixels
double discard_high = 0.5; // fraction of all pixels
double discard_adisp = 0.2; // discard above/below this fraction of average height
double discard_rdisp = 0.02; // discard above/below this fraction of average height
double pix_size = 0.005; // hdr_x0y0, // in meters
int max_image_width = 4000; // 3200; // increase pixel size as a power of 2 until image fits
boolean crop_empty = true;
int crop_extra = 20;
int [] tex_pals = {0,1,2};
// boolean use_fixed_range = true;
// double fixed_range = 250.0;
int tex_palette_start = 0;
int tex_palette_end = 12;
int [] hdr_whs = new int[3]; int [] hdr_whs = new int[3];
double [] hdr_x0y0 = new double[2]; double [] hdr_x0y0 = new double[2];
double [][] to_ground_xyxatr = scenes[ref_index].getGround( double [][] to_ground_xyxatr = scenes[ref_index].getGround(
......
...@@ -54,24 +54,18 @@ public class Render3D { ...@@ -54,24 +54,18 @@ public class Render3D {
public Render3D ( public Render3D (
// String x3d_dir,
// String model_name,
QuadCLT ref_scene, // all coordinates relative to this scene QuadCLT ref_scene, // all coordinates relative to this scene
double [][] toground, // projection plane center relative to reference scene double [][] toground, // projection plane center relative to reference scene
double pixel_size, // in meters double pixel_size, // in meters
double [] x0_y0, // usually negative - top-left point of the output render double [] x0_y0, // usually negative - top-left point of the output render
int out_width, // output rendered image width in pixels int out_width, // output rendered image width in pixels
int out_height){ // output rendered image height in pixels int out_height){ // output rendered image height in pixels
// this.x3d_dir = x3d_dir;
// this.model_name = model_name;
this.ref_scene = ref_scene; this.ref_scene = ref_scene;
this.pixel_per_m = 1.0 / pixel_size; this.pixel_per_m = 1.0 / pixel_size;
this.out_width = out_width; this.out_width = out_width;
this.out_height = out_height; this.out_height = out_height;
this.toground = toground; this.toground = toground;
this.tocam = ErsCorrection.invertXYZATR(this.toground); // null this.tocam = ErsCorrection.invertXYZATR(this.toground); // null
// double [][] test1 = ErsCorrection.invertXYZATR(this.tocam); //OK
// double [][] test2 = ErsCorrection.invertXYZATR(test1); // OK
// ground plane x0, y0 in camera coordinates // ground plane x0, y0 in camera coordinates
ground_origin = new Vector3D(ErsCorrection.applyXYZATR(tocam, new double [] {x0_y0[0], x0_y0[1], 0.0})); ground_origin = new Vector3D(ErsCorrection.applyXYZATR(tocam, new double [] {x0_y0[0], x0_y0[1], 0.0}));
Vector3D v3x1 = new Vector3D(ErsCorrection.applyXYZATR(tocam, new double [] {x0_y0[0] + 1.0,x0_y0[1], 0.0})); Vector3D v3x1 = new Vector3D(ErsCorrection.applyXYZATR(tocam, new double [] {x0_y0[0] + 1.0,x0_y0[1], 0.0}));
...@@ -84,7 +78,6 @@ public class Render3D { ...@@ -84,7 +78,6 @@ public class Render3D {
ground_normal_unit = ground_normal.normalize(); // unitary vector normal and away from the ground plane ground_normal_unit = ground_normal.normalize(); // unitary vector normal and away from the ground plane
above_ground = ground_normal.getNorm(); above_ground = ground_normal.getNorm();
xy_offs = new double[] {ground_x.dotProduct(ground_origin), ground_y.dotProduct(ground_origin)}; xy_offs = new double[] {ground_x.dotProduct(ground_origin), ground_y.dotProduct(ground_origin)};
// double [] test_gp=projectToPlanePixels(ground_origin);
} }
public double [] projectToPlaneLinear(Vector3D v3) { // get ground place pixel coordinate from camera x,y,z public double [] projectToPlaneLinear(Vector3D v3) { // get ground place pixel coordinate from camera x,y,z
......
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