Commit 904ad2bc authored by Andrey Filippov's avatar Andrey Filippov

implemented/debugged photometric sensors matching

parent 5a125530
...@@ -475,7 +475,7 @@ public class IntersceneMatchParameters { ...@@ -475,7 +475,7 @@ public class IntersceneMatchParameters {
String [] stereo_choices = new String [stereo_views.length + 1]; String [] stereo_choices = new String [stereo_views.length + 1];
stereo_choices[0] = "--none--"; stereo_choices[0] = "--none--";
for (int i = 0; i < stereo_views.length; i++) { for (int i = 0; i < stereo_views.length; i++) {
stereo_choices[i+1] = doublesToString(stereo_views[i])+" mm"; stereo_choices[i+1] = doublesToString(stereo_views[i],"%.0f")+" mm";
} }
gd. addChoice("Remove stereo-view (base, up, back)", stereo_choices, stereo_choices[0], gd. addChoice("Remove stereo-view (base, up, back)", stereo_choices, stereo_choices[0],
"Remove selected stereo-view, consisting of streo-base, viewpoint above camera, viewpoint behing camera - all in mm"); "Remove selected stereo-view, consisting of streo-base, viewpoint above camera, viewpoint behing camera - all in mm");
...@@ -1031,7 +1031,7 @@ public class IntersceneMatchParameters { ...@@ -1031,7 +1031,7 @@ public class IntersceneMatchParameters {
*/ */
properties.setProperty(prefix+"stereo_views_num", this.stereo_views.length+""); // int properties.setProperty(prefix+"stereo_views_num", this.stereo_views.length+""); // int
for (int i = 0; i < this.stereo_views.length; i++) { for (int i = 0; i < this.stereo_views.length; i++) {
properties.setProperty(prefix+"stereo_views_"+i, doublesToString(this.stereo_views[i])); // String properties.setProperty(prefix+"stereo_views_"+i, doublesToString(this.stereo_views[i],"%.0f")); // String
properties.setProperty(prefix+"generate_stereo_var_"+i, this.generate_stereo_var[i]+""); // boolean properties.setProperty(prefix+"generate_stereo_var_"+i, this.generate_stereo_var[i]+""); // boolean
} }
...@@ -1785,12 +1785,16 @@ public class IntersceneMatchParameters { ...@@ -1785,12 +1785,16 @@ public class IntersceneMatchParameters {
return doublesToString(data, null); return doublesToString(data, null);
} }
public static String doublesToString(double [] data, String fmt) { public static String doublesToString(double [] data, String fmt) {
if ((fmt == null) || (fmt.trim().length()==0)) { // if ((fmt == null) || (fmt.trim().length()==0)) {
fmt = "%.0f"; // fmt = "%.0f";
} // }
String s = ""; String s = "";
for (int i = 0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
if (fmt==null) {
s += data[i]; // unformatted
} else {
s+=String.format(fmt,data[i]); s+=String.format(fmt,data[i]);
}
if (i < (data.length - 1)) { if (i < (data.length - 1)) {
s+= ", "; s+= ", ";
} }
......
...@@ -4045,6 +4045,7 @@ public class OpticalFlow { ...@@ -4045,6 +4045,7 @@ public class OpticalFlow {
boolean export_images = clt_parameters.imp.export_images; boolean export_images = clt_parameters.imp.export_images;
boolean export_dsi_image = clt_parameters.imp.export_ranges; boolean export_dsi_image = clt_parameters.imp.export_ranges;
boolean export_ml_files = clt_parameters.imp.export_ml_files; boolean export_ml_files = clt_parameters.imp.export_ml_files;
boolean calibrate_photometric = true;
boolean show_dsi_image = clt_parameters.imp.show_ranges && !batch_mode; boolean show_dsi_image = clt_parameters.imp.show_ranges && !batch_mode;
boolean show_images = clt_parameters.imp.show_images && !batch_mode; boolean show_images = clt_parameters.imp.show_images && !batch_mode;
...@@ -4424,7 +4425,9 @@ public class OpticalFlow { ...@@ -4424,7 +4425,9 @@ public class OpticalFlow {
} else {// if (build_orientations) { } else {// if (build_orientations) {
if (!reuse_video) { // reuse_video only uses reference scene if (!reuse_video) { // reuse_video only uses reference scene
for (int scene_index = ref_index - 1; scene_index >= earliest_scene ; scene_index--) { for (int scene_index = ref_index - 1; scene_index >= earliest_scene ; scene_index--) {
quadCLTs[scene_index] = (QuadCLT) quadCLT_main.spawnNoModelQuadCLT( // restores image data // quadCLTs[scene_index] = (QuadCLT) quadCLT_main.spawnNoModelQuadCLT( // restores image data
// to include ref scene photometric calibration
quadCLTs[scene_index] = quadCLTs[ref_index].spawnNoModelQuadCLT( // restores image data
set_channels[scene_index].set_name, set_channels[scene_index].set_name,
clt_parameters, clt_parameters,
colorProcParameters, // colorProcParameters, //
...@@ -4504,6 +4507,62 @@ public class OpticalFlow { ...@@ -4504,6 +4507,62 @@ public class OpticalFlow {
} }
} }
if (calibrate_photometric) {
if (combo_dsn_final == null) { // always re-read?
combo_dsn_final =quadCLTs[ref_index].readDoubleArrayFromModelDirectory( // always re-read?
"-INTER-INTRA-LMA", // String suffix,
0, // int num_slices, // (0 - all)
null); // int [] wh);
}
double [][] combo_dsn_final_filtered =
conditionComboDsnFinal(
true, // boolean use_conf, // use configuration parameters, false - use following
clt_parameters, // CLTParameters clt_parameters,
combo_dsn_final, // double [][] combo_dsn_final, // dls,
quadCLTs[ref_index], // QuadCLT scene,
debugLevel); // int debugLevel);// > 0
QuadCLT.calibratePhotometric(
clt_parameters, // CLTParameters clt_parameters,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
0.0, // final double min_strength,
100.0, // final double max_diff, // 30.0
2, // final int num_refines, // 2
combo_dsn_final_filtered, // final double [][] combo_dsn_final, // double [][] combo_dsn_final, // dls,
threadsMax, // int threadsMax,
true); //final boolean debug)
// copy offsets to the current to be saved with other properties. Is it correct/needed?
quadCLTs[ref_index].saveInterProperties( // save properties for interscene processing (extrinsics, ers, ...)
null, // String path, // full name with extension or w/o path to use x3d directory
debugLevel+1);
quadCLT_main.setLwirOffsets(quadCLTs[ref_index].getLwirOffsets());
quadCLT_main.setLwirScales(quadCLTs[ref_index].getLwirScales());
// Re-read reference and other scenes using new offsets
quadCLTs[ref_index] = (QuadCLT) quadCLT_main.spawnQuadCLT( // restores dsi from "DSI-MAIN"
set_channels[ref_index].set_name,
clt_parameters,
colorProcParameters, //
threadsMax,
debugLevel);
quadCLTs[ref_index].setDSRBG(
clt_parameters, // CLTParameters clt_parameters,
threadsMax, // int threadsMax, // maximal number of threads to launch
updateStatus, // boolean updateStatus,
debugLevel); // int debugLevel)
ers_reference = quadCLTs[ref_index].getErsCorrection();
if (!reuse_video) { // reuse_video only uses reference scene
for (int scene_index = ref_index - 1; scene_index >= earliest_scene ; scene_index--) {
// quadCLTs[scene_index] = (QuadCLT) quadCLT_main.spawnNoModelQuadCLT( // restores image data
// to include ref scene photometric calibration
quadCLTs[scene_index] = quadCLTs[ref_index].spawnNoModelQuadCLT( // restores image data
set_channels[scene_index].set_name,
clt_parameters,
colorProcParameters, //
threadsMax,
debugLevel-2);
}
}
}
if (test_ers) { // only debug feature if (test_ers) { // only debug feature
test_ers0 = quadCLTs.length -1; // make it always == reference ! test_ers0 = quadCLTs.length -1; // make it always == reference !
...@@ -5025,6 +5084,7 @@ public class OpticalFlow { ...@@ -5025,6 +5084,7 @@ public class OpticalFlow {
quadCLTs[ref_index], // final QuadCLT scene, quadCLTs[ref_index], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true, // toRGB, // final boolean toRGB, true, // toRGB, // final boolean toRGB,
clt_parameters.imp.show_color_nan, // boolean show_nan
"GPU-SHIFTED-D"+clt_parameters.disparity, // String suffix, "GPU-SHIFTED-D"+clt_parameters.disparity, // String suffix,
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5042,6 +5102,7 @@ public class OpticalFlow { ...@@ -5042,6 +5102,7 @@ public class OpticalFlow {
quadCLTs[ref_index], // final QuadCLT scene, quadCLTs[ref_index], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false, // toRGB, // final boolean toRGB, false, // toRGB, // final boolean toRGB,
clt_parameters.imp.show_mono_nan, // boolean show_nan
"GPU-SHIFTED-D"+clt_parameters.disparity, // String suffix, "GPU-SHIFTED-D"+clt_parameters.disparity, // String suffix,
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5121,6 +5182,7 @@ public class OpticalFlow { ...@@ -5121,6 +5182,7 @@ public class OpticalFlow {
quadCLTs[ref_index], // final QuadCLT scene, quadCLTs[ref_index], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true, // toRGB, // final boolean toRGB, true, // toRGB, // final boolean toRGB,
clt_parameters.imp.show_color_nan,
scenes_suffix+"GPU-SHIFTED-FOREGROUND", // String suffix, scenes_suffix+"GPU-SHIFTED-FOREGROUND", // String suffix,
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5138,6 +5200,7 @@ public class OpticalFlow { ...@@ -5138,6 +5200,7 @@ public class OpticalFlow {
quadCLTs[ref_index], // final QuadCLT scene, quadCLTs[ref_index], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false, // toRGB, // final boolean toRGB, false, // toRGB, // final boolean toRGB,
clt_parameters.imp.show_mono_nan,
scenes_suffix+"GPU-SHIFTED-FOREGROUND", // String suffix, scenes_suffix+"GPU-SHIFTED-FOREGROUND", // String suffix,
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5164,6 +5227,7 @@ public class OpticalFlow { ...@@ -5164,6 +5227,7 @@ public class OpticalFlow {
quadCLTs[ref_index], // final QuadCLT scene, quadCLTs[ref_index], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true, // final boolean toRGB, true, // final boolean toRGB,
clt_parameters.imp.show_color_nan,
"GPU-SHIFTED-BACKGROUND", // String suffix, "GPU-SHIFTED-BACKGROUND", // String suffix,
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5181,6 +5245,7 @@ public class OpticalFlow { ...@@ -5181,6 +5245,7 @@ public class OpticalFlow {
quadCLTs[ref_index], // final QuadCLT scene, quadCLTs[ref_index], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false, // final boolean toRGB, false, // final boolean toRGB,
clt_parameters.imp.show_mono_nan,
"GPU-SHIFTED-BACKGROUND", // String suffix, "GPU-SHIFTED-BACKGROUND", // String suffix,
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5244,6 +5309,7 @@ public class OpticalFlow { ...@@ -5244,6 +5309,7 @@ public class OpticalFlow {
} }
} }
if (export_ml_files) { if (export_ml_files) {
if (combo_dsn_final == null) { // always re-read? if (combo_dsn_final == null) { // always re-read?
combo_dsn_final =quadCLTs[ref_index].readDoubleArrayFromModelDirectory( // always re-read? combo_dsn_final =quadCLTs[ref_index].readDoubleArrayFromModelDirectory( // always re-read?
...@@ -5381,6 +5447,8 @@ public class OpticalFlow { ...@@ -5381,6 +5447,8 @@ public class OpticalFlow {
quadCLTs[nscene], // final QuadCLT scene, quadCLTs[nscene], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true, // final boolean toRGB, true, // final boolean toRGB,
clt_parameters.imp.show_color_nan,
"", // String suffix, no suffix here "", // String suffix, no suffix here
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5403,6 +5471,7 @@ public class OpticalFlow { ...@@ -5403,6 +5471,7 @@ public class OpticalFlow {
quadCLTs[nscene], // final QuadCLT scene, quadCLTs[nscene], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false, // final boolean toRGB, false, // final boolean toRGB,
clt_parameters.imp.show_mono_nan,
"", // String suffix, no suffix here "", // String suffix, no suffix here
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5516,6 +5585,7 @@ public class OpticalFlow { ...@@ -5516,6 +5585,7 @@ public class OpticalFlow {
quadCLTs[nscene], // final QuadCLT scene, quadCLTs[nscene], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
true, // final boolean toRGB, true, // final boolean toRGB,
clt_parameters.imp.show_color_nan,
"", // String suffix, no suffix here "", // String suffix, no suffix here
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5538,6 +5608,7 @@ public class OpticalFlow { ...@@ -5538,6 +5608,7 @@ public class OpticalFlow {
quadCLTs[nscene], // final QuadCLT scene, quadCLTs[nscene], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false, // final boolean toRGB, false, // final boolean toRGB,
clt_parameters.imp.show_mono_nan,
"", // String suffix, no suffix here "", // String suffix, no suffix here
threadsMax, // int threadsMax, threadsMax, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
...@@ -5702,6 +5773,7 @@ public class OpticalFlow { ...@@ -5702,6 +5773,7 @@ public class OpticalFlow {
quadCLTs[nscene], // final QuadCLT scene, quadCLTs[nscene], // final QuadCLT scene,
quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref quadCLTs[ref_index], // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
toRGB, // final boolean toRGB, toRGB, // final boolean toRGB,
(toRGB? clt_parameters.imp.show_color_nan : clt_parameters.imp.show_mono_nan),
"", // String suffix, no suffix here "", // String suffix, no suffix here
QuadCLT.THREADS_MAX, // int threadsMax, QuadCLT.THREADS_MAX, // int threadsMax,
debugLevel); // int debugLevel) debugLevel); // int debugLevel)
......
...@@ -2169,6 +2169,175 @@ public class QuadCLT extends QuadCLTCPU { ...@@ -2169,6 +2169,175 @@ public class QuadCLT extends QuadCLTCPU {
IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3)+" sec, --- Free memory3="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")"); IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3)+" sec, --- Free memory3="+Runtime.getRuntime().freeMemory()+" (of "+Runtime.getRuntime().totalMemory()+")");
} }
public static boolean calibratePhotometric(
CLTParameters clt_parameters,
final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
final double min_strength,
final double max_diff, // 30.0
final int num_refines, // 2
final double [][] combo_dsn_final, // double [][] combo_dsn_final, // dls,
int threadsMax,
final boolean debug)
{
// filter disparity by LMA only, same bg and fg
double [] disparity_ref= combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_DISP].clone();
for (int i = 00; i < disparity_ref.length; i++) {
if (combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_STRENGTH][i] < min_strength) {
disparity_ref[i] = Double.NaN;
} else if (combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_DISP_BG_ALL][i] !=
combo_dsn_final[OpticalFlow.COMBO_DSN_INDX_DISP][i]) {
disparity_ref[i] = Double.NaN;
}
}
ImagePlus img_ref = renderGPUFromDSI(
-1, // final int sensor_mask,
false, // final boolean merge_channels,
null, // final Rectangle full_woi_in, // show larger than sensor WOI in tiles (or null)
clt_parameters, // CLTParameters clt_parameters,
disparity_ref, // double [] disparity_ref,
OpticalFlow.ZERO3, // final double [] scene_xyz, // camera center in world coordinates
OpticalFlow.ZERO3, // final double [] scene_atr, // camera orientation relative to world frame
ref_scene, // final QuadCLT scene,
ref_scene, // final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
false, // final boolean toRGB,
true, // final boolean show_nan,
"PHOTOMETRIC", // String suffix,
threadsMax, // int threadsMax,
-2); // final int debugLevel);
img_ref.show();
ImageStack imageStack = img_ref.getStack();
int num_sens=imageStack.getSize();
float [] fpixels;
double [][] dpixels = new double [num_sens][];
for (int n = 00; n < num_sens; n++) {
fpixels = (float[]) imageStack.getPixels(n + 1);
dpixels[n] = new double [fpixels.length];
for (int i = 0; i < fpixels.length; i++) {
dpixels[n][i] = fpixels[i];
}
}
// double [][] dpix_orig = new double[num_sens][];
// for (int n = 0; n < num_sens; n++) {
// dpix_orig[n] = dpixels[n].clone();
// }
int width = img_ref.getWidth();
int height = img_ref.getHeight();
int len = width* height;
double [] avg_pix = new double [len];
double [] offsets = new double[dpixels.length];
double [] scales = new double[dpixels.length];
double s0 = 0.0;
double sx= 0.0;
double sx2 = 0.0;
double [] sy = new double[num_sens];
double [] sxy = new double[num_sens];
boolean [] good_pix = new boolean[len];
Arrays.fill(good_pix, true);
for (int nref = 0; nref < num_refines; nref++) {
Arrays.fill(avg_pix, 0.0);
for (int i = 0; i < len; i++) {
for (int n = 0; n < num_sens; n++) {
avg_pix[i]+=dpixels[n][i];
good_pix[i] &= !Double.isNaN(dpixels[n][i]);
}
avg_pix[i] /= dpixels.length;
}
Arrays.fill(offsets,0.0);
Arrays.fill(scales,0.0);
s0 = 0.0;
sx= 0.0;
sx2 = 0.0;
Arrays.fill(sy,0.0);
Arrays.fill(sxy,0.0);
for (int i = 0; i < len; i++) if (good_pix[i]) { // !Double.isNaN(avg_pix[i])){
s0 += 1.0;
sx += avg_pix[i];
sx2 += avg_pix[i] * avg_pix[i];
for (int n = 0; n < num_sens; n++) {
sy[n] += dpixels[n][i];
sxy[n] += dpixels[n][i] * avg_pix[i];
}
}
for (int n = 0; n < num_sens; n++) {
double d = s0 * sx2 + sx * sy[n];
scales[n] = (sxy[n] * s0 + sy[n] * sy[n]) / d;
offsets[n] = (sy[n] * sx2 -sxy[n]*sx) / d;
}
if (debug) {
System.out.println("calibratePhotometric() nref="+nref);
for (int n = 0; n < num_sens; n++) {
System.out.println(String.format("%2d: %8.4f %8.6f", n,offsets[n],scales[n]));
}
System.out.println();
double [][] diffs = new double [num_sens][len];
for (int n = 0; n < num_sens; n++) {
Arrays.fill(diffs[n], Double.NaN);
}
for (int i = 0; i < len; i++) if (good_pix[i]) { // if (!Double.isNaN(avg_pix[i])){
for (int n = 0; n < num_sens; n++) {
diffs[n][i] = dpixels[n][i] - (scales[n] * avg_pix[i] + offsets[n]);
}
}
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
diffs,
width,
height,
true,
"photometric-err"+nref);
// dpix_orig[n] = dpixels[n].clone();
double [][] corrected = new double [num_sens][len];
for (int n = 0; n < num_sens; n++) {
Arrays.fill(corrected[n], Double.NaN);
for (int i = 0; i < len; i++) if (!Double.isNaN(dpixels[n][i])){
corrected[n][i] = (dpixels[n][i] - offsets[n])/scales[n];
}
}
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
corrected,
width,
height,
true,
"photometric-corr"+nref);
}
//max_diff
if (nref < (num_refines-1)) {
for (int i = 0; i < len; i++) if (good_pix[i]) { // !Double.isNaN(avg_pix[i])){
for (int n = 0; n < num_sens; n++) {
double diff = Math.abs(dpixels[n][i] - (scales[n] * avg_pix[i] + offsets[n]));
if (diff > max_diff) {
// dpixels[n][i] = Double.NaN;
good_pix[i] = false;
break;
}
}
}
}
}
double [] offsets_old = ref_scene.getLwirOffsets();
double [] scales_old = ref_scene.getLwirScales();
double [] offsets_new = new double[num_sens];
double [] scales_new = new double[num_sens];
for (int n = 0; n < num_sens; n++) {
scales_new[n] = scales_old[n]/scales[n];
// offsets_new[n] = offsets_old[n] - offsets[n] / scales_old[n];
offsets_new[n] = offsets_old[n] + offsets[n] / scales_old[n];
}
System.out.println("calibratePhotometric() Updated calibration:");
for (int n = 0; n < num_sens; n++) {
System.out.println(String.format("%2d: %8.4f %8.6f", n,offsets_new[n],scales_new[n]));
}
System.out.println();
ref_scene.setLwirOffsets(offsets_new);
ref_scene.setLwirScales (scales_new);
return true;
}
public static ImagePlus renderGPUFromDSI( public static ImagePlus renderGPUFromDSI(
final int sensor_mask, final int sensor_mask,
final boolean merge_channels, final boolean merge_channels,
...@@ -2182,10 +2351,11 @@ public class QuadCLT extends QuadCLTCPU { ...@@ -2182,10 +2351,11 @@ public class QuadCLT extends QuadCLTCPU {
final QuadCLT scene, final QuadCLT scene,
final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref final QuadCLT ref_scene, // now - may be null - for testing if scene is rotated ref
final boolean toRGB, final boolean toRGB,
final boolean show_nan,
String suffix, String suffix,
int threadsMax, int threadsMax,
final int debugLevel){ final int debugLevel){
boolean show_nan = toRGB? clt_parameters.imp.show_color_nan : clt_parameters.imp.show_mono_nan; // boolean show_nan = toRGB? clt_parameters.imp.show_color_nan : clt_parameters.imp.show_mono_nan;
double [][] pXpYD =OpticalFlow.transformToScenePxPyD( // now should work with offset ref_scene double [][] pXpYD =OpticalFlow.transformToScenePxPyD( // now should work with offset ref_scene
full_woi_in, // final Rectangle [] extra_woi, // show larger than sensor WOI (or null) full_woi_in, // final Rectangle [] extra_woi, // show larger than sensor WOI (or null)
disparity_ref, // final double [] disparity_ref, // invalid tiles - NaN in disparity disparity_ref, // final double [] disparity_ref, // invalid tiles - NaN in disparity
......
...@@ -151,6 +151,7 @@ public class QuadCLTCPU { ...@@ -151,6 +151,7 @@ public class QuadCLTCPU {
boolean [][] saturation_imp = null; // (near) saturated pixels or null boolean [][] saturation_imp = null; // (near) saturated pixels or null
boolean is_aux = false; boolean is_aux = false;
double [] lwir_offsets = null; // per image subtracted values double [] lwir_offsets = null; // per image subtracted values
double [] lwir_scales = null; // per image scales
double lwir_offset = Double.NaN; // average of lwir_offsets[] double lwir_offset = Double.NaN; // average of lwir_offsets[]
// hot and cold are calculated during autoranging (when generating 4 images for restored (added lwir_offset) // hot and cold are calculated during autoranging (when generating 4 images for restored (added lwir_offset)
// absolute temperatures to be used instead of colorProcParameters lwir_low and lwir_high if autoranging // absolute temperatures to be used instead of colorProcParameters lwir_low and lwir_high if autoranging
...@@ -261,6 +262,7 @@ public class QuadCLTCPU { ...@@ -261,6 +262,7 @@ public class QuadCLTCPU {
this.is_aux = qParent.is_aux; this.is_aux = qParent.is_aux;
// this.is_mono = qParent.is_mono; // this.is_mono = qParent.is_mono;
this.lwir_offsets = ErsCorrection.clone1d(qParent.lwir_offsets); this.lwir_offsets = ErsCorrection.clone1d(qParent.lwir_offsets);
this.lwir_scales = ErsCorrection.clone1d(qParent.lwir_scales);
this.lwir_offset = qParent.lwir_offset; this.lwir_offset = qParent.lwir_offset;
this.lwir_cold_hot = ErsCorrection.clone1d(qParent.lwir_cold_hot); this.lwir_cold_hot = ErsCorrection.clone1d(qParent.lwir_cold_hot);
this.ds_from_main = ErsCorrection.clone2d(qParent.ds_from_main); this.ds_from_main = ErsCorrection.clone2d(qParent.ds_from_main);
...@@ -1478,6 +1480,37 @@ public class QuadCLTCPU { ...@@ -1478,6 +1480,37 @@ public class QuadCLTCPU {
public double getLwirOffset() {return lwir_offset;} // USED in lwir public double getLwirOffset() {return lwir_offset;} // USED in lwir
public boolean isLwirCalibrated() {
return lwir_offsets != null;
}
public double [] getLwirOffsets() {
if (lwir_offsets == null) {
lwir_offsets = new double [getNumSensors()];
}
return lwir_offsets;
}
public double [] getLwirScales() {
if (lwir_scales == null) {
lwir_scales = new double [getNumSensors()];
Arrays.fill(lwir_scales, 1.0);
}
return lwir_scales;
}
public void setLwirOffsets(double [] offsets) {
lwir_offsets = offsets; // will need to update properties!
if (offsets != null) {
double s = 0;
for (double offset:offsets) s+=offset;
lwir_offset = s/offsets.length;
} else {
lwir_offset = Double.NaN;
}
}
public void setLwirScales(double [] scales) {
lwir_scales = scales; // will need to update properties!
}
public double [] getColdHot() { // USED in lwir public double [] getColdHot() { // USED in lwir
return lwir_cold_hot; return lwir_cold_hot;
} }
...@@ -1668,6 +1701,14 @@ public class QuadCLTCPU { ...@@ -1668,6 +1701,14 @@ public class QuadCLTCPU {
} }
properties.setProperty(prefix+"num_orient", this.num_orient+""); properties.setProperty(prefix+"num_orient", this.num_orient+"");
properties.setProperty(prefix+"num_accum", this.num_accum+""); properties.setProperty(prefix+"num_accum", this.num_accum+"");
if (this.lwir_offsets != null) {
properties.setProperty(prefix+"lwir_offsets",
IntersceneMatchParameters.doublesToString(this.lwir_offsets));
}
if (this.lwir_scales != null) {
properties.setProperty(prefix+"lwir_scales",
IntersceneMatchParameters.doublesToString(this.lwir_scales));
}
} }
...@@ -1697,7 +1738,19 @@ public class QuadCLTCPU { ...@@ -1697,7 +1738,19 @@ public class QuadCLTCPU {
this.num_accum = Integer.parseInt(other_properties.getProperty(other_prefix+"num_accum")); this.num_accum = Integer.parseInt(other_properties.getProperty(other_prefix+"num_accum"));
properties.setProperty(this_prefix+"num_accum", this.num_accum+""); properties.setProperty(this_prefix+"num_accum", this.num_accum+"");
} }
// copy offsets and scales
if (other_properties.getProperty(other_prefix+"lwir_offsets")!=null) {
this.lwir_offsets= IntersceneMatchParameters.StringToDoubles(
other_properties.getProperty(other_prefix+"lwir_offsets"),0);
properties.setProperty(this_prefix+"lwir_offsets",
IntersceneMatchParameters.doublesToString(this.lwir_offsets));
}
if (other_properties.getProperty(other_prefix+"lwir_scales")!=null) {
this.lwir_scales= IntersceneMatchParameters.StringToDoubles(
other_properties.getProperty(other_prefix+"lwir_scales"),0);
properties.setProperty(this_prefix+"lwir_scales",
IntersceneMatchParameters.doublesToString(this.lwir_scales));
}
/* /*
...@@ -1803,8 +1856,24 @@ public class QuadCLTCPU { ...@@ -1803,8 +1856,24 @@ public class QuadCLTCPU {
geometryCorrection.setRigOffsetFromProperies(prefix, properties); geometryCorrection.setRigOffsetFromProperies(prefix, properties);
} }
// inter-frame properties only make sense for, well, scenes. So they will only be read // inter-frame properties only make sense for, well, scenes. So they will only be read
if (properties.getProperty(prefix+"num_orient")!=null) this.num_orient=Integer.parseInt(properties.getProperty(prefix+"num_orient")); if (properties.getProperty(prefix+"num_orient")!=null) {
if (properties.getProperty(prefix+"num_accum")!=null) this.num_accum= Integer.parseInt(properties.getProperty(prefix+"num_accum")); this.num_orient=Integer.parseInt(properties.getProperty(prefix+"num_orient"));
}
if (properties.getProperty(prefix+"num_accum")!=null) {
this.num_accum= Integer.parseInt(properties.getProperty(prefix+"num_accum"));
}
if (properties.getProperty(prefix+"lwir_offsets")!=null) {
this.lwir_offsets= IntersceneMatchParameters.StringToDoubles(
properties.getProperty(prefix+"lwir_offsets"),0);
}
if (properties.getProperty(prefix+"lwir_scales")!=null) {
this.lwir_scales= IntersceneMatchParameters.StringToDoubles(
properties.getProperty(prefix+"lwir_scales"),0);
}
} }
public void setKernelImageFile(ImagePlus img_kernels){ // not used in lwir public void setKernelImageFile(ImagePlus img_kernels){ // not used in lwir
...@@ -4889,6 +4958,7 @@ public class QuadCLTCPU { ...@@ -4889,6 +4958,7 @@ public class QuadCLTCPU {
boolean lwir_subtract_dc = colorProcParameters.lwir_subtract_dc; boolean lwir_subtract_dc = colorProcParameters.lwir_subtract_dc;
boolean lwir_eq_chn = colorProcParameters.lwir_eq_chn; boolean lwir_eq_chn = colorProcParameters.lwir_eq_chn;
boolean correct_vignetting = colorProcParameters.correct_vignetting; boolean correct_vignetting = colorProcParameters.correct_vignetting;
boolean recalc_lwir_offsets = false;
final Thread[] threads = ImageDtt.newThreadArray(threadsMax); final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0); final AtomicInteger ai = new AtomicInteger(0);
...@@ -5176,13 +5246,16 @@ public class QuadCLTCPU { ...@@ -5176,13 +5246,16 @@ public class QuadCLTCPU {
debugLevel); debugLevel);
} }
if (is_lwir && (lwir_subtract_dc || lwir_eq_chn)) { if (is_lwir && (lwir_subtract_dc || lwir_eq_chn)) {
this.lwir_offsets = channelLwirEqualize( if (recalc_lwir_offsets || !isLwirCalibrated()) {
// this.lwir_offsets =
setLwirOffsets(
channelLwirEqualize( // now only calculates offsets, does not apply
channelFiles, channelFiles,
imp_srcs, imp_srcs,
lwir_subtract_dc, // boolean remove_dc, lwir_subtract_dc, // boolean remove_dc,
set_name, // just for debug messages == setNames.get(nSet) set_name, // just for debug messages == setNames.get(nSet)
threadsMax, threadsMax,
debugLevel); debugLevel));
int num_avg = 0; int num_avg = 0;
this.lwir_offset = 0.0; this.lwir_offset = 0.0;
for (int srcChannel=0; srcChannel < channelFiles.length; srcChannel++){ for (int srcChannel=0; srcChannel < channelFiles.length; srcChannel++){
...@@ -5194,6 +5267,16 @@ public class QuadCLTCPU { ...@@ -5194,6 +5267,16 @@ public class QuadCLTCPU {
} }
this.lwir_offset /= num_avg; this.lwir_offset /= num_avg;
} }
double [] offsets = getLwirOffsets();
double [] scales = getLwirScales();
channelLwirApplyEqualize( // now apply (was part of channelLwirEqualize() )
channelFiles, // int [] channelFiles,
imp_srcs, // ImagePlus [] imp_srcs,
offsets, // double [] offsets,
scales, // double [] scales,
threadsMax,
debugLevel);
}
// 08/12/2020 common part moved here, from getRigImageStacks() // 08/12/2020 common part moved here, from getRigImageStacks()
image_name = (String) imp_srcs[0].getProperty("name"); image_name = (String) imp_srcs[0].getProperty("name");
image_path= (String) imp_srcs[0].getProperty("path"); image_path= (String) imp_srcs[0].getProperty("path");
...@@ -5686,6 +5769,7 @@ public class QuadCLTCPU { ...@@ -5686,6 +5769,7 @@ public class QuadCLTCPU {
} }
} }
} }
public static double [] channelLwirEqualize( // USED in lwir public static double [] channelLwirEqualize( // USED in lwir
int [] channelFiles, int [] channelFiles,
ImagePlus [] imp_srcs, ImagePlus [] imp_srcs,
...@@ -5705,11 +5789,7 @@ public class QuadCLTCPU { ...@@ -5705,11 +5789,7 @@ public class QuadCLTCPU {
public void run() { public void run() {
double [] wnd_x; double [] wnd_x;
double [] wnd_y; double [] wnd_y;
// for (int srcChannel=0; srcChannel<channelFiles.length; srcChannel++){
for (int srcChannel = ai.getAndIncrement(); srcChannel < channelFiles.length; srcChannel = ai.getAndIncrement()) { for (int srcChannel = ai.getAndIncrement(); srcChannel < channelFiles.length; srcChannel = ai.getAndIncrement()) {
// for (int srcChannel=0; srcChannel < channelFiles.length; srcChannel++){
int nFile=channelFiles[srcChannel]; int nFile=channelFiles[srcChannel];
if (nFile >=0){ if (nFile >=0){
avr_pix[srcChannel][0] = 0.0; avr_pix[srcChannel][0] = 0.0;
...@@ -5717,18 +5797,14 @@ public class QuadCLTCPU { ...@@ -5717,18 +5797,14 @@ public class QuadCLTCPU {
float [] pixels=(float []) imp_srcs[srcChannel].getProcessor().getPixels(); float [] pixels=(float []) imp_srcs[srcChannel].getProcessor().getPixels();
int width = imp_srcs[srcChannel].getWidth(); int width = imp_srcs[srcChannel].getWidth();
int height = imp_srcs[srcChannel].getHeight(); int height = imp_srcs[srcChannel].getHeight();
// if (wnd_x.length != width) {
wnd_x = new double[width]; wnd_x = new double[width];
for (int i = 0; i < width; i++) { for (int i = 0; i < width; i++) {
wnd_x[i] = 0.5 - 0.5*Math.cos(2*Math.PI * (i+1) / (width + 1)); wnd_x[i] = 0.5 - 0.5*Math.cos(2*Math.PI * (i+1) / (width + 1));
} }
// }
// if (wnd_y.length != height) {
wnd_y = new double[height]; wnd_y = new double[height];
for (int i = 0; i < height; i++) { for (int i = 0; i < height; i++) {
wnd_y[i] = 0.5 - 0.5*Math.cos(2*Math.PI * (i+1) / (height + 1)); wnd_y[i] = 0.5 - 0.5*Math.cos(2*Math.PI * (i+1) / (height + 1));
} }
// }
int indx = 0; int indx = 0;
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
...@@ -5737,8 +5813,6 @@ public class QuadCLTCPU { ...@@ -5737,8 +5813,6 @@ public class QuadCLTCPU {
avr_pix[srcChannel][1] += w; avr_pix[srcChannel][1] += w;
} }
} }
// total_s += avr_pix[srcChannel][0];
// total_w += avr_pix[srcChannel][1];
atotal_s.accumulate(avr_pix[srcChannel][0]); atotal_s.accumulate(avr_pix[srcChannel][0]);
atotal_w.accumulate(avr_pix[srcChannel][1]); atotal_w.accumulate(avr_pix[srcChannel][1]);
avr_pix[srcChannel][0]/=avr_pix[srcChannel][1]; // weighted average avr_pix[srcChannel][0]/=avr_pix[srcChannel][1]; // weighted average
...@@ -5748,7 +5822,6 @@ public class QuadCLTCPU { ...@@ -5748,7 +5822,6 @@ public class QuadCLTCPU {
}; };
} }
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
// double avg = total_s/total_w;
double avg = atotal_s.get()/atotal_w.get(); double avg = atotal_s.get()/atotal_w.get();
if (!remove_dc) { // not used in lwir if (!remove_dc) { // not used in lwir
...@@ -5766,12 +5839,41 @@ public class QuadCLTCPU { ...@@ -5766,12 +5839,41 @@ public class QuadCLTCPU {
for (int srcChannel = ai.getAndIncrement(); srcChannel < channelFiles.length; srcChannel = ai.getAndIncrement()) { for (int srcChannel = ai.getAndIncrement(); srcChannel < channelFiles.length; srcChannel = ai.getAndIncrement()) {
int nFile=channelFiles[srcChannel]; int nFile=channelFiles[srcChannel];
if (nFile >=0) { if (nFile >=0) {
// offsets[srcChannel]= (avr_pix[srcChannel][0] - (remove_dc ? 0.0: avg));
offsets[srcChannel]= avr_pix[srcChannel][0]; offsets[srcChannel]= avr_pix[srcChannel][0];
// float fd = (float)offsets[srcChannel];
// float [] pixels = (float []) imp_srcs[srcChannel].getProcessor().getPixels();
// for (int i = 0; i < pixels.length; i++) {
// pixels[i] -= fd;
// }
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return offsets;
}
public static void channelLwirApplyEqualize(
int [] channelFiles,
ImagePlus [] imp_srcs,
double [] offsets,
double [] scales,
final int threadsMax,
int debugLevel){
final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int srcChannel = ai.getAndIncrement(); srcChannel < channelFiles.length; srcChannel = ai.getAndIncrement()) {
int nFile=channelFiles[srcChannel];
if (nFile >=0) {
float fd = (float)offsets[srcChannel]; float fd = (float)offsets[srcChannel];
float fscale = (float) scales[srcChannel];
float [] pixels = (float []) imp_srcs[srcChannel].getProcessor().getPixels(); float [] pixels = (float []) imp_srcs[srcChannel].getProcessor().getPixels();
for (int i = 0; i < pixels.length; i++) { for (int i = 0; i < pixels.length; i++) {
pixels[i] -= fd; pixels[i] = (pixels[i] - fd) * fscale;
} }
} }
} }
...@@ -5779,9 +5881,10 @@ public class QuadCLTCPU { ...@@ -5779,9 +5881,10 @@ public class QuadCLTCPU {
}; };
} }
ImageDtt.startAndJoin(threads); ImageDtt.startAndJoin(threads);
return offsets;
} }
// public ImagePlus [] processCLTQuadCorrCPU( // USED in lwir // public ImagePlus [] processCLTQuadCorrCPU( // USED in lwir
public void processCLTQuadCorrCPU( // USED in lwir public void processCLTQuadCorrCPU( // USED in lwir
// ImagePlus [] imp_quad, // should have properties "name"(base for saving results), "channel","path" // ImagePlus [] imp_quad, // should have properties "name"(base for saving results), "channel","path"
......
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