Commit 8ad607c6 authored by Andrey Filippov's avatar Andrey Filippov

working on motion vectors strength equalization

parent ad8191c2
...@@ -2802,6 +2802,19 @@ public class ImageDtt extends ImageDttCPU { ...@@ -2802,6 +2802,19 @@ public class ImageDtt extends ImageDttCPU {
} }
if (half_disparity > 0.0) { // scale by disparity if (half_disparity > 0.0) { // scale by disparity
mv[nTile][2] *= half_disparity/(half_disparity + pxd[nTile][2]); mv[nTile][2] *= half_disparity/(half_disparity + pxd[nTile][2]);
// } else { // temporary, testing, make equalization?
// double disp0 = 5.0;
// if (pxd[nTile][2] > disp0) {
// mv[nTile][2] *= pxd[nTile][2]/disp0;
// }
/*
} else {
double disp0 = 5.0;
if (pxd[nTile][2] > disp0) {
mv[nTile][2] *= 10; // pxd[nTile][2]/disp0;
}
*/
} }
if ((half_avg_diff > 0.0) &&(num_neibs > 0)) { if ((half_avg_diff > 0.0) &&(num_neibs > 0)) {
double dx = mv[nTile][0] - sx / num_neibs; double dx = mv[nTile][0] - sx / num_neibs;
......
...@@ -185,8 +185,8 @@ public class IntersceneMatchParameters { ...@@ -185,8 +185,8 @@ public class IntersceneMatchParameters {
public double min_str_fpn = 0.2; // 0.25; // minimal correlation strength for all but TD-accumulated layer public double min_str_fpn = 0.2; // 0.25; // minimal correlation strength for all but TD-accumulated layer
public double min_str_sum_fpn = 0.5; // 0.8; // minimal correlation strength for TD-accumulated layer public double min_str_sum_fpn = 0.5; // 0.8; // minimal correlation strength for TD-accumulated layer
public double min_str = 0.18; // tiles w/o FPN: minimal correlation strength for all but TD-accumulated layer public double min_str = 0.12; //18; // tiles w/o FPN: minimal correlation strength for all but TD-accumulated layer
public double min_str_sum = 0.33; // tiles w/o FPN: minimal correlation strength for TD-accumulated layer public double min_str_sum = 0.2; // 0.33; // tiles w/o FPN: minimal correlation strength for TD-accumulated layer
public int min_neibs = 2; // minimal number of strong neighbors (> min_str) public int min_neibs = 2; // minimal number of strong neighbors (> min_str)
public double weight_zero_neibs = 0.2; // Reduce weight for no-neib (1.0 for all 8) public double weight_zero_neibs = 0.2; // Reduce weight for no-neib (1.0 for all 8)
...@@ -194,7 +194,7 @@ public class IntersceneMatchParameters { ...@@ -194,7 +194,7 @@ public class IntersceneMatchParameters {
public double half_avg_diff = 0.2; // when L2 of x,y difference from average of neibs - reduce twice public double half_avg_diff = 0.2; // when L2 of x,y difference from average of neibs - reduce twice
// Detect initial match // Detect initial match
public double min_ref_str = 0.22; // For orientations: use only tiles of the reference scene DSI_MAIN is stronger public double min_ref_str = 0.15; // 0.22; // For orientations: use only tiles of the reference scene DSI_MAIN is stronger
public int pix_step = 4; // Azimuth/tilt search step in pixels public int pix_step = 4; // Azimuth/tilt search step in pixels
public int search_rad = 10; // Search radius in steps public int search_rad = 10; // Search radius in steps
public double maybe_sum = 1.0; // minimal sum of strengths (will search for the best) public double maybe_sum = 1.0; // minimal sum of strengths (will search for the best)
......
...@@ -45,6 +45,7 @@ import com.elphel.imagej.cameras.CLTParameters; ...@@ -45,6 +45,7 @@ import com.elphel.imagej.cameras.CLTParameters;
import com.elphel.imagej.cameras.ColorProcParameters; import com.elphel.imagej.cameras.ColorProcParameters;
import com.elphel.imagej.cameras.EyesisCorrectionParameters; import com.elphel.imagej.cameras.EyesisCorrectionParameters;
import com.elphel.imagej.common.DoubleGaussianBlur; import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.PolynomialApproximation;
import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.correction.CorrectionColorProc; import com.elphel.imagej.correction.CorrectionColorProc;
import com.elphel.imagej.correction.EyesisCorrections; import com.elphel.imagej.correction.EyesisCorrections;
...@@ -2426,20 +2427,234 @@ public class QuadCLT extends QuadCLTCPU { ...@@ -2426,20 +2427,234 @@ public class QuadCLT extends QuadCLTCPU {
} }
double [] offsets_old = ref_scene.getLwirOffsets(); double [] offsets_old = ref_scene.getLwirOffsets();
double [] scales_old = ref_scene.getLwirScales(); double [] scales_old = ref_scene.getLwirScales();
double [] scales2_old = ref_scene.getLwirScales2();
double [] offsets_new = new double[num_sens]; double [] offsets_new = new double[num_sens];
double [] scales_new = new double[num_sens]; double [] scales_new = new double[num_sens];
double [] scales2_new = new double[num_sens];
for (int n = 0; n < num_sens; n++) { for (int n = 0; n < num_sens; n++) {
scales_new[n] = scales_old[n]/scales[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]; offsets_new[n] = offsets_old[n] + offsets[n] / scales_old[n];
} }
System.out.println("calibratePhotometric() Updated calibration:"); System.out.println("calibratePhotometric() Updated calibration:");
for (int n = 0; n < num_sens; n++) { 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(String.format("%2d: %8.4f %8.6f %8.6f", n,offsets_new[n],scales_new[n], scales2_new[n]));
} }
System.out.println(); System.out.println();
ref_scene.setLwirOffsets(offsets_new); ref_scene.setLwirOffsets (offsets_new);
ref_scene.setLwirScales (scales_new); ref_scene.setLwirScales (scales_new);
ref_scene.setLwirScales2 (scales2_new);
return true;
}
public static boolean calibratePhotometric2( // quadratic
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 = 0; 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];
}
}
boolean quadratic = true;
// 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];
double [][] pa_coeff = new double[num_sens][];
Arrays.fill(good_pix, true);
for (int nref = 0; nref < num_refines; nref++) {
Arrays.fill(avg_pix, 0.0);
int num_good = 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;
if (good_pix[i]) {
num_good++;
}
}
double [][] pa_data = new double [num_good][2];
for (int nsens = 0; nsens < num_sens; nsens++) {
int indx = 0;
for (int i = 0; i < len; i++) if (good_pix[i]){
pa_data[indx][0] = dpixels[nsens][i];
pa_data[indx][1] = avg_pix[i];
indx++;
}
// quadratic
pa_coeff[nsens] =(new PolynomialApproximation(0)).polynomialApproximation1d(pa_data, quadratic ? 2 : 1);
}
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 %8.6f", n,pa_coeff[n][0],pa_coeff[n][1], 1e6*pa_coeff[n][2]));
}
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]);
diffs[n][i] = -(avg_pix[i] - pa_coeff[n][2] * dpixels[n][i] * dpixels[n][i] - pa_coeff[n][1] * dpixels[n][i] - pa_coeff[n][0]);
}
}
(new ShowDoubleFloatArrays()).showArrays( // out of boundary 15
diffs,
width,
height,
true,
"photometric-quad-err"+nref);
}
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 [] scales2_old = ref_scene.getLwirScales2();
double [] offsets_new = new double[num_sens];
double [] scales_new = new double[num_sens];
double [] scales2_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];
}
System.out.println("calibratePhotometric() Updated calibration:");
for (int n = 0; n < num_sens; n++) {
System.out.println(String.format("%2d: %8.4f %8.6f %8.6f", n,offsets_new[n],scales_new[n], scales2_new[n]));
}
System.out.println();
ref_scene.setLwirOffsets (offsets_new);
ref_scene.setLwirScales (scales_new);
ref_scene.setLwirScales2 (scales2_new);
return true; return true;
} }
......
...@@ -153,7 +153,7 @@ public class QuadCLTCPU { ...@@ -153,7 +153,7 @@ public class QuadCLTCPU {
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_scales = null; // per image scales
//double [] lwir_scales2 = null; // per image quadratic scales double [] lwir_scales2 = null; // per image quadratic scales
@Deprecated @Deprecated
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)
...@@ -266,6 +266,7 @@ public class QuadCLTCPU { ...@@ -266,6 +266,7 @@ public class QuadCLTCPU {
// 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_scales = ErsCorrection.clone1d(qParent.lwir_scales);
this.lwir_scales2 = ErsCorrection.clone1d(qParent.lwir_scales2);
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);
...@@ -1798,6 +1799,12 @@ public class QuadCLTCPU { ...@@ -1798,6 +1799,12 @@ public class QuadCLTCPU {
} }
return lwir_scales; return lwir_scales;
} }
public double [] getLwirScales2() {
if (lwir_scales2 == null) {
lwir_scales2 = new double [getNumSensors()]; // all 0;
}
return lwir_scales2;
}
public void setLwirOffsets(double [] offsets) { public void setLwirOffsets(double [] offsets) {
lwir_offsets = offsets; // will need to update properties! lwir_offsets = offsets; // will need to update properties!
if (offsets != null) { if (offsets != null) {
...@@ -1812,6 +1819,9 @@ public class QuadCLTCPU { ...@@ -1812,6 +1819,9 @@ public class QuadCLTCPU {
public void setLwirScales(double [] scales) { public void setLwirScales(double [] scales) {
lwir_scales = scales; // will need to update properties! lwir_scales = scales; // will need to update properties!
} }
public void setLwirScales2(double [] scales2) {
lwir_scales2 = scales2; // 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;
...@@ -2011,6 +2021,10 @@ public class QuadCLTCPU { ...@@ -2011,6 +2021,10 @@ public class QuadCLTCPU {
properties.setProperty(prefix+"lwir_scales", properties.setProperty(prefix+"lwir_scales",
IntersceneMatchParameters.doublesToString(this.lwir_scales)); IntersceneMatchParameters.doublesToString(this.lwir_scales));
} }
if (this.lwir_scales2 != null) {
properties.setProperty(prefix+"lwir_scales2",
IntersceneMatchParameters.doublesToString(this.lwir_scales2));
}
} }
...@@ -2053,6 +2067,12 @@ public class QuadCLTCPU { ...@@ -2053,6 +2067,12 @@ public class QuadCLTCPU {
properties.setProperty(this_prefix+"lwir_scales", properties.setProperty(this_prefix+"lwir_scales",
IntersceneMatchParameters.doublesToString(this.lwir_scales)); IntersceneMatchParameters.doublesToString(this.lwir_scales));
} }
if (other_properties.getProperty(other_prefix+"lwir_scales2")!=null) {
this.lwir_scales2= IntersceneMatchParameters.StringToDoubles(
other_properties.getProperty(other_prefix+"lwir_scales2"),0);
properties.setProperty(this_prefix+"lwir_scales2",
IntersceneMatchParameters.doublesToString(this.lwir_scales2));
}
/* /*
...@@ -2173,6 +2193,10 @@ public class QuadCLTCPU { ...@@ -2173,6 +2193,10 @@ public class QuadCLTCPU {
this.lwir_scales= IntersceneMatchParameters.StringToDoubles( this.lwir_scales= IntersceneMatchParameters.StringToDoubles(
properties.getProperty(prefix+"lwir_scales"),0); properties.getProperty(prefix+"lwir_scales"),0);
} }
if (properties.getProperty(prefix+"lwir_scales2")!=null) {
this.lwir_scales2= IntersceneMatchParameters.StringToDoubles(
properties.getProperty(prefix+"lwir_scales2"),0);
}
...@@ -5572,11 +5596,13 @@ public class QuadCLTCPU { ...@@ -5572,11 +5596,13 @@ public class QuadCLTCPU {
} }
double [] offsets = getLwirOffsets(); double [] offsets = getLwirOffsets();
double [] scales = getLwirScales(); double [] scales = getLwirScales();
double [] scales2 = getLwirScales2();
channelLwirApplyEqualize( // now apply (was part of channelLwirEqualize() ) channelLwirApplyEqualize( // now apply (was part of channelLwirEqualize() )
channelFiles, // int [] channelFiles, channelFiles, // int [] channelFiles,
imp_srcs, // ImagePlus [] imp_srcs, imp_srcs, // ImagePlus [] imp_srcs,
offsets, // double [] offsets, offsets, // double [] offsets,
scales, // double [] scales, scales, // double [] scales,
scales2, // double [] scales2,
threadsMax, threadsMax,
debugLevel); debugLevel);
} }
...@@ -6162,6 +6188,7 @@ public class QuadCLTCPU { ...@@ -6162,6 +6188,7 @@ public class QuadCLTCPU {
ImagePlus [] imp_srcs, ImagePlus [] imp_srcs,
double [] offsets, double [] offsets,
double [] scales, double [] scales,
double [] scales2,
final int threadsMax, final int threadsMax,
int debugLevel){ int debugLevel){
final Thread[] threads = ImageDtt.newThreadArray(threadsMax); final Thread[] threads = ImageDtt.newThreadArray(threadsMax);
...@@ -6174,9 +6201,11 @@ public class QuadCLTCPU { ...@@ -6174,9 +6201,11 @@ public class QuadCLTCPU {
if (nFile >=0) { if (nFile >=0) {
float fd = (float)offsets[srcChannel]; float fd = (float)offsets[srcChannel];
float fscale = (float) scales[srcChannel]; float fscale = (float) scales[srcChannel];
float fscale2 = (float) scales2[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] = (pixels[i] - fd) * fscale; float poffs = (pixels[i] - fd);
pixels[i] = poffs * fscale + poffs*poffs*fscale2;
} }
} }
} }
......
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