Commit fabeb071 authored by Andrey Filippov's avatar Andrey Filippov

improving fine adjustment

parent 92f321f5
......@@ -23,15 +23,15 @@
*/
import java.util.ArrayList;
//import GeometryCorrection.CorrVector;
import Jama.Matrix;
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.WindowManager;
public class AlignmentCorrection {
static int NUM_SLICES = 10; // disp, strength, dx0, dy0, dx1, dy1, dx2, dy2, dx3, dy3)
static int NUM_ALL_SLICES = 14; // disp, strength, dx0, dy0, str0, dx1, dy1, str1, dx2, dy2, str2, dx3, dy3 str3,)
static final int NUM_SLICES = 10; // disp, strength, dx0, dy0, dx1, dy1, dx2, dy2, dx3, dy3)
static final int NUM_ALL_SLICES = 14; // disp, strength, dx0, dy0, str0, dx1, dy1, str1, dx2, dy2, str2, dx3, dy3 str3,)
static final int NUM_SENSORS = 4;
QuadCLT qc;
public class Sample{
......@@ -46,13 +46,89 @@ public class AlignmentCorrection {
}
}
public class Mismatch{
public double [] pXY; // tile center x,y
public double disparity_task;
public double disparity_meas;
public double strength;
public double [] offsets;
public Mismatch()
{
pXY = new double[2];
disparity_task = 0.0;
disparity_meas = 0.0;
strength = 0.0;
offsets = new double[2*NUM_SENSORS];
}
public Mismatch (
double [] pXY, // tile center x,y
double disparity_task,
double disparity_meas,
double strength,
double [] offsets )
{
this.pXY = pXY;
this.disparity_task = disparity_task;
this.disparity_meas = disparity_meas;
this.strength = strength;
this.offsets = offsets;
}
public Mismatch (
double [] pXY, // tile center x,y
double disparity_task,
double disparity_meas,
double strength,
double [][] offsets )
{
this.pXY = pXY;
this.disparity_task = disparity_task;
this.disparity_meas = disparity_meas;
this.strength = strength;
this.offsets = new double [NUM_SENSORS * 2];
for (int i = 0; i < NUM_SENSORS; i++){
this.offsets[i*2 + 0] = offsets[i][0];
this.offsets[i*2 + 1] = offsets[i][1];
}
}
public double [] getPXY(){
return pXY;
}
public double getDisparityTask() {
return disparity_task;
}
public double getDisparityMeas() {
return disparity_meas;
}
public double getStrength() {
return strength;
}
public void copyToY(
double [] y,
int n_sample)
{
System.arraycopy(this.offsets, 0, y, n_sample * (2 * NUM_SENSORS), (2 * NUM_SENSORS));
}
public void copyToW(
double [] w,
int n_sample)
{
for (int i = n_sample * (2 * NUM_SENSORS); i < (n_sample + 1) * (2 * NUM_SENSORS); i++){
w[i] = strength;
}
}
}
//System.arraycopy(dpixels, (tileY*width+tileX)*dct_size + i*width, tile_in, i*n2, n2);
AlignmentCorrection (QuadCLT qc){
this.qc = qc;
}
public double [][][] infinityCorrection(
final boolean use_poly,
final double min_strength_in,
final double max_diff,
final int max_iterations,
......@@ -153,34 +229,14 @@ public class AlignmentCorrection {
tilesX,
magic_coeff, // still not understood coefficient that reduces reported disparity value. Seems to be around 8.5
debugLevel);
/*
double [][][] disparity_corr_coefficiants = null;
if (clt_parameters.inf_disp_apply) {
disparity_corr_coefficiants = infinityCorrection(
clt_parameters.fcorr_inf_vert,// final boolean use_vertical,
// min_strength,
// max_diff,
// max_iterations,
// max_coeff_diff,
// far_pull, // = 0.2; // 1; // 0.5;
clt_parameters,
disp_strength,
samples_list,
tilesX,
magic_coeff, // still not understood coefficient that reduces reported disparity value. Seems to be around 8.5
debugLevel);
if (debugLevel > -1){
System.out.println("infinityCorrection(): coefficient increments from infinityCorrection");
show_fine_corr(
disparity_corr_coefficiants, // double [][][] corr,
"");// String prefix)
}
}
*/
double [][][] mismatch_corr_coefficiants = null;
// if (clt_parameters.inf_disp_apply) {
ArrayList<Mismatch> mismatch_list = use_poly? null : (new ArrayList<Mismatch>());
mismatch_corr_coefficiants = infinityMismatchCorrection(
clt_parameters.disp_scan_start, // final double disp_scan_start,
clt_parameters.disp_scan_step, // final double disp_scan_step,
use_poly, // clt_parameters.ly_poly, // final boolean use_poly,
clt_parameters.fcorr_inf_quad, // final boolean use_quadratic,
clt_parameters.fcorr_inf_vert, // final boolean use_vertical,
clt_parameters.ly_inf_en, // final boolean use_disparity, // for infinity
......@@ -189,6 +245,7 @@ public class AlignmentCorrection {
samples_list,
tilesX,
magic_coeff, // still not understood coefficient that reduces reported disparity value. Seems to be around 8.5
mismatch_list, // ArrayList<Mismatch> mismatch_list,
debugLevel);
if (debugLevel > -1){
System.out.println("infinityCorrection(): coefficient increments from infinityMismatchCorrection");
......@@ -441,11 +498,11 @@ public class AlignmentCorrection {
* @return per sub-camera, per direction (x,y) 6 quadratic polynomial coefficients, same format as fine_geometry_correction()
*/
public double [][][] infinityCorrection(
// final double min_strength0,
// final double max_diff0,
// final int max_iterations0,
// final double max_coeff_diff0,
// final double far_pull0, // = 0.2; // 1; // 0.5;
// final double min_strength0,
// final double max_diff0,
// final int max_iterations0,
// final double max_coeff_diff0,
// final double far_pull0, // = 0.2; // 1; // 0.5;
final boolean use_vertical,
EyesisCorrectionParameters.CLTParameters clt_parameters,
double [][] disp_strength,
......@@ -589,6 +646,8 @@ public class AlignmentCorrection {
* Correct channel mismatch (preserving disparity) using the same tiles as those for correcting disparity
* at infinity
* Next parameters are made separate to be able to modify them between different runs keeping clt_parameters
* @param use_poly calculate quadratic/linear correction (can not work with high disparity).
* False - adjust extrinsics (tilt, azimuth, roll)
* @param clt_parameters CLT parameters
* @param disp_strength array of a single or multiple disparity/strength pairs (0,2, .. - disparity,
* 1,3,.. - corresponding strengths
......@@ -596,10 +655,14 @@ public class AlignmentCorrection {
* tile index and (possibly modified) weight of each tile
* @param tilesX number of tiles in each data line
* @param magic_coeff still not understood coefficient that reduces reported disparity value. Seems to be around 0.85
* @param mismatch_list data to calculate extrinsic corrections or null
* @param debugLevel debug level
* @return per sub-camera, per direction (x,y) 6 quadratic polynomial coefficients, same format as fine_geometry_correction()
*/
public double [][][] infinityMismatchCorrection(
final double disp_scan_start,
final double disp_scan_step,
final boolean use_poly,
final boolean use_quadratic,
final boolean use_vertical,
final boolean use_disparity, // for infinity
......@@ -608,6 +671,7 @@ public class AlignmentCorrection {
ArrayList<Sample> samples_list,
int tilesX,
double magic_coeff, // still not understood coefficient that reduces reported disparity value. Seems to be around 8.5
ArrayList<Mismatch> mismatch_list,
int debugLevel)
{
// Mismatch data has disparity values already subtracted, so to correct disparity at infinity, disparity values should be restored
......@@ -617,8 +681,8 @@ public class AlignmentCorrection {
double thresholdLin = 1.0E-20; // threshold ratio of matrix determinant to norm for linear approximation (det too low - fail)
double thresholdQuad = 1.0E-30; // threshold ratio of matrix determinant to norm for quadratic approximation (det too low - fail)
// final int [] indices_mismatch = {1,4,6,9}; // "dy0", "dy1", "dx2", "dx3"
// final int [] indices_mismatch = {2+1, 2+4, 2+6, 2+9}; // "dy0", "dy1", "dx2", "dx3"
// final int [] indices_mismatch = {2+1, 2+3, 2+4, 2+6}; // "dy0", "dy1", "dx2", "dx3"
// final int [] indices_mismatch = {2+1, 2+4, 2+6, 2+9}; // "dy0", "dy1", "dx2", "dx3"
// final int [] indices_mismatch = {2+1, 2+3, 2+4, 2+6}; // "dy0", "dy1", "dx2", "dx3"
final int [][] indices_mismatch = {
{2+0, 2+2, 2+4, 2+6}, // "dx0", "dx1", "dx2", "dx3"
{2+1, 2+3, 2+5, 2+7}}; // "dy0", "dy1", "dy2", "dy3"
......@@ -654,6 +718,84 @@ public class AlignmentCorrection {
for (int i = 0; i < 4; i++){
dxy[i] = scale * disp_strength[indices_mismatch[dir][i] + (s.series * NUM_SLICES)][s.tile];
}
/*
use best fit as they are overdefined
y1 - y0 = 2 * dy0
y3 - y1 = 2 * dy3
y3 - y2 = 2 * dy1
y2 - y0 = 2 * dy2
x2 - x0 = 2 * dx2
x3 - x2 = 2 * dx1
x3 - x1 = 2 * dx3
x1 - x0 = 2 * dx0
x1 - x0 = 2 * dx0
x3 - x1 = 2 * dx3
x3 - x2 = 2 * dx1
x2 - x0 = 2 * dx2
y0 + y1 + y2 + y3 = 0
x0 + x1 + x2 + x3 = 0
e1 = (y1 - y0 - 2*dy0)^2 +
(y2 - y0 - 2*dy2)^2 +
(y3 - y1 - 2*dy3)^2 +
(y3 - y2 - 2*dy1)^2 =
(y1 - y0 - 2*dy0)^2 +
(y2 - y0 - 2*dy2)^2 +
(-(y0+y1+y2) - y1 - 2*dy3)^2 +
(-(y0+y1+y2) - y2 - 2*dy1)^2 =
(y1 - y0 - 2*dy0)^2 +
(y2 - y0 - 2*dy2)^2 +
(y0 + 2 * y1 + y2 + 2*dy3)^2 +
(y0 + y1 + 2 * y2 + 2*dy1)^2
de1/dy0 = -2 * (y1 - y0 - 2*dy0)
-2 * (y2 - y0 - 2*dy2)
+2 * (y0 + 2 * y1 + y2 + 2*dy3)
+2 * (y0 + y1 + 2 * y2 + 2*dy1) =
2 * (-(y1 - y0 - 2*dy0)-(y2 - y0 - 2*dy2)+ (y0 + 2 * y1 + y2 + 2*dy3) + (y0 + y1 + 2 * y2 + 2*dy1)) =
2 * ((2*dy0 + y0 - y1) + (2*dy2 + y0 - y2) + (y0 + 2 * y1 + y2 + 2*dy3) + (y0 + y1 + 2 * y2 + 2*dy1)) =
2 * (2 * (dy0+dy1+dy2+dy3) + y0 * 4 + 2 * y1 + 2 * y2)
2 * y0 + 1 * y1 + 1 * y2 + (dy0+dy1+dy2+dy3) = 0;
de1/dy1 = +2 * (y1 - y0 - 2*dy0)
+2 * (2*y0 + 4 * y1 + 2*y2 + 4*dy3)
+2 * (y0 + y1 + 2 * y2 + 2*dy1) =
2* ( 2*(-dy0 +2*dy3 +dy1) + y0 * 2 + y1 * 6 + y2 * 4
1 * y0 + 3 * y1 + 2 * y2 + (-dy0 +2*dy3 +dy1) = 0
de1/dy2 = +2 * (y2 - y0 - 2*dy2)
+2 * (y0 + 2 * y1 + y2 + 2*dy3)
+2 * (2*y0 + 2*y1 + 4 * y2 + 4*dy1) =
2*(2*(-dy2 + dy3 +2*dy1) + y0 * 2 + y1 * 4 + y2 * 6
1 * y0 + 2 * y1 + 3 * y2 + (-dy2 + dy3 +2*dy1) = 0;
2 * y0 + 1 * y1 + 1 * y2 + (dy0+dy1+dy2+dy3) = 0;
1 * y0 + 3 * y1 + 2 * y2 + (-dy0 +2*dy3 +dy1) = 0
1 * y0 + 2 * y1 + 3 * y2 + (-dy2 +dy3 + 2*dy1) = 0;
| 2 1 1 |
A = | 1 3 2 |
| 1 2 3 |
|-dy0 -dy1 -dy2 -dy3 |
B = |+dy0 -dy1 -2*dy3 |
|+dy2 -2*dy1 -dy3 |
*/
/*
* |-dy0 -dy1 -dy2 -dy3 |
* B = |+dy0 -dy1 -2*dy3 |
......@@ -686,6 +828,7 @@ public class AlignmentCorrection {
}
if (use_poly) {
if (use_vertical) {
// 2d optimization for 4 functions of x, y
mdata[indx][0] = new double [2];
......@@ -704,6 +847,26 @@ public class AlignmentCorrection {
mdata[n][indx][2] = s.weight; // disp_strength[2 * p.x + 1][p.y]; // strength
}
}
} else if (mismatch_list != null){
// double centerX = tileX * transform_size + transform_size/2 - shiftX;
// double centerY = tileY * transform_size + transform_size/2 - shiftY;
double [] centerXY = {
tileX * qc.tp.getTileSize() + qc.tp.getTileSize()/2,// - shiftX;
tileY * qc.tp.getTileSize() + qc.tp.getTileSize()/2};//- shiftY;
double disparity_task = disp_scan_start + disp_scan_step * s.series;
double disparity_meas = disp_strength[s.series * NUM_SLICES + 0][s.tile];
double strength = disp_strength[s.series * NUM_SLICES + 1][s.tile];
// final double disp_scan_start,
// final double disp_scan_step,
// final int disp_scan_count,
mismatch_list.add(new Mismatch(
centerXY,
disparity_task,
disparity_meas,
strength,
xy));
}
indx ++;
}
if (dbg_xy != null){
......@@ -728,6 +891,10 @@ public class AlignmentCorrection {
titles);
}
if (!use_poly){
return null; // for extrinsics - use mismatch_list
}
double [][] coeffs = new double[8][6];
if (use_vertical){
double [][] approx2d = pa.quadraticApproximation(
......@@ -771,174 +938,6 @@ public class AlignmentCorrection {
return coeff_full;
}
public double [][][] infinityMismatchCorrectionOld(
final boolean use_quadratic,
final boolean use_vertical,
EyesisCorrectionParameters.CLTParameters clt_parameters,
double [][] disp_strength,
ArrayList<Sample> samples_list,
int tilesX,
double magic_coeff, // still not understood coefficient that reduces reported disparity value. Seems to be around 8.5
int debugLevel)
{
final int num_tiles = disp_strength[0].length;
final int tilesY = num_tiles/tilesX;
PolynomialApproximation pa = new PolynomialApproximation();
double thresholdLin = 1.0E-20; // threshold ratio of matrix determinant to norm for linear approximation (det too low - fail)
double thresholdQuad = 1.0E-30; // threshold ratio of matrix determinant to norm for quadratic approximation (det too low - fail)
// final int [] indices_mismatch = {1,4,6,9}; // "dy0", "dy1", "dx2", "dx3"
// final int [] indices_mismatch = {2+1, 2+4, 2+6, 2+9}; // "dy0", "dy1", "dx2", "dx3"
final int [] indices_mismatch = {2+1, 2+3, 2+4, 2+6}; // "dy0", "dy1", "dx2", "dx3"
// use last generated samples_list;
double [][][] mdata;
if (use_vertical) {
mdata = new double[samples_list.size()][3][];
} else {
mdata = new double [indices_mismatch.length][samples_list.size()][3];
}
int indx = 0;
for (Sample s: samples_list){
int tileX = s.tile % tilesX;
int tileY = s.tile / tilesX;
if (use_vertical) {
// 2d optimization for 4 functions of x, y
mdata[indx][0] = new double [2];
mdata[indx][0][0] = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
mdata[indx][0][1] = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
mdata[indx][1] = new double [indices_mismatch.length]; // 4
for (int ip = 0; ip < indices_mismatch.length; ip++) {
mdata[indx][1][ip] = disp_strength[indices_mismatch[ip] + (s.series * NUM_SLICES)][s.tile];
}
mdata[indx][2] = new double [1];
mdata[indx][2][0] = s.weight; // disp_strength[2 * p.x + 1][p.y]; // strength
} else {
// 4 individual 1d optimization for functions of x only
for (int n = 0; n < indices_mismatch.length; n++){
mdata[n][indx][0] = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
mdata[n][indx][1] = disp_strength[indices_mismatch[n] + (s.series * NUM_SLICES)][s.tile];
mdata[n][indx][2] = s.weight; // disp_strength[2 * p.x + 1][p.y]; // strength
}
}
indx ++;
}
double [][] coeffs = new double[8][6];
if (use_vertical){
double [][] approx2d = pa.quadraticApproximation(
mdata,
!use_quadratic, // boolean forceLinear, // use linear approximation
thresholdLin, // threshold ratio of matrix determinant to norm for linear approximation (det too low - fail)
thresholdQuad, // threshold ratio of matrix determinant to norm for quadratic approximation (det too low - fail)
debugLevel);
for (int n = 0; n < approx2d.length; n++){
if (approx2d[n].length == 6) {
coeffs[n] = approx2d[n];
} else {
for (int i = 0; i < 3; i++){
coeffs[n][3+i] = approx2d[n][i];
}
}
}
} else {
for (int n = 0; n < mdata.length; n++){
double [] approx1d = pa.polynomialApproximation1d(mdata[n], use_quadratic ? 2 : 1);
// disparity_approximation = new double[6];
coeffs[n][5] = approx1d[0];
coeffs[n][3] = approx1d[1];
if (approx1d.length > 2){
coeffs[n][0] = approx1d[2];
}
}
}
// convert to 8 sets of coefficient for px0, py0, px1, py1, ... py3.
double [][][] coeff_full = new double [4][2][6];
double scale = 0.5/magic_coeff;
for (int j = 0; j < coeffs[0].length; j++){
coeff_full[0][0][j] = -coeffs[2][j] * scale;
coeff_full[0][1][j] = -coeffs[0][j] * scale;
coeff_full[1][0][j] = -coeffs[3][j] * scale;
coeff_full[1][1][j] = coeffs[0][j] * scale;
coeff_full[2][0][j] = coeffs[2][j] * scale;
coeff_full[2][1][j] = -coeffs[1][j] * scale;
coeff_full[3][0][j] = coeffs[3][j] * scale;
coeff_full[3][1][j] = coeffs[1][j] * scale;
}
if (debugLevel > -1){
double [] strength = new double [num_tiles];
for (Sample s: samples_list){
strength[s.tile] = s.weight;
}
int tilesX8 = (tilesX - 1) / 8 + 1;
int tilesY8 = (tilesY - 1) / 8 + 1;
int len8 = tilesX8*tilesY8;
double [][] mismatch_8 = new double[11][len8];
for (int i = 0; i < num_tiles; i++) {
if (strength[i] > 0) {
int tileX = i % tilesX;
int tileY = i / tilesX;
int tX8 = tileX/8;
int tY8 = tileY/8;
int indx8 = tY8*tilesX8+tX8;
double tX = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
double tY = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
double w = strength[i];
for (int ip = 0; ip < 4; ip++) {
mismatch_8[ip][indx8] += w * disp_strength[indices_mismatch[ip]][i];
}
mismatch_8[8][indx8] += w * tX;
mismatch_8[9][indx8] += w * tY;
mismatch_8[10][indx8] += w;
}
}
for (int i = 0; i < len8; i++) {
if (mismatch_8[10][i] > 0){
for (int n = 0; n<4; n++){
mismatch_8[n][i] /= mismatch_8[10][i];
}
mismatch_8[8][i] /= mismatch_8[10][i];
mismatch_8[9][i] /= mismatch_8[10][i];
} else {
for (int n = 0; n<4; n++){
mismatch_8[n][i] = Double.NaN;
}
mismatch_8[8][i] = Double.NaN;
mismatch_8[9][i] = Double.NaN;
}
for (int n = 0; n<4; n++){
double tX = mismatch_8[8][i];
double tY = mismatch_8[9][i];
//f(x,y)=A*x^2+B*y^2+C*x*y+D*x+E*y+F
mismatch_8[4+n][i] = (
coeffs[n][0]*tX*tX+
coeffs[n][1]*tY*tY+
coeffs[n][2]*tX*tY+
coeffs[n][3]*tX+
coeffs[n][4]*tY+
coeffs[n][5]);
}
}
String [] titles = {"dy0","dy1","dx2","dx3","cy0","cy1","cx2","cx3","tx","ty","w"};
showDoubleFloatArrays sdfa_instance = new showDoubleFloatArrays(); // just for debugging?
sdfa_instance.showArrays(
mismatch_8,
tilesX8,
tilesY8,
true,
"mismatch_8",
titles);
}
return coeff_full;
}
public double[][] filterLazyEyePairs (
final double[][] samples_in,
final int smpl_side, // 8 x8 masked, 16x16 sampled
......@@ -973,8 +972,8 @@ public class AlignmentCorrection {
final int num_tiles = samples_in[0].length;
int tilesY = num_tiles/tilesX;
final double [][] samples = new double [NUM_SLICES][num_tiles];
// final int low_lim = -smpl_side/2;
// final int high_lim = 3 * smpl_side/2;
// final int low_lim = -smpl_side/2;
// final int high_lim = 3 * smpl_side/2;
final int step = norm_center ? smpl_side : 1;
final int start = norm_center ? smpl_side/2 : 0;
for (int tY = start; tY < tilesY; tY += step){
......@@ -1016,9 +1015,9 @@ public class AlignmentCorrection {
rms += s2[i] - s1[i] * s1[i];
}
rms = Math.sqrt(rms/s1.length);
// if (rms_max > 0.0){
// System.out.println("filterLazyEyePairs(): tX="+tX+", tY="+ tY+" rms = "+rms);
// }
// if (rms_max > 0.0){
// System.out.println("filterLazyEyePairs(): tX="+tX+", tY="+ tY+" rms = "+rms);
// }
if (rms <= rms_max){ // otherwise discard all the tile
while (sample_list.size() > samples_left){
int worst_index = -1;
......@@ -1049,12 +1048,12 @@ public class AlignmentCorrection {
}
if (norm_center) {
double sd = 0.0;
// double sw1 = 0.0;
// double sw1 = 0.0;
for (Integer nTile:sample_list) {
double w = samples_in[1][nTile];
double d = samples_in[0][nTile];
sd += w*d;
// sw1 += w;
// sw1 += w;
}
sd /= sw;
int nTile =tY * tilesX + tX;
......@@ -1121,8 +1120,8 @@ public class AlignmentCorrection {
final int num_tiles = disp_strength_in[0].length;
int tilesY = num_tiles/tilesX;
final double [][] disp_strength = new double [NUM_SLICES][num_tiles];
// final int low_lim = -smpl_side/2;
// final int high_lim = 3 * smpl_side/2;
// final int low_lim = -smpl_side/2;
// final int high_lim = 3 * smpl_side/2;
final DoubleGaussianBlur gb=new DoubleGaussianBlur();
final int step = norm_center ? smpl_side : 1;
final int start = norm_center ? smpl_side/2 : 0;
......@@ -1324,10 +1323,10 @@ public class AlignmentCorrection {
// remove worst, update sd2, sd and sw
while ((num_in_sample > smplNum) && (sw > 0)){ // try, remove worst
double d_mean = sd/sw;
// double [] mismatch_mean = new double[sm.length];
// for (int j = 0; j < sm.length; j++){
// mismatch_mean[j] = sm[j]/sw;
// }
// double [] mismatch_mean = new double[sm.length];
// for (int j = 0; j < sm.length; j++){
// mismatch_mean[j] = sm[j]/sw;
// }
int iworst = -1;
double dworst2 = 0.0;
for (int i = 0; i < smplLen; i++) if (smpl_sel[i]) {
......@@ -1404,7 +1403,7 @@ public class AlignmentCorrection {
ImagePlus imp_src,
int debugLevel)
{
// double min_max_ratio = 1.3;
// double min_max_ratio = 1.3;
ImageStack clt_mismatches_stack= imp_src.getStack();
final int tilesX = clt_mismatches_stack.getWidth(); // tp.getTilesX();
final int tilesY = clt_mismatches_stack.getHeight(); // tp.getTilesY();
......@@ -1423,7 +1422,7 @@ public class AlignmentCorrection {
int tilesX,
int debugLevel)
{
// double min_max_ratio = 1.3;
// double min_max_ratio = 1.3;
final int tilesY = data[0].length/tilesX; // tp.getTilesY();
final int nTiles =tilesX * tilesY;
......@@ -1432,29 +1431,13 @@ public class AlignmentCorrection {
final double [][] scans = new double [num_scans * NUM_ALL_SLICES][nTiles];
for (int ns = 0; ns < num_scans; ns++){
// double [][]min_max_strength = new double[2][nTiles];
// double [][]min_max_strength = new double[2][nTiles];
for (int pair = 0; pair < 4; pair++){
float [][] fset = new float [3][];
// fset[0] = (float[]) clt_mismatches_stack.getPixels(12 * num_scans + ns +1);
// fset[1] = (float[]) clt_mismatches_stack.getPixels(13 * num_scans + ns +1); //
scans[ns * NUM_ALL_SLICES + 0] = data[12 * num_scans + ns];
scans[ns * NUM_ALL_SLICES + 1] = data[13 * num_scans + ns];
// for (int i = 0; i < nTiles; i++){
// scans[ns * NUM_ALL_SLICES + 0][i] = fset[0][i]; // disparity
// scans[ns * NUM_ALL_SLICES + 1][i] = fset[1][i]; // strength
// }
// fset[0] = (float[]) clt_mismatches_stack.getPixels((2 * pair + 0) * num_scans + ns +1);
// fset[1] = (float[]) clt_mismatches_stack.getPixels((2 * pair + 1) * num_scans + ns +1); //
// fset[2] = (float[]) clt_mismatches_stack.getPixels((8 + pair ) * num_scans + ns +1);
scans[ns * NUM_ALL_SLICES + pair * 3 + 2] = data[(2 * pair + 0) * num_scans + ns];
scans[ns * NUM_ALL_SLICES + pair * 3 + 3] = data[(2 * pair + 1) * num_scans + ns];
scans[ns * NUM_ALL_SLICES + pair * 3 + 4] = data[(8 + pair ) * num_scans + ns];
// for (int i = 0; i < nTiles; i++){
// scans[ns * NUM_ALL_SLICES + pair * 3 + 2][i] = fset[0][i]; // dx_i
// scans[ns * NUM_ALL_SLICES + pair * 3 + 3][i] = fset[1][i]; // dy_i
// scans[ns * NUM_ALL_SLICES + pair * 3 + 4][i] = fset[2][i]; // str_i
// }
}
}
if (debugLevel > 0) {
......@@ -1474,7 +1457,7 @@ public class AlignmentCorrection {
ImagePlus imp_src,
int debugLevel)
{
// double min_max_ratio = 1.3;
// double min_max_ratio = 1.3;
ImageStack clt_mismatches_stack= imp_src.getStack();
final int tilesX = clt_mismatches_stack.getWidth(); // tp.getTilesX();
final int tilesY = clt_mismatches_stack.getHeight(); // tp.getTilesY();
......@@ -1484,7 +1467,7 @@ public class AlignmentCorrection {
final double [][] scans = new double [num_scans * NUM_ALL_SLICES][nTiles];
for (int ns = 0; ns < num_scans; ns++){
// double [][]min_max_strength = new double[2][nTiles];
// double [][]min_max_strength = new double[2][nTiles];
for (int pair = 0; pair < 4; pair++){
float [][] fset = new float [3][];
fset[0] = (float[]) clt_mismatches_stack.getPixels(12 * num_scans + ns +1);
......@@ -1519,10 +1502,13 @@ public class AlignmentCorrection {
public double [][][] lazyEyeCorrection(
// final double disp_scan_start,
// final double disp_scan_step,
final boolean use_poly, // Use polynomial correction, false - correct tilt/azimuth/roll of each sensor
final double fcorr_radius,
final double min_strength_in,
final double max_diff,
// final double comp_strength_var,
// final double comp_strength_var,
final int max_iterations,
final double max_coeff_diff,
final double far_pull, // = 0.2; // 1; // 0.5;
......@@ -1766,9 +1752,9 @@ public class AlignmentCorrection {
double [][] dbg_img = new double [inf_and_ly.length][num_tiles1];
for (int tY = 0; tY < tilesY1; tY++) {
for (int tX = 0; tX < tilesX1; tX++) {
// if (tY == 14) {
// System.out.println("lazyEyeCorrection(): tX="+tX+", tY="+tY);
// }
// if (tY == 14) {
// System.out.println("lazyEyeCorrection(): tX="+tX+", tY="+tY);
// }
int nTile1 = tX + tY*tilesX1;
for (int sY = 0; sY < step; sY ++) {
for (int sX = 0; sX < step; sX ++) {
......@@ -1883,8 +1869,11 @@ public class AlignmentCorrection {
String [] prefixes = {"disparity", "strength", "dx0", "dy0", "dx1", "dy1", "dx2", "dy2", "dx3", "dy3"};
(new showDoubleFloatArrays()).showArrays(combo_mismatch, tilesX, combo_mismatch[0].length/tilesX, true, "combo_mismatch" , prefixes);
}
ArrayList<Mismatch> mismatch_list = use_poly? null : (new ArrayList<Mismatch>());
double [][][] mismatch_corr_coefficiants = infinityMismatchCorrection(
clt_parameters.disp_scan_start, // final double disp_scan_start,
clt_parameters.disp_scan_step, // final double disp_scan_step,
use_poly, // clt_parameters.ly_poly, // final boolean use_poly,
clt_parameters.fcorr_quadratic, // final boolean use_quadratic,
true, // clt_parameters.fcorr_inf_vert, // final boolean use_vertical,
false, // final boolean use_disparity, // for infinity
......@@ -1893,14 +1882,37 @@ public class AlignmentCorrection {
inf_samples_list, // ArrayList<Sample> samples_list,
tilesX, // int tilesX,
magic_coeff, // double , // still not understood coefficient that reduces reported disparity value. Seems to be around 8.5
mismatch_list, // ArrayList<Mismatch> mismatch_list,
debugLevel); // int debugLevel)
if (debugLevel > -1) {
System.out.println("===== lazyEyeCorrection(): correction coefficients =====");
if (mismatch_corr_coefficiants != null) {
show_fine_corr(
mismatch_corr_coefficiants,
"mismatch_corr_coefficiants");
}
}
if (mismatch_list != null){
boolean apply_extrinsic = true;
GeometryCorrection.CorrVector corr_vector = solveCorr (
mismatch_list, // ArrayList<Mismatch> mismatch_list,
qc.geometryCorrection, // GeometryCorrection geometryCorrection,
qc.geometryCorrection.getCorrVector(), // GeometryCorrection.CorrVector corr_vector,
1); // int debugLevel)
if (debugLevel > -1){
System.out.println("Old extrinsic corrections:");
System.out.println(qc.geometryCorrection.getCorrVector().toString());
System.out.println("Delta extrinsic corrections:");
System.out.println(corr_vector.toString());
}
if (apply_extrinsic){
qc.geometryCorrection.getCorrVector().incrementVector(corr_vector);
if (debugLevel > -1){
System.out.println("New extrinsic corrections:");
System.out.println(qc.geometryCorrection.getCorrVector().toString());
}
}
}
return mismatch_corr_coefficiants;
}
......@@ -1982,184 +1994,168 @@ public class AlignmentCorrection {
sdfa_instance.showArrays(dbg_clt_mismatch, tilesX, tilesY, true, title, titles);
}
public void process_fine_corr(
boolean dry_run,
EyesisCorrectionParameters.CLTParameters clt_parameters,
int debugLevel
) {
final double disp_variation = 0.2; // 15; // 5; // 0.2 ?
ImagePlus imp_src = WindowManager.getCurrentImage();
if (imp_src==null){
IJ.showMessage("Error","12*n-layer file clt_mismatches is required");
return;
double [][] getJacobianTransposed(
ArrayList<Mismatch> mismatch_list,
GeometryCorrection geometryCorrection,
GeometryCorrection.CorrVector corr_vector,
int debugLevel)
{
double [][] jt = new double [GeometryCorrection.CorrVector.LENGTH][2 * NUM_SENSORS * mismatch_list.size()];
double [][] jt_dbg = null;
if (debugLevel > 0){
jt_dbg = new double [GeometryCorrection.CorrVector.LENGTH][2 * NUM_SENSORS * mismatch_list.size()];
}
ImageStack clt_mismatches_stack= imp_src.getStack();
final int tilesX = clt_mismatches_stack.getWidth(); // tp.getTilesX();
final int tilesY = clt_mismatches_stack.getHeight(); // tp.getTilesY();
final int nTiles =tilesX * tilesY;
final int num_scans = clt_mismatches_stack.getSize()/14;
final double [][] scans = new double [num_scans * NUM_SLICES][nTiles];
for (int ns = 0; ns < num_scans; ns++){
for (int pair = 0; pair < 4; pair++){
float [][] fset = new float [2][];
fset[0] = (float[]) clt_mismatches_stack.getPixels((2 * pair + 0) * num_scans + ns +1);
fset[1] = (float[]) clt_mismatches_stack.getPixels((2 * pair + 1) * num_scans + ns +1); //
for (int i = 0; i < nTiles; i++){
scans[ns * NUM_SLICES + pair * 2 + 2][i] = fset[0][i]; // dxi
scans[ns * NUM_SLICES + pair * 2 + 3][i] = fset[1][i]; // dyi
for (int indx = 0; indx<mismatch_list.size(); indx++){ // need indx value
Mismatch mm = mismatch_list.get(indx);
double [] pXY = mm.getPXY();
double [][][][] fj = geometryCorrection.getPortsCoordinatesAndDerivatives(
corr_vector, // CorrVector corr_vector,
true, // boolean calc_deriv,
pXY[0], // double px,
pXY[1], // double py,
mm.getDisparityTask()); // double disparity)
for (int npar = 0; npar < jt.length; npar++){
for (int ns = 0; ns < NUM_SENSORS; ns++){
for (int dir = 0; dir < 2; dir++){
jt[npar][2 * NUM_SENSORS * indx + 2 * ns + dir] = fj[1][ns][dir][npar];
}
}
float [][] fset = new float [2][];
fset[0] = (float[]) clt_mismatches_stack.getPixels(12 * num_scans + ns +1);
fset[1] = (float[]) clt_mismatches_stack.getPixels(13 * num_scans + ns +1); //
for (int i = 0; i < nTiles; i++){
scans[ns * NUM_SLICES + 0][i] = fset[0][i]; // disparity
scans[ns * NUM_SLICES + 1][i] = fset[1][i]; // strength
}
if (debugLevel > 0){
double [][][][] fj_dbg = null;
fj_dbg = geometryCorrection.getPortsCoordinatesAndDerivatives(
1E-6, // double delta, // 1e-6
corr_vector, // CorrVector corr_vector,
pXY[0], // double px,
pXY[1], // double py,
mm.getDisparityTask()); // double disparity)
double max_rdiff = 0;
for (int npar = 0; npar < jt.length; npar++){
for (int ns = 0; ns < NUM_SENSORS; ns++){
for (int dir = 0; dir < 2; dir++){
jt_dbg[npar][2 * NUM_SENSORS * indx + 2 * ns + dir] = fj_dbg[1][ns][dir][npar];
double avg = 0.5*(jt_dbg[npar][2 * NUM_SENSORS * indx + 2 * ns + dir] + jt[npar][2 * NUM_SENSORS * indx + 2 * ns + dir]);
double rdiff= Math.abs(0.5*(jt_dbg[npar][2 * NUM_SENSORS * indx + 2 * ns + dir] - jt[npar][2 * NUM_SENSORS * indx + 2 * ns + dir]));
if (avg != 0.0){
rdiff /= avg;
}
if (debugLevel > -1) {
String [] prefixes = {"disparity", "strength", "dx0", "dy0", "dx1", "dy1", "dx2", "dy2", "dx3", "dy3"};
String [] titles = new String [num_scans * NUM_SLICES];
for (int ns = 0; ns < num_scans; ns++){
for (int i = 0; i < NUM_SLICES; i++){
titles[ns * NUM_SLICES + i] = prefixes[i]+"_"+ns;
if (rdiff > max_rdiff){
max_rdiff = rdiff;
}
}
(new showDoubleFloatArrays()).showArrays(scans, tilesX, scans[0].length/tilesX, true, "scans" , titles);
}
// public double fcorr_disp_diff = 1.5; // consider only tiles with absolute residual disparity lower than
// separate here from reading image
final int num_tiles = scans[0].length;
double[][] filtered_scans = filterDisparityStrength (
scans, // final double[][] disp_strength_in,
clt_parameters.fcorr_inf_strength, // final double strength_floor,
clt_parameters.inf_str_pow, // final double strength_pow,
clt_parameters.inf_smpl_side, // final int smplSide, // = 2; // Sample size (side of a square)
clt_parameters.inf_smpl_num, // final int smplNum, // = 3; // Number after removing worst (should be >1)
clt_parameters.inf_smpl_rms, // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
tilesX);// final int tilesX);
// public double fcorr_disp_diff = 1.5; // consider only tiles with absolute residual disparity lower than
if (debugLevel > -1) {
System.out.println("process_fine_corr() 2: removing tile with residual disparity absoulte value > "+ clt_parameters.fcorr_disp_diff);
}
for (int ns = 0; ns < num_scans; ns++){
for (int i = 0; i < num_tiles; i++){
double disp = filtered_scans[ns * NUM_SLICES + 0][i];
if (Math.abs(disp) > clt_parameters.fcorr_disp_diff) {
filtered_scans[ns * NUM_SLICES + 1][i] = 0.0;
if (debugLevel > 1) {
System.out.println(String.format("px = %5.0f py = %5.0f disp_task = %7.3f disp_meas = %7.3f strength = %7.3f max rdiff = %f",
mm.getPXY()[0], mm.getPXY()[1], mm.getDisparityTask(), mm.getDisparityMeas(), mm.getStrength(), max_rdiff));
}
}
}
double [][] combo_mismatch = new double [NUM_SLICES][num_tiles];
for (int ns = 0; ns < num_scans; ns++){
for (int nTile = 0; nTile < num_tiles; nTile++) {
double w = filtered_scans[ns * NUM_SLICES + 1][nTile];
if (w > 0.0){
double disp = filtered_scans[ns * NUM_SLICES + 0][nTile];
if (Math.abs(disp) <= clt_parameters.fcorr_disp_diff) {
for (int i = 2; i < NUM_SLICES; i++) if (i != 1){
combo_mismatch[i][nTile] += filtered_scans[ns * NUM_SLICES + i][nTile] * w;
return jt;
}
combo_mismatch[0][nTile] += (
filtered_scans[ns * NUM_SLICES + 0][nTile]/clt_parameters.corr_magic_scale +
clt_parameters.disp_scan_start + clt_parameters.disp_scan_step * ns)* w;
combo_mismatch[1][nTile] += w;
double [][] getJTJ(
double [][] jt,
double [] w)
{
double [][] jtj = new double [jt.length][jt.length];
for (int i = 0; i < jt.length; i++){
for (int j = 0; j < i; j++){
jt[i][j] = jt[j][i];
}
for (int j = i; j < jt.length; j++){
for (int k = 0; k < jt[0].length; k++){
jtj[i][j] += jt[i][k] * jt[j][k] * w[k];
}
}
}
return jtj;
}
for (int nTile = 0; nTile < num_tiles; nTile++) {
double w = combo_mismatch[1][nTile];
if (w > 0.0){
for (int i = 0; i < NUM_SLICES; i++) if (i != 1){
combo_mismatch[i][nTile] /= w;
double [] mulWeight(double [] y, double [] w){
double [] yw = y.clone();
for (int i = 0; i < yw.length; i++){
yw[i] *= w[i];
}
} else {
for (int i = 0; i < NUM_SLICES; i++) if (i != 1){
combo_mismatch[i][nTile] = Double.NaN;
return yw;
}
double getSumWeight(double [] w){
double sum_w = 0.0;
for (int i = 0; i < w.length; i++){
sum_w += w[i];
}
return sum_w;
}
final TileNeibs tnImage = new TileNeibs(tilesX, tilesY); // num_tiles/tilesX);
for (int nTile = 0; nTile < num_tiles; nTile++) if (combo_mismatch[1][nTile] > 0.0){
double d = combo_mismatch[0][nTile];
for (int dir = 0; dir <8; dir++){
int nTile1 = tnImage.getNeibIndex(nTile, dir);
if ((nTile1 >= 0) && (combo_mismatch[1][nTile1] > 0.0)){
if (Math.abs(combo_mismatch[0][nTile1] - d) > disp_variation){
combo_mismatch[1][nTile] = 0.0;
for (int i = 0; i < NUM_SLICES; i++) if (i != 1){
combo_mismatch[i][nTile] = Double.NaN;
double getRMS(double [] y, double [] w){
double rms = 0.0;
double sw = 0.0;
for (int i = 0; i < w.length; i++){
rms += w[i]*y[i]*y[i];
sw += w[i];
}
break;
if (sw != 0.0){
rms = Math.sqrt(rms/sw);
}
return rms;
}
double [] getYminusFx(
ArrayList<Mismatch> mismatch_list)
{
double [] yMinusFx = new double [2 * NUM_SENSORS * mismatch_list.size()];
for (int indx = 0; indx<mismatch_list.size(); indx++){ // need indx value
Mismatch mm = mismatch_list.get(indx);
mm.copyToY(yMinusFx, indx);
}
return yMinusFx;
}
// extract infinity data to be processed as infinity
double [][] inf_scan = new double [NUM_SLICES][];
for (int i = 0; i < NUM_SLICES; i++){
inf_scan[i] = scans[i];
double [] getWeights(
ArrayList<Mismatch> mismatch_list)
{
double [] w = new double [2 * NUM_SENSORS * mismatch_list.size()];
for (int indx = 0; indx<mismatch_list.size(); indx++){ // need indx value
Mismatch mm = mismatch_list.get(indx);
mm.copyToW(w, indx);
}
// Need to filter first!
ArrayList<Sample> inf_samples_list = selectInfinityTiles(
clt_parameters.fcorr_radius, // final double fcorr_radius,
clt_parameters.fcorr_inf_vert,// final boolean use_vertical,
0.0, // any > 0.0
clt_parameters.fcorr_inf_diff, // max_diff, //clt_parameters.fcorr_inf_diff
clt_parameters.inf_iters, // max_iterations, // clt_parameters.inf_iters
clt_parameters.inf_final_diff, // max_coeff_diff, // clt_parameters.inf_final_diff
clt_parameters.inf_far_pull, // far_pull, // clt_parameters.inf_far_pull, = 0.2; // 1; // 0.5;
clt_parameters,
inf_scan,
tilesX,
clt_parameters.corr_magic_scale, // magic_coeff, // still not understood coefficient that reduces reported disparity value. Seems to be around 8.5
debugLevel);
if (debugLevel > -1) {
double inf_weight = 0.0;
for (Sample s: inf_samples_list) {
inf_weight += s.weight;
return w;
}
System.out.println("process_fine_corr(): number of infinity samples="+inf_samples_list.size()+", total weight = "+inf_weight);
}
public GeometryCorrection.CorrVector solveCorr (
ArrayList<Mismatch> mismatch_list,
GeometryCorrection geometryCorrection,
GeometryCorrection.CorrVector corr_vector,
int debugLevel)
{
double [][] jta = getJacobianTransposed(
mismatch_list, // ArrayList<Mismatch> mismatch_list,
geometryCorrection, // GeometryCorrection geometryCorrection,
corr_vector, // GeometryCorrection.CorrVector corr_vector)
debugLevel); // int debugLevel)
Matrix jt = new Matrix(jta);
double [] y_minus_fx_a = getYminusFx(
mismatch_list); // ArrayList<Mismatch> mismatch_list)
if (debugLevel > -1) {
String [] prefixes = {"disparity", "strength", "dx0", "dy0", "dx1", "dy1", "dx2", "dy2", "dx3", "dy3"};
String [] titles = new String [num_scans * NUM_SLICES];
for (int ns = 0; ns < num_scans; ns++){
for (int i = 0; i < NUM_SLICES; i++){
titles[ns * NUM_SLICES + i] = prefixes[i]+"_"+ns;
}
}
(new showDoubleFloatArrays()).showArrays(filtered_scans, tilesX, tilesY, true, "filtered_scans" , titles);
double [] weights = getWeights(
mismatch_list); // ArrayList<Mismatch> mismatch_list)
double [] y_minus_fx_a_weighted = mulWeight(y_minus_fx_a, weights);
double rms0 = getRMS (y_minus_fx_a, weights);
if (debugLevel > -1){
System.out.println("solveCorr(): initial RMS = " + rms0);
}
if (debugLevel > -1) {
String [] prefixes = {"disparity", "strength", "dx0", "dy0", "dx1", "dy1", "dx2", "dy2", "dx3", "dy3"};
(new showDoubleFloatArrays()).showArrays(combo_mismatch, tilesX, combo_mismatch[0].length/tilesX, true, "combo_mismatch" , prefixes);
Matrix y_minus_fx_weighted = new Matrix(y_minus_fx_a, y_minus_fx_a_weighted.length);
Matrix jtj = new Matrix(getJTJ(jta, weights)); // less operations than jt.times(jt.transpose());
Matrix jtj_inv = jtj.inverse();
Matrix jty = jt.times(y_minus_fx_weighted);
Matrix mrslt = jtj_inv.times(jty);
double [] drslt = mrslt.getColumnPackedCopy();
GeometryCorrection.CorrVector rslt = geometryCorrection.getCorrVector(drslt);
return rslt;
}
}
}
......@@ -2046,11 +2046,12 @@ public class EyesisCorrectionParameters {
public int ly_smpl_side = 3; // Sample size (side of a square)
public int ly_smpl_num = 5; // Number after removing worst (should be >1)
public double ly_meas_disp = 1.5; // Maximal measured relative disparity
public double ly_smpl_rms = 0.1; // Maximal RMS of the remaining tiles in a sample
public double ly_disp_var = 0.2; // Maximal full disparity difference to 8 neighbors
public double ly_smpl_rms = 0.2; // 1; // Maximal RMS of the remaining tiles in a sample
public double ly_disp_var = 0.5; // 2; // Maximal full disparity difference to 8 neighbors
public double ly_inf_frac = 0.5; // Relative weight of infinity calibration data
public boolean ly_on_scan = true; // Calculate and apply lazy eye correction after disparity scan
public boolean ly_inf_en = true; // Simultaneously correct disparity at infinity
public boolean ly_poly = false; // Use polynomial correction, false - correct tilt/azimuth/roll of each sensor
// old fcorr parameters, reuse?
// public int fcorr_sample_size = 32; // Use square this size side to detect outliers
......@@ -2674,6 +2675,7 @@ public class EyesisCorrectionParameters {
properties.setProperty(prefix+"ly_inf_frac", this.ly_inf_frac +"");
properties.setProperty(prefix+"ly_on_scan", this.ly_on_scan+"");
properties.setProperty(prefix+"ly_inf_en", this.ly_inf_en+"");
properties.setProperty(prefix+"ly_poly", this.ly_poly+"");
properties.setProperty(prefix+"corr_magic_scale", this.corr_magic_scale +"");
......@@ -3249,6 +3251,7 @@ public class EyesisCorrectionParameters {
if (properties.getProperty(prefix+"ly_inf_frac")!=null) this.ly_inf_frac=Double.parseDouble(properties.getProperty(prefix+"ly_inf_frac"));
if (properties.getProperty(prefix+"ly_on_scan")!=null) this.ly_on_scan=Boolean.parseBoolean(properties.getProperty(prefix+"ly_on_scan"));
if (properties.getProperty(prefix+"ly_inf_en")!=null) this.ly_inf_en=Boolean.parseBoolean(properties.getProperty(prefix+"ly_inf_en"));
if (properties.getProperty(prefix+"ly_poly")!=null) this.ly_poly=Boolean.parseBoolean(properties.getProperty(prefix+" "));
if (properties.getProperty(prefix+"corr_magic_scale")!=null) this.corr_magic_scale=Double.parseDouble(properties.getProperty(prefix+"corr_magic_scale"));
......@@ -3839,6 +3842,7 @@ public class EyesisCorrectionParameters {
gd.addNumericField("Relative weight of infinity calibration data", this.ly_inf_frac, 3);
gd.addCheckbox ("Calculate and apply lazy eye correction after disparity scan (need to repeat)",this.ly_on_scan);
gd.addCheckbox ("Use infinity disparity (disable if there is not enough of infinity data)", this.ly_inf_en);
gd.addCheckbox ("*Use polynomial correction, false - correct tilt/azimuth/roll of each sensor)", this.ly_poly);
gd.addMessage ("---");
// gd.addNumericField("Use square this size side to detect outliers", this.fcorr_sample_size, 0);
// gd.addNumericField("Keep tiles only if there are more in each square", this.fcorr_mintiles, 0);
......@@ -4451,6 +4455,7 @@ public class EyesisCorrectionParameters {
this.ly_inf_frac= gd.getNextNumber();
this.ly_on_scan= gd.getNextBoolean();
this.ly_inf_en= gd.getNextBoolean();
this.ly_poly= gd.getNextBoolean();
// this.fcorr_sample_size= (int)gd.getNextNumber();
// this.fcorr_mintiles= (int) gd.getNextNumber();
......
......@@ -531,6 +531,7 @@ private Panel panel1,
addButton("CLT process corr", panelClt2, color_conf_process);
addButton("CLT disparity scan", panelClt2, color_conf_process);
addButton("CLT reset fine corr", panelClt2, color_stop);
addButton("CLT reset extrinsic corr", panelClt2, color_stop);
addButton("CLT show fine corr", panelClt2, color_configure);
addButton("CLT apply fine corr", panelClt2, color_process);
addButton("CLT test fine corr", panelClt2, color_process);
......@@ -4586,6 +4587,18 @@ private Panel panel1,
}
QUAD_CLT.reset_fine_corr();
return;
} else if (label.equals("CLT reset extrinsic corr")) {
if (QUAD_CLT == null){
QUAD_CLT = new QuadCLT (
PROPERTIES,
EYESIS_CORRECTIONS,
CORRECTION_PARAMETERS);
if (DEBUG_LEVEL > 0){
System.out.println("Created new QuadCLT instance, will need to read CLT kernels");
}
}
QUAD_CLT.resetExtrinsicCorr();
return;
} else if (label.equals("CLT show fine corr")) {
if (QUAD_CLT == null){
QUAD_CLT = new QuadCLT (
......
......@@ -29,6 +29,8 @@ import ij.IJ;
public class GeometryCorrection {
static double SCENE_UNITS_SCALE = 0.001;
static String SCENE_UNITS_NAME = "m";
static final String [] CORR_NAMES = {"tilt0","tilt1","tilt2","azimuth0","azimuth1","azimuth2","roll0","roll1","roll2","roll3"};
public int debugLevel = 0;
// public double azimuth; // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
// public double radius; // mm, distance from the rotation axis
......@@ -81,6 +83,133 @@ public class GeometryCorrection {
private double stepR=0.001;
private double maxR=2.0; // calculate up to this*distortionRadius
public CorrVector extrinsic_corr;
public GeometryCorrection(double [] extrinsic_corr)
{
this.extrinsic_corr = new CorrVector(extrinsic_corr);
}
// correction of cameras mis-alignment
public CorrVector getCorrVector(double [] vector){
return new CorrVector(vector);
}
public CorrVector getCorrVector(){
return extrinsic_corr;
}
public void setCorrVector(CorrVector vector){
if (vector == null){
vector = new CorrVector();
}
extrinsic_corr = vector;
}
public class CorrVector{
static final int LENGTH = 10;
static final int TILT_INDEX = 0;
static final int AZIMUTH_INDEX = 3;
static final int ROLL_INDEX = 6;
double [] vector;
public CorrVector ()
{
this.vector = new double[10];
}
public CorrVector (
double tilt0, double tilt1, double tilt2,
double azimuth0, double azimuth1, double azimuth2,
double roll0, double roll1, double roll2, double roll3)
{}
public CorrVector (double [] vector)
{
this.vector = vector;
}
/**
* Set subcamera corrections from a single array
* @param tilt for subcameras 0..2, radians, positive - up (subcamera 3 so sum == 0)
* @param azimuth for subcameras 0..2, radians, positive - right (subcamera 3 so sum == 0)
* @param roll for subcameras 0..3, radians, positive - CW looking to the target
*/
public CorrVector (double [] tilt, double [] azimuth, double [] roll)
{
double [] vector = {
tilt[0], tilt[1], tilt[2],
azimuth[0], azimuth[1], azimuth[2],
roll[0], roll[1], roll[2], roll[3]};
this.vector = vector;
}
public CorrVector getCorrVector(double [] vector){
return new CorrVector(vector);
}
public double [] toArray()
{
return vector;
}
public double [] getTilts()
{
double [] tilts = {vector[0], vector[1], vector[2], - (vector[0] + vector[1] +vector[2])};
return tilts;
}
public double getTilt(int indx)
{
if (indx == 3) return - (vector[0] + vector[1] +vector[2]);
else return vector[0 + indx];
}
public double [] getAzimuths()
{
double [] azimuths = {vector[3], vector[4], vector[5], -(vector[3] + vector[4] + vector[5])};
return azimuths;
}
public double getAzimuth(int indx)
{
if (indx == 3) return - (vector[3] + vector[4] +vector[5]);
else return vector[3 + indx];
}
public double [] getRolls()
{
double [] rolls = {vector[6],vector[7],vector[8], vector[9]};
return rolls;
}
public double getRoll(int indx)
{
return vector[6 + indx];
}
public String toString()
{
String s;
double [] v = new double [vector.length];
for (int i = 0; i < vector.length; i++){
v[i] = vector[i]*180/Math.PI;
}
s = String.format("tilt (up): %8.5f° %8.5f° %8.5f° %8.5f°\n" , v[0], v[1], v[2], -(v[0] + v[1] + v[2]) );
s += String.format("azimuth (right): %8.5f° %8.5f° %8.5f° %8.5f°\n" , v[3], v[4], v[5], -(v[3] + v[4] + v[5]) );
s += String.format("roll (CW): %8.5f° %8.5f° %8.5f° %8.5f°\n" , v[6], v[7], v[8], v[9] );
return s;
}
public void incrementVector(double [] incr)
{
for (int i = 0; i < incr.length; i++){
vector[i]+=incr[i];
}
}
public void incrementVector(CorrVector incr)
{
incrementVector(incr.toArray());
}
public CorrVector clone(){
return new CorrVector(this.vector.clone());
}
}
public void setDistortion(
double focalLength,
double distortionC,
......@@ -611,6 +740,29 @@ public class GeometryCorrection {
double px,
double py,
double disparity)
{
boolean new_ports = true; // false;
if (new_ports) {
double [][][][] fj = getPortsCoordinatesAndDerivatives(
getCorrVector(), // CorrVector corr_vector,
false, // boolean calc_deriv,
px, // double px,
py, // double py,
disparity); // double disparity)
return fj[0][0];
} else {
return getPortsCoordinates_nocorr( // old, tested
px,
py,
disparity);
}
}
public double [][] getPortsCoordinates_nocorr( // old, tested
double px,
double py,
double disparity)
{
double [][] pXY = new double [numSensors][2];
double pXcd = px - 0.5 * this.pixelCorrectionWidth;
......@@ -639,20 +791,44 @@ public class GeometryCorrection {
double pXid = pXci * rD2rND;
double pYid = pYci * rD2rND;
// individual rotate (check sign)
double c_roll = Math.cos((this.roll[i] - this.common_roll) * Math.PI/180.0);
double s_roll = Math.sin((this.roll[i] - this.common_roll) * Math.PI/180.0);
double a_roll = (this.roll[i] - this.common_roll) * Math.PI/180.0 ;
double c_roll = Math.cos(a_roll);
double s_roll = Math.sin(a_roll);
// double c_roll = Math.cos((this.roll[i] - this.common_roll) * Math.PI/180.0);
// double s_roll = Math.sin((this.roll[i] - this.common_roll) * Math.PI/180.0);
pXY[i][0] = c_roll * pXid + s_roll* pYid + this.pXY0[i][0];
pXY[i][1] = -s_roll * pXid + c_roll* pYid + this.pXY0[i][1];
}
return pXY;
}
public double [][] getPortsCoordinatesIdeal_wrong(
/**
* Calculate pixel coordinates for each of numSensors images, for a given (px,py) of the idealized "center" (still distorted) image
* and generic disparity, measured in pixels
* @param corr_vector misalignment correction
* @param px pixel X coordinate
* @param py pixel Y coordinate
* @param disparity disparity
* @return array of per port pairs of pixel shifts
*/
public double [][][][] getPortsCoordinatesAndDerivatives(
CorrVector corr_vector,
boolean calc_deriv,
double px,
double py,
double disparity)
{
double [][] pXY = new double [numSensors][2];
double [][][] pXYderiv = calc_deriv? new double [numSensors][2][CorrVector.LENGTH] : null;
double [][][][] rslt = new double[calc_deriv? 2:1][][][];
rslt[0] = new double[1][][];
rslt[0][0] = pXY;
if (calc_deriv){
rslt[1] = pXYderiv;
}
double pXcd = px - 0.5 * this.pixelCorrectionWidth;
double pYcd = py - 0.5 * this.pixelCorrectionHeight;
double rD = Math.sqrt(pXcd*pXcd + pYcd*pYcd)*0.001*this.pixelSize; // distorted radius in a virtual center camera
......@@ -660,33 +836,137 @@ public class GeometryCorrection {
double pXc = pXcd * rND2R; // non-distorted coordinates relative to the (0.5 * this.pixelCorrectionWidth, 0.5 * this.pixelCorrectionHeight)
double pYc = pYcd * rND2R; // in pixels
double [] a={this.distortionC,this.distortionB,this.distortionA,this.distortionA5,this.distortionA6,this.distortionA7,this.distortionA8};
double corr_scale = focalLength/(0.001*pixelSize);
double ri_scale = 0.001 * this.pixelSize / this.distortionRadius;
for (int i = 0; i < numSensors; i++){
// non-distorted XY of the shifted location of the individual sensor
double pXci = pXc - disparity * this.rXY_ideal[i][0]; // in pixels
double pYci = pYc - disparity * this.rXY_ideal[i][1];
double pXci = pXc - disparity * this.rXY[i][0]; // in pixels
double pYci = pYc - disparity * this.rXY[i][1];
// add misalignment, for small angles express in non-distorted pixels
pXci += -corr_vector.getAzimuth(i) * corr_scale;
pYci += corr_vector.getTilt(i) * corr_scale;
// calculate back to distorted
double rNDi = Math.sqrt(pXci*pXci + pYci*pYci); // in pixels
// Rdist/R=A8*R^7+A7*R^6+A6*R^5+A5*R^4+A*R^3+B*R^2+C*R+(1-A6-A7-A6-A5-A-B-C)");
double ri = rNDi* 0.001 * this.pixelSize / this.distortionRadius; // relative to distortion radius
double ri = rNDi* ri_scale; // relative to distortion radius
// double rD2rND = (1.0 - distortionA8 - distortionA7 - distortionA6 - distortionA5 - distortionA - distortionB - distortionC);
double rD2rND = 1.0;
double rri = 1.0;
for (int j = 0; j < a.length; j++){
rri *= ri;
rD2rND += a[j]*(rri - 1.0);
rD2rND += a[j]*(rri - 1.0); // Fixed
}
double pXid = pXci * rD2rND;
double pYid = pYci * rD2rND;
// individual rotate (check sign)
// double c_roll = Math.cos((this.roll[i] - this.common_roll) * Math.PI/180.0);
// double s_roll = Math.sin((this.roll[i] - this.common_roll) * Math.PI/180.0);
double c_roll = Math.cos(( - this.common_roll) * Math.PI/180.0);
double s_roll = Math.sin(( - this.common_roll) * Math.PI/180.0);
pXY[i][0] = c_roll * pXid + s_roll* pYid + 0.5 * this.pixelCorrectionWidth; // this.pXY0[i][0];
pXY[i][1] = -s_roll * pXid + c_roll* pYid + 0.5 * this.pixelCorrectionWidth; // this.pXY0[i][1];
double a_roll = (this.roll[i] - this.common_roll) * Math.PI/180.0 + corr_vector.getRoll(i) ;
double c_roll = Math.cos(a_roll);
double s_roll = Math.sin(a_roll);
pXY[i][0] = c_roll * pXid + s_roll * pYid + this.pXY0[i][0];
pXY[i][1] = -s_roll * pXid + c_roll * pYid + this.pXY0[i][1];
if (calc_deriv) {
double dpXci_dazimuth = -corr_scale;
double dpYci_dtilt = corr_scale;
// double rNDi = Math.sqrt(pXci*pXci + pYci*pYci); // in pixels
double dri_dazimuth = pXci/rNDi * dpXci_dazimuth * ri_scale;
double dri_dtilt = pYci/rNDi * dpYci_dtilt * ri_scale;
double drD2rND_dri = 0.0;
rri = 1.0;
for (int j = 0; j < a.length; j++){
drD2rND_dri += (j+1) * rri;
rri *= ri;
}
double drD2rND_dazimuth = drD2rND_dri * dri_dazimuth;
double drD2rND_dtilt = drD2rND_dri * dri_dtilt;
// double pXid = pXci * rD2rND;
// double pYid = pYci * rD2rND;
double dpXid_dazimuth = dpXci_dazimuth * rD2rND + pXid * drD2rND_dazimuth;
double dpYid_dazimuth = pYid * drD2rND_dazimuth;
double dpXid_dtilt = pXid * drD2rND_dtilt;
double dpYid_dtilt = dpYci_dtilt * rD2rND + pYid * drD2rND_dtilt;
// pXY[i][0] = c_roll * pXid + s_roll * pYid + this.pXY0[i][0];
// pXY[i][1] = -s_roll * pXid + c_roll * pYid + this.pXY0[i][1];
double dxi_dazimuth = c_roll * dpXid_dazimuth + s_roll * dpYid_dazimuth;
double dyi_dazimuth = -s_roll * dpXid_dazimuth + c_roll * dpYid_dazimuth;
double dxi_dtilt = c_roll * dpXid_dtilt + s_roll * dpYid_dtilt;
double dyi_dtilt = -s_roll * dpXid_dtilt + c_roll * dpYid_dtilt;
if (i < (numSensors - 1)){
pXYderiv[i][0][CorrVector.TILT_INDEX+i] = dxi_dtilt;
pXYderiv[i][1][CorrVector.TILT_INDEX+i] = dyi_dtilt;
pXYderiv[i][0][CorrVector.AZIMUTH_INDEX+i] = dxi_dazimuth;
pXYderiv[i][1][CorrVector.AZIMUTH_INDEX+i] = dyi_dazimuth;
} else {
for (int j = 0; j < (numSensors - 1); j++){
pXYderiv[j][0][CorrVector.TILT_INDEX+i] = -dxi_dtilt;
pXYderiv[j][1][CorrVector.TILT_INDEX+i] = -dyi_dtilt;
pXYderiv[j][0][CorrVector.AZIMUTH_INDEX+i] = -dxi_dazimuth;
pXYderiv[j][1][CorrVector.AZIMUTH_INDEX+i] = -dyi_dazimuth;
}
return pXY;
}
double dxi_droll = -s_roll * pXid + c_roll * pYid;
double dyi_droll = -c_roll * pXid - s_roll * pYid;
pXYderiv[i][0][CorrVector.ROLL_INDEX+i] = dxi_droll;
pXYderiv[i][1][CorrVector.ROLL_INDEX+i] = dyi_droll;
}
}
return rslt;
}
// debug version, calculates derivatives as differences
public double [][][][] getPortsCoordinatesAndDerivatives(
double delta, // 1e-6
CorrVector corr_vector,
double px,
double py,
double disparity)
{
double [][][][] rslt = new double[2][][][];
rslt[0] = getPortsCoordinatesAndDerivatives(
corr_vector, // CorrVector corr_vector,
false, // boolean calc_deriv,
px, // double px,
py, // double py,
disparity // double disparity
)[0];
double [][][] pXYderiv = new double [numSensors][2][CorrVector.LENGTH];
rslt[1] = pXYderiv;
for (int nPar = 0; nPar < CorrVector.LENGTH; nPar++){
CorrVector cv_delta_p = corr_vector.clone();
CorrVector cv_delta_m = corr_vector.clone();
cv_delta_p.vector[nPar] += 0.5 *delta;
cv_delta_m.vector[nPar] -= 0.5 *delta;
double [][] rslt_p = getPortsCoordinatesAndDerivatives(
cv_delta_p, // CorrVector corr_vector,
false, // boolean calc_deriv,
px, // double px,
py, // double py,
disparity // double disparity
)[0][0];
double [][] rslt_m = getPortsCoordinatesAndDerivatives(
cv_delta_m, // CorrVector corr_vector,
false, // boolean calc_deriv,
px, // double px,
py, // double py,
disparity // double disparity
)[0][0];
for (int sens = 0; sens < numSensors; sens++){
for (int dir = 0; dir < 2; dir++){
pXYderiv[sens][dir][nPar] = (rslt_p[sens][dir] - rslt_m[sens][dir]) / delta;
}
}
}
return rslt;
}
// should return same as input if disparity==0
public double [][] getPortsCoordinatesIdeal(
......
......@@ -22,12 +22,9 @@
**
*/
import java.awt.Polygon;
//import java.awt.Polygon;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
......@@ -37,7 +34,6 @@ import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.WindowManager;
import ij.gui.Roi;
import ij.io.FileSaver;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;
......@@ -52,6 +48,7 @@ public class QuadCLT {
public EyesisCorrectionParameters.CorrectionParameters correctionsParameters=null;
double [][][][][][] clt_kernels = null;
GeometryCorrection geometryCorrection = null;
double [] extrinsic_corr = new double [GeometryCorrection.CORR_NAMES.length]; // extrinsic corrections (needed from properties, before geometryCorrection
public int extra_items = 8; // number of extra items saved with kernels (center offset (partial, full, derivatives)
public ImagePlus eyesisKernelImage = null;
public long startTime;
......@@ -91,7 +88,7 @@ public class QuadCLT {
}
// TODO:Add saving just calibration
public void setProperties(){
public void setProperties(){ // save
for (int n = 0; n < fine_corr.length; n++){
for (int d = 0; d < fine_corr[n].length; d++){
for (int i = 0; i < fine_corr[n][d].length; i++){
......@@ -100,9 +97,16 @@ public class QuadCLT {
}
}
}
if (geometryCorrection != null){
for (int i = 0; i < GeometryCorrection.CORR_NAMES.length; i++){
String name = prefix+"extrinsic_corr_"+GeometryCorrection.CORR_NAMES[i];
properties.setProperty(name, geometryCorrection.getCorrVector().toArray()[i]+"");
}
}
}
public void getProperties(){
public void getProperties(){ // restore
for (int n = 0; n < fine_corr.length; n++){
for (int d = 0; d < fine_corr[n].length; d++){
for (int i = 0; i < fine_corr[n][d].length; i++){
......@@ -111,6 +115,16 @@ public class QuadCLT {
}
}
}
// always set extrinsic_corr
for (int i = 0; i < GeometryCorrection.CORR_NAMES.length; i++){
String name = prefix+"extrinsic_corr_"+GeometryCorrection.CORR_NAMES[i];
if (properties.getProperty(name)!=null) {
this.extrinsic_corr[i] = Double.parseDouble(properties.getProperty(name));
if (geometryCorrection != null){
geometryCorrection.getCorrVector().toArray()[i] = this.extrinsic_corr[i];
}
}
}
}
......@@ -129,7 +143,7 @@ public class QuadCLT {
return geometryCorrection != null;
}
public boolean initGeometryCorrection(int debugLevel){
geometryCorrection = new GeometryCorrection();
geometryCorrection = new GeometryCorrection(extrinsic_corr);
PixelMapping.SensorData [] sensors = eyesisCorrections.pixelMapping.sensors;
// verify that all sensors have the same distortion parameters
int numSensors = sensors.length;
......@@ -3458,6 +3472,7 @@ public class QuadCLT {
AlignmentCorrection ac = new AlignmentCorrection(this);
// includes both infinity correction and mismatch correction for the same infinity tiles
double [][][] new_corr = ac.infinityCorrection(
clt_parameters.ly_poly, // final boolean use_poly,
clt_parameters.fcorr_inf_strength, // final double min_strenth,
clt_parameters.fcorr_inf_diff, // final double max_diff,
clt_parameters.inf_iters, // 20, // 0, // final int max_iterations,
......@@ -3876,334 +3891,6 @@ public class QuadCLT {
}
/**
* Calculate quadratic polynomials for each subcamera X/Y correction to match disparity = 0 at infinity
* Next parameters are made separate to be able to modify them between different runs keeping clt_parameters
* @param min_strenth minimal correlation strength to use tile
* @param max_diff maximal disparity difference between tiles and previous approximation to use tiles
* @param max_iterations maximal number of iterations to find disparity surface
* @param max_coeff_diff coefficients maximal change to continue iterations
* @param clt_parameters CLT parameters
* @param disp_strength array of a single or multiple disparity/strength pairs (0,2, .. - disparity,
* 1,3,.. - corresponding strengths
* @param tilesX number of tiles in each data line
* @param magic_coeff still not understood coefficient that reduces reported disparity value. Seems to be around 0.85
* @param debugLevel debug level
* @return per sub-camera, per direction (x,y) 6 quadratic polynomial coefficients, same format as fine_geometry_correction()
*/
public double [][][] infinityCorrection(
final double min_strenth,
final double max_diff,
final int max_iterations,
final double max_coeff_diff,
EyesisCorrectionParameters.CLTParameters clt_parameters,
double [][] disp_strength,
int tilesX,
double magic_coeff, // still not understood coefficient that reduces reported disparity value. Seems to be around 8.5
int debugLevel)
{
final double far_pull = 0.2; // 1; // 0.5;
final int numTiles = disp_strength[0].length;
final int tilesY = numTiles/tilesX;
double [] disparity_poly = new double[6];
PolynomialApproximation pa = new PolynomialApproximation();
double thresholdLin = 1.0E-20; // threshold ratio of matrix determinant to norm for linear approximation (det too low - fail)
double thresholdQuad = 1.0E-30; // threshold ratio of matrix determinant to norm for quadratic approximation (det too low - fail)
double [] disp_surface = new double[numTiles];
// double [] corr_weight = new double [numTiles]; // reduce weight for far tiles (by more than range farther than surface)
class Sample{
int series;
int tile;
double weight;
Sample(int series, int tile, double weight) {
this.series = series;
this.tile = tile;
this.weight = weight;
}
}
ArrayList<Sample> samples_list = new ArrayList<Sample>();
for (int pass = 0; pass < max_iterations; pass++){
for (int nTile = 0; nTile < numTiles; nTile++){
int tileX = nTile % tilesX;
int tileY = nTile / tilesX;
double x = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
double y = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
disp_surface[nTile] =
disparity_poly[0] * x * x +
disparity_poly[1] * y * y +
disparity_poly[2] * x * y +
disparity_poly[3] * x +
disparity_poly[4] * y +
disparity_poly[5];
}
samples_list.clear();
for (int num_set = 0; num_set < disp_strength.length/2; num_set++){
int disp_index = 2 * num_set;
int str_index = 2 * num_set+1;
for (int nTile = 0; nTile < numTiles; nTile++){
if ((disp_strength[str_index][nTile] >= min_strenth) &&
// (Math.abs(disp_strength[disp_index][nTile] - disp_surface[nTile]) < max_diff)){
((disp_strength[disp_index][nTile] - disp_surface[nTile]) < max_diff)){
double weight= disp_strength[str_index][nTile];
// next are for far tiles, that differ by more than max_diff
if (Math.abs(disp_strength[disp_index][nTile] - disp_surface[nTile]) > max_diff){
weight *= far_pull;
}
samples_list.add(new Sample(num_set, nTile, weight));
}
}
}
double [][][] mdata;
if (clt_parameters.fcorr_inf_vert) {
mdata = new double[samples_list.size()][3][];
} else {
mdata = new double [1][samples_list.size()][3];
}
int indx = 0;
for (Sample s: samples_list){
int tileX = s.tile % tilesX;
int tileY = s.tile / tilesX;
if (clt_parameters.fcorr_inf_vert) {
mdata[indx][0] = new double [2];
mdata[indx][0][0] = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
mdata[indx][0][1] = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
mdata[indx][1] = new double [1];
mdata[indx][1][0] = (disp_strength[2 * s.series + 0][s.tile]/magic_coeff - disp_surface[s.tile]); // disparity residual
mdata[indx][2] = new double [1];
mdata[indx][2][0] = s.weight; // disp_strength[2 * s.series + 1][s.tile]; // strength
// if (Math.abs( mdata[indx][1][0]) > max_diff) { // far tiles
// mdata[indx][2][0] *= far_pull;
// }
} else {
mdata[0][indx][0] = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
mdata[0][indx][1] = (disp_strength[2 * s.series + 0][s.tile]/magic_coeff - disp_surface[s.tile]); // disparity residual
mdata[0][indx][2] = s.weight; // disp_strength[2 * s.series + 1][s.tile]; // strength
// if (Math.abs( mdata[0][indx][1]) > max_diff) { // far tiles
// mdata[0][indx][2] *= far_pull;
// }
}
indx ++;
}
if ((debugLevel > -1) && (pass < 20)){
String [] titles = {"disparity","approx","diff", "strength"};
double [][] dbg_img = new double [titles.length][numTiles];
for (int nTile = 0; nTile < numTiles; nTile++){
int tileX = nTile % tilesX;
int tileY = nTile / tilesX;
double x = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
double y = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
dbg_img[1][nTile] =
disparity_poly[0] * x * x +
disparity_poly[1] * y * y +
disparity_poly[2] * x * y +
disparity_poly[3] * x +
disparity_poly[4] * y +
disparity_poly[5];
}
for (Sample s: samples_list){
dbg_img[0][s.tile] += disp_strength[2 * s.series][s.tile] * s.weight; // disp_strength[2 * p.x + 1][p.y];
dbg_img[3][s.tile] += s.weight; // disp_strength[2 * p.x + 1][p.y];
}
for (int nTile = 0; nTile < numTiles; nTile++) {
if (dbg_img[3][nTile] > 0.0) {
dbg_img[0][nTile] /=dbg_img[3][nTile];
} else {
dbg_img[0][nTile] = Double.NaN;
}
}
for (int nTile = 0; nTile < numTiles; nTile++) {
if (dbg_img[3][nTile] > 0.0) {
dbg_img[2][nTile] = dbg_img[0][nTile] - dbg_img[1][nTile];
} else {
dbg_img[2][nTile] = Double.NaN;
}
}
(new showDoubleFloatArrays()).showArrays(dbg_img, tilesX, tilesY, true, "infinity_"+pass, titles);
}
double [][] coeffs = new double[1][6];
if (clt_parameters.fcorr_inf_vert){
double[][] approx2d = pa.quadraticApproximation(
mdata,
!clt_parameters.fcorr_inf_quad, // boolean forceLinear, // use linear approximation
thresholdLin, // threshold ratio of matrix determinant to norm for linear approximation (det too low - fail)
thresholdQuad, // threshold ratio of matrix determinant to norm for quadratic approximation (det too low - fail)
debugLevel); {
}
if (approx2d[0].length == 6) {
coeffs = approx2d;
} else {
for (int i = 0; i < 3; i++){
coeffs[0][3+i] = approx2d[0][i];
}
}
} else {
double [] approx1d = pa.polynomialApproximation1d(mdata[0], clt_parameters.fcorr_inf_quad ? 2 : 1);
// disparity_approximation = new double[6];
coeffs[0][5] = approx1d[0];
coeffs[0][3] = approx1d[1];
if (approx1d.length > 2){
coeffs[0][0] = approx1d[2];
}
}
if (debugLevel > -1){
System.out.println(String.format(
"infinityCorrection() disparity pass=%03d A=%8.5f B=%8.5f C=%8.5f D=%8.5f E=%8.5f F=%8.5f",
pass, disparity_poly[0], disparity_poly[1], disparity_poly[2],
disparity_poly[3], disparity_poly[4], disparity_poly[5]) );
}
boolean all_done = true;
for (int i = 0; i < disparity_poly.length; i++){
if (Math.abs(coeffs[0][i]) > max_coeff_diff){
all_done = false;
break;
}
}
if (all_done) break;
for (int i = 0; i < disparity_poly.length; i++){
disparity_poly[i] += coeffs[0][i];
}
}
// use last generated samples_list;
double [][][] mdata;
if (clt_parameters.fcorr_inf_vert) {
mdata = new double[samples_list.size()][3][];
} else {
mdata = new double [8][samples_list.size()][3];
}
int indx = 0;
for (Sample s: samples_list){
int tileX = s.tile % tilesX;
int tileY = s.tile / tilesX;
double centerX = tileX * tp.getTileSize() + tp.getTileSize()/2;// - shiftX;
double centerY = tileY * tp.getTileSize() + tp.getTileSize()/2;//- shiftY;
double [][] centersXY_disp = geometryCorrection.getPortsCoordinates(
centerX,
centerY,
disp_strength[2 * s.series + 0][s.tile]/magic_coeff); // disparity
double [][] centersXY_inf = geometryCorrection.getPortsCoordinates(
centerX,
centerY,
0.0); // disparity
for (int i = 0; i < centersXY_disp.length;i++){
centersXY_disp[i][0] -= centersXY_inf[i][0];
centersXY_disp[i][1] -= centersXY_inf[i][1];
}
if (clt_parameters.fcorr_inf_vert) {
mdata[indx][0] = new double [2];
mdata[indx][0][0] = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
mdata[indx][0][1] = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
mdata[indx][1] = new double [8];
for (int n = 0; n < 8; n++){
mdata[indx][1][n] = -centersXY_disp[n / 2][n % 2];
}
mdata[indx][2] = new double [1];
mdata[indx][2][0] = s.weight; // disp_strength[2 * p.x + 1][p.y]; // strength
} else {
for (int n = 0; n < 8; n++){
mdata[n][indx][0] = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
mdata[n][indx][1] = -centersXY_disp[n / 2][n % 2];
mdata[n][indx][2] = s.weight; // disp_strength[2 * p.x + 1][p.y]; // strength
}
}
indx ++;
}
double [][] coeffs = new double[8][6];
if (clt_parameters.fcorr_inf_vert){
double [][] approx2d = pa.quadraticApproximation(
mdata,
!clt_parameters.fcorr_inf_quad, // boolean forceLinear, // use linear approximation
thresholdLin, // threshold ratio of matrix determinant to norm for linear approximation (det too low - fail)
thresholdQuad, // threshold ratio of matrix determinant to norm for quadratic approximation (det too low - fail)
debugLevel);
for (int n = 0; n < 8; n++){
if (approx2d[n].length == 6) {
coeffs[n] = approx2d[n];
} else {
for (int i = 0; i < 3; i++){
coeffs[n][3+i] = approx2d[n][i];
}
}
}
} else {
for (int n = 0; n < 8; n++){
double [] approx1d = pa.polynomialApproximation1d(mdata[n], clt_parameters.fcorr_inf_quad ? 2 : 1);
// disparity_approximation = new double[6];
coeffs[n][5] = approx1d[0];
coeffs[n][3] = approx1d[1];
if (approx1d.length > 2){
coeffs[n][0] = approx1d[2];
}
}
}
double [][][] inf_corr = new double [4][2][];
for (int n = 0; n < 8; n++){
inf_corr[n / 2][n % 2] = coeffs[n];
}
if (debugLevel > 0) {
String [] titles = {"disparity","approx","diff", "strength"};
double [][] dbg_img = new double [titles.length][numTiles];
for (int nTile = 0; nTile < numTiles; nTile++){
int tileX = nTile % tilesX;
int tileY = nTile / tilesX;
double x = (2.0 * tileX)/tilesX - 1.0; // -1.0 to +1.0;
double y = (2.0 * tileY)/tilesY - 1.0; // -1.0 to +1.0
dbg_img[1][nTile] =
disparity_poly[0] * x * x +
disparity_poly[1] * y * y +
disparity_poly[2] * x * y +
disparity_poly[3] * x +
disparity_poly[4] * y +
disparity_poly[5];
}
for (Sample s: samples_list){
dbg_img[0][s.tile] += disp_strength[2 * s.series][s.tile] * s.weight; // disp_strength[2 * p.x + 1][p.y];
dbg_img[3][s.tile] += s.weight; // disp_strength[2 * s.series + 1][s.tile];
}
for (int nTile = 0; nTile < numTiles; nTile++) {
if (dbg_img[3][nTile] > 0.0) {
dbg_img[0][nTile] /=dbg_img[3][nTile];
} else {
dbg_img[0][nTile] = Double.NaN;
}
}
for (int nTile = 0; nTile < numTiles; nTile++) {
if (dbg_img[3][nTile] > 0.0) {
dbg_img[2][nTile] = dbg_img[0][nTile] - dbg_img[1][nTile];
} else {
dbg_img[2][nTile] = Double.NaN;
}
}
(new showDoubleFloatArrays()).showArrays(dbg_img, tilesX, tilesY, true, "QC_infinityCorrection", titles);
}
return inf_corr;
}
public void apply_fine_corr(
double [][][] corr,
int debugLevel)
......@@ -4250,6 +3937,8 @@ public class QuadCLT {
System.out.println();
}
}
System.out.println();
showExtrinsicCorr();
}
......@@ -4258,6 +3947,24 @@ public class QuadCLT {
this.fine_corr = new double [4][2][6]; // reset all coefficients to 0
}
public void showExtrinsicCorr()
{
System.out.println("Extrinsic corrections");
if (geometryCorrection == null){
System.out.println("are not set, will be:");
System.out.println(new GeometryCorrection(this.extrinsic_corr).getCorrVector().toString());
} else {
System.out.println(geometryCorrection.getCorrVector().toString());
}
}
public void resetExtrinsicCorr()
{
this.extrinsic_corr = new double [GeometryCorrection.CORR_NAMES.length];
if (geometryCorrection != null){
geometryCorrection.setCorrVector(null);
}
}
public void cltDisparityScans(
EyesisCorrectionParameters.CLTParameters clt_parameters,
EyesisCorrectionParameters.DebayerParameters debayerParameters,
......@@ -4671,6 +4378,7 @@ public class QuadCLT {
debugLevel); // int debugLevel)
double [][][] new_corr = ac.lazyEyeCorrection(
clt_parameters.ly_poly, // final boolean use_poly,
clt_parameters.fcorr_radius, // final double fcorr_radius,
clt_parameters.fcorr_inf_strength, // final double min_strenth,
clt_parameters.fcorr_inf_diff, // final double max_diff,
......@@ -4702,7 +4410,7 @@ public class QuadCLT {
tilesX, // int tilesX,
clt_parameters.corr_magic_scale, // double magic_coeff, // still not understood coefficent that reduces reported disparity value. Seems to be around 8.5
debugLevel + (clt_parameters.fine_dbg ? 1:0)); // int debugLevel)
if (clt_parameters.ly_on_scan) {
if (clt_parameters.ly_on_scan && (new_corr != null)) {
if (debugLevel > -1){
System.out.println("=== Applying lazy eye correction === ");
}
......@@ -4779,14 +4487,14 @@ public class QuadCLT {
) {
ImagePlus imp_src = WindowManager.getCurrentImage();
if (imp_src==null){
IJ.showMessage("Error","2*n-layer file with disparities/strengthspairs measured at infinity is required");
IJ.showMessage("Error","14*n-layer file with disparities/strengthspairs measured at infinity is required");
return;
}
ImageStack disp_strength_stack= imp_src.getStack();
final int tilesX = disp_strength_stack.getWidth(); // tp.getTilesX();
final int tilesY = disp_strength_stack.getHeight(); // tp.getTilesY();
final int nTiles =tilesX * tilesY;
final int num_scans = disp_strength_stack.getSize()/AlignmentCorrection.NUM_SLICES;
final int num_scans = disp_strength_stack.getSize()/AlignmentCorrection.NUM_ALL_SLICES;
final double [][] inf_disp_strength = new double [AlignmentCorrection.NUM_SLICES * num_scans][nTiles];
for (int n = 0; n < disp_strength_stack.getSize(); n++){
float [] fpixels = (float[]) disp_strength_stack.getPixels(n +1);
......@@ -4800,6 +4508,7 @@ public class QuadCLT {
AlignmentCorrection ac = new AlignmentCorrection(this);
// includes both infinity correction and mismatch correction for the same infinity tiles
double [][][] new_corr = ac.infinityCorrection(
clt_parameters.ly_poly, // final boolean use_poly,
clt_parameters.fcorr_inf_strength, // final double min_strenth,
clt_parameters.fcorr_inf_diff, // final double max_diff,
clt_parameters.inf_iters, // 20, // 0, // final int max_iterations,
......@@ -4876,6 +4585,7 @@ public class QuadCLT {
double [][][] new_corr = ac.lazyEyeCorrection(
clt_parameters.ly_poly, // final boolean use_poly,
clt_parameters.fcorr_radius, // final double fcorr_radius,
clt_parameters.fcorr_inf_strength, // final double min_strenth,
clt_parameters.fcorr_inf_diff, // final double max_diff,
......@@ -4908,7 +4618,7 @@ public class QuadCLT {
clt_parameters.corr_magic_scale, // double magic_coeff, // still not understood coefficent that reduces reported disparity value. Seems to be around 8.5
debugLevel + (clt_parameters.fine_dbg ? 1:0)); // int debugLevel)
if (!dry_run){
if (!dry_run && (new_corr != null)){
apply_fine_corr(
new_corr,
debugLevel + 2);
......@@ -5419,7 +5129,7 @@ public class QuadCLT {
ImageDtt.DISPARITY_INDEX_CM, // index of disparity value in disparity_map == 2 (0,2 or 4)
threadsMax, // maximal number of threads to launch
updateStatus,
1); // debugLevel);
debugLevel);
// bgnd_data.texture = imp_bgnd.getTitle()+".png";
if (clt_parameters.show_expand ) { // getBackgroundImage() sets selected
......@@ -5833,9 +5543,6 @@ public class QuadCLT {
// runtime.gc();
// System.out.println("--- Free memory="+runtime.freeMemory()+" (of "+runtime.totalMemory()+")");
boolean use_zMapExpansionStep = true; // false;
if (use_zMapExpansionStep) {
num_extended = zMapExpansionStep(
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,// List, first, last - to search for the already tried disparity
clt_parameters, //final EyesisCorrectionParameters.CLTParameters clt_parameters, // for refinePassSetup()
......@@ -5935,324 +5642,6 @@ public class QuadCLT {
dbg_y, // final int dbg_y,
debugLevel+1); // final int debugLevel)
} else { // if (use_zMapExpansionStep) {
// Temporarily mixing results of refinePassSetup() and tp.getFilteredDisparityStrength(). The Later needs measurement pass, not refined
double [][] filtered_disp_strength = tp.getFilteredDisparityStrength(
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,// List, first, last - to search for the already tried disparity
tp.clt_3d_passes.size() - 1, // final int measured_scan_index, // will not look at higher scans
0, // final int start_scan_index,
tp.clt_3d_passes.get(bg_pass).getSelected(), // selected , // final boolean [] bg_tiles, // get from selected in clt_3d_passes.get(0);
clt_parameters.ex_min_over,// final double ex_min_over, // when expanding over previously detected (by error) background, disregard far tiles
disp_index, // final int disp_index,
str_index, // final int str_index,
null, // final double [] tiltXY, // null - free with limit on both absolute (2.0?) and relative (0.2) values
trustedCorrelation, // final double trustedCorrelation,
strength_floor, // final double strength_floor,
strength_pow, // final double strength_pow,
smplSide, // final int smplSide, // = 2; // Sample size (side of a square)
smplNum, // final int smplNum, // = 3; // Number after removing worst (should be >1)
smplRms, // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
smplRelRms, // final double smplRelRms, // = 0.005; // Maximal RMS/disparity in addition to smplRms
smplWnd, // final boolean smplWnd, //
max_abs_tilt, // final double max_abs_tilt, // = 2.0; // pix per tile
max_rel_tilt, // final double max_rel_tilt, // = 0.2; // (pix / disparity) per tile
dbg_x,
dbg_y, // final int dbg_y,
debugLevel+1); // final int debugLevel)
if (over_infinity) {
tp.filterOverBackground(
filtered_disp_strength, // final double [][] ds,
filtered_bgnd_disp_strength[1], // final double [] bg_strength,
tp.clt_3d_passes.get(bg_pass).getSelected(), // final boolean [] bg_tiles, // get from selected in clt_3d_passes.get(0);
filterMinStrength, // final double minStrength,
clt_parameters.ex_min_over); // final double ex_min_over // when expanding over previously detected (by error) background, disregard far tiles
}
refine_pass = tp.clt_3d_passes.size(); // 1
// refine pass uses hor/vert thresholds inside
CLTPass3d refined = tp.refinePassSetup( // prepare tile tasks for the refine pass (re-measure disparities)
// final double [][][] image_data, // first index - number of image in a quad
clt_parameters,
clt_parameters.stUseRefine, // use supertiles
bg_pass,
// disparity range - differences from
clt_parameters.bgnd_range, // double disparity_far,
clt_parameters.grow_disp_max, // other_range, //double disparity_near, //
clt_parameters.ex_strength, // double this_sure, // minimal strength to be considered definitely good
clt_parameters.ex_nstrength, // double ex_nstrength, // minimal 4-corr strength divided by channel diff for new (border) tiles
clt_parameters.bgnd_maybe, // double this_maybe, // maximal strength to ignore as non-background
clt_parameters.sure_smth, // sure_smth, // if 2-nd worst image difference (noise-normalized) exceeds this - do not propagate bgnd
clt_parameters.pt_super_trust, // final double super_trust, // If strength exceeds ex_strength * super_trust, do not apply ex_nstrength and plate_ds
// using plates disparity/strength - averaged for small square sets of tiles. If null - just use raw tiles
filtered_disp_strength, // final double [][] plate_ds, // disparity/strength last time measured for the multi-tile squares. Strength =-1 - not measured. May be null
clt_parameters.pt_keep_raw_fg, // final boolean keep_raw_fg, // do not replace raw tiles by the plates, if raw is closer (like poles)
clt_parameters.pt_scale_pre, // final double scale_filtered_strength_pre, // scale plate_ds[1] before comparing to raw strength
clt_parameters.pt_scale_post, // final double scale_filtered_strength_post,// scale plate_ds[1] when replacing raw (generally plate_ds is more reliable if it exists)
ImageDtt.DISPARITY_INDEX_CM, // index of disparity value in disparity_map == 2 (0,2 or 4)
geometryCorrection,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
tp.clt_3d_passes.add(refined);
if (show_expand || (clt_parameters.show_expand && last_pass)) {
tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
"after_refine-"+refine_pass);
}
tp.calcMaxTried(
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,
bg_pass, // final int firstPass,
refine_pass, // may add 1 to include current (for future?) // final int lastPassPlus1,
tp.clt_3d_passes.get(refine_pass)); // final int lastPassPlus1,
// repeated composite scan may be replaced by just a clone
CLTPass3d extended_pass = tp.compositeScan(
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,
bg_pass, // final int firstPass,
tp.clt_3d_passes.size(), // final int lastPassPlus1,
// tp.clt_3d_passes.get(bg_pass).getSelected(), // selected , // final boolean [] bg_tiles, // get from selected in clt_3d_passes.get(0);
// clt_parameters.ex_min_over,// final double ex_min_over, // when expanding over previously detected (by error) background, disregard far tiles
tp.getTrustedCorrelation(), // final double trustedCorrelation,
0.0, // clt_parameters.bgnd_range, // final double disp_far, // limit results to the disparity range
clt_parameters.grow_disp_max, // final double disp_near,
clt_parameters.combine_min_strength, // final double minStrength,
clt_parameters.combine_min_hor, // final double minStrengthHor,
clt_parameters.combine_min_vert, // final double minStrengthVert,
false, // final boolean no_weak,
true, // false, // final boolean use_last, //
// TODO: when useCombo - pay attention to borders (disregard)
false, // final boolean usePoly) // use polynomial method to find max), valid if useCombo == false
true, // final boolean copyDebug)
debugLevel);
if (over_infinity) {
tp.filterOverBackground(
extended_pass, // final CLTPass3d pass,
comboMinStrength, // final double minStrength,
comboMinStrengthHor, // final double minStrengthHor,
comboMinStrengthVert, //final double minStrengthVert,
tp.clt_3d_passes.get(bg_pass).getSelected(), // selected , // final boolean [] bg_tiles, // get from selected in clt_3d_passes.get(0);
clt_parameters.ex_min_over,// final double ex_min_over, // when expanding over previously detected (by error) background, disregard far tiles
filtered_disp_strength);
}
if (show_expand || (clt_parameters.show_expand && last_pass)) tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
"after_refine-combine-"+(tp.clt_3d_passes.size() - 1));
if (show_expand || (clt_parameters.show_expand && last_pass)) {
String [] titles = {"disp","strength", "disp_combined","str_combined","max_tried","selected"};
String title = "FDS_"+(tp.clt_3d_passes.size() - 1);
double [][] dbg_img = new double [titles.length][];
dbg_img[0] = filtered_disp_strength[0];
dbg_img[1] = filtered_disp_strength[1];
dbg_img[2] = extended_pass.getDisparity();
dbg_img[3] = extended_pass.getStrength();
double [][] max_tried_disparity = extended_pass.getMaxTriedDisparity();
if (max_tried_disparity != null){
dbg_img[4] = new double [tilesX * tilesY];
for (int ty = 0; ty < tilesY; ty++){
for (int tx = 0; tx < tilesX; tx++){
dbg_img[4][ty*tilesX + tx] = max_tried_disparity[ty][tx];
}
}
}
boolean [] s_selected = extended_pass.selected;
boolean [] s_border = extended_pass.border_tiles;
if ((s_selected != null) && (s_border != null)){
dbg_img[5] = new double [tilesX * tilesY];
for (int i = 0; i < dbg_img[5].length; i++){
dbg_img[5][i] = 1.0 * ((s_selected[i]?1:0) + (s_border[i]?2:0));
}
}
(new showDoubleFloatArrays()).showArrays(dbg_img, tilesX, tilesY, true, title,titles);
}
if (new_expand) { // show_expand){ // use new mode
if (last_pass){
System.out.println("+++++++++++ Last pass ++++++++++++");
}
// public boolean []
tp.dbg_filtered_disp_strength = filtered_disp_strength; // to be shown inside
boolean [] variants_flags = {
clt_parameters.gr_var_new_sngl,
clt_parameters.gr_var_new_fg,
clt_parameters.gr_var_all_fg,
clt_parameters.gr_var_new_bg,
clt_parameters.gr_var_all_bg,
clt_parameters.gr_var_next};
numLeftRemoved = tp.prepareExpandVariant(
extended_pass, // final CLTPass3d scan, // combined scan with max_tried_disparity, will be modified to re-scan
tp.clt_3d_passes.get(refine_pass), // final CLTPass3d last_scan, // last prepared tile - can use last_scan.disparity, .border_tiles and .selected
tp.clt_3d_passes.get(bg_pass), // final CLTPass3d bg_scan, // background scan data
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,// List, first, last - to search for the already tried disparity
0, // final int firstPass,
tp.clt_3d_passes.size(), // final int lastPassPlus1,
clt_parameters.gr_min_new , // 20, // final int min_new, // discard variant if there are less new tiles
variants_flags, // 0x1e, // 0x1f, // final int variants_mask,
clt_parameters.gr_num_steps , // 8, // final int num_steps, // how far to extend
clt_parameters.gr_steps_over , // 8, // 4, // final int num_steps_disc, // how far to extend
clt_parameters.gr_smpl_size , // 5, // final int smpl_size, // == 5
clt_parameters.gr_min_pnts , // 5, // 4, // 3, // final int min_points, // == 3
clt_parameters.gr_use_wnd , // true, // final boolean use_wnd, // use window function fro the neighbors
clt_parameters.gr_tilt_damp , // 0.001, // final double tilt_cost,
clt_parameters.gr_split_rng , // 5.0, // final double split_threshold, // if full range of the values around the cell higher, need separate fg, bg
clt_parameters.gr_same_rng , // 3.0, // final double same_range, // modify
clt_parameters.gr_diff_cont , // 2.0, // final double diff_continue, // maximal difference from the old value (for previously defined tiles
clt_parameters.gr_abs_tilt , // 2.0, // final double max_abs_tilt, // = 2.0; // pix per tile
clt_parameters.gr_rel_tilt , // 0.2, // final double max_rel_tilt, // = 0.2; // (pix / disparity) per tile
clt_parameters.gr_smooth , // 50, // final int max_tries, // maximal number of smoothing steps
clt_parameters.gr_fin_diff , // 0.01, // final double final_diff, // maximal change to finish iterations
0.0, // clt_parameters.grow_disp_max, // final double grow_disp_min,
clt_parameters.grow_disp_max, // final double grow_disp_max,
clt_parameters.grow_disp_step, // final double grow_disp_step,
clt_parameters.gr_unique_pretol , // 1.0, // final double unique_pre_tolerance, // usually larger than clt_parameters.unique_tolerance
last_pass? clt_parameters.gr_unique_tol : clt_parameters.gr_unique_pretol, // final double unique_tolerance,
clt_parameters. show_expand, // final boolean show_expand,
clt_parameters. show_unique, // final boolean show_unique,
//show_expand
138, // 216, // 214, // 210, // 206, // 204, // 202, // 200, // 198, // final int dbg_x,
149, // 138, // 140, // 142, // 143, // 142, // final int dbg_y,
1); // 2); // 1); // final int debugLevel)
refine_pass = tp.clt_3d_passes.size(); // now points to the extended_pass !!
tp.clt_3d_passes.add(extended_pass);
if (clt_parameters.show_expand || (clt_parameters.show_variant && (numLeftRemoved[1] > 1 ))) tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
"prepareExpandVariant-"+numLeftRemoved[1]+"-"+refine_pass); //String title)
} else { // old way
boolean show_ex_debug = show_retry_far || (clt_parameters.show_retry_far && last_pass) || dbg_pass;
num_extended = tp.setupExtendDisparity(
extended_pass, // final CLTPass3d scan, // combined scan with max_tried_disparity, will be modified to re-scan
tp.clt_3d_passes.get(refine_pass), // final CLTPass3d last_scan, // last prepared tile - can use last_scan.disparity, .border_tiles and .selected
over_infinity? null: tp.clt_3d_passes.get(bg_pass), // final CLTPass3d bg_scan, // background scan data
clt_parameters.grow_sweep, // 8; // Try these number of tiles around known ones
clt_parameters.grow_disp_max, // = 50.0; // Maximal disparity to try
0.5 * clt_parameters.grow_disp_trust, // = 4.0; // Trust measured disparity within +/- this value
clt_parameters.grow_disp_step, // = 6.0; // Increase disparity (from maximal tried) if nothing found in that tile // TODO: handle enclosed dips?
clt_parameters.grow_min_diff, // = 0.5; // Grow more only if at least one channel has higher variance from others for the tile
clt_parameters.grow_retry_far, // final boolean grow_retry_far, // Retry tiles around known foreground that have low max_tried_disparity
clt_parameters.grow_pedantic, // final boolean grow_pedantic, // Scan full range between max_tried_disparity of the background and known foreground
clt_parameters.grow_retry_inf, // final boolean grow_retry_inf, // Retry border tiles that were identified as infinity earlier
clt_parameters, // EyesisCorrectionParameters.CLTParameters clt_parameters,
geometryCorrection, // GeometryCorrection geometryCorrection,
show_ex_debug, // true, // final boolean show_debug,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
//TODO: break if nothing wanted? - no, there are some left to be refined
if (debugLevel > -1){
System.out.println("=== setupExtendDisparity() pass:"+num_expand+" added "+num_extended+" new tiles to scan");
}
refine_pass = tp.clt_3d_passes.size(); // 1
tp.clt_3d_passes.add(extended_pass);
numLeftRemoved = tp.makeUnique(
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,
0, // final int firstPass,
refine_pass, // - 1, // final int lastPassPlus1,
tp.clt_3d_passes.get(refine_pass), // final CLTPass3d new_scan,
clt_parameters.grow_disp_max, // final double grow_disp_max,
clt_parameters.gr_unique_tol, // final double unique_tolerance,
clt_parameters.show_unique); // final boolean show_unique)
if (show_expand) tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
"before_measure-"+refine_pass); //String title)
if (debugLevel > -1){
System.out.println("last makeUnique("+refine_pass+") -> left: "+numLeftRemoved[0]+", removed:" + numLeftRemoved[1]);
}
// num_extended = numLeftRemoved[0];
//TODO: break if nothing wanted? - here yes, will make sense
} // end of old way
// } // if (use_zMapExpansionStep) else
//// num_extended = numLeftRemoved[0];
// refine_pass = tp.clt_3d_passes.size(); //
//java.lang.IndexOutOfBoundsException: Index: 43, Size: 35
refine_pass = tp.clt_3d_passes.size() - 1; // was not here!
CLTMeasure( // perform single pass according to prepared tiles operations and disparity
image_data, // first index - number of image in a quad
clt_parameters,
refine_pass,
false, // final boolean save_textures,
threadsMax, // maximal number of threads to launch
updateStatus,
debugLevel);
// ********************************************** //
tp.removeNonMeasurement();
refine_pass = tp.clt_3d_passes.size() - 1;
// ********************************************** //
if (show_expand || (clt_parameters.show_expand && last_pass)) {
tp.showScan(
tp.clt_3d_passes.get(refine_pass), // CLTPass3d scan,
"after_measure-"+refine_pass); //String title)
// just testing:
}
if (debugLevel > -1){
System.out.println("extending: CLTMeasure("+refine_pass+"), num_extended = "+num_extended);
}
//num_expand == 9
CLTPass3d combo_pass = tp.compositeScan(
tp.clt_3d_passes, // final ArrayList <CLTPass3d> passes,
bg_pass, // final int firstPass,
tp.clt_3d_passes.size(), // final int lastPassPlus1,
tp.getTrustedCorrelation(), // final double trustedCorrelation,
-0.5, // 0.0, // clt_parameters.bgnd_range, // final double disp_far, // limit results to the disparity range
clt_parameters.grow_disp_max, // final double disp_near,
clt_parameters.combine_min_strength, // final double minStrength,
clt_parameters.combine_min_hor, // final double minStrengthHor,
clt_parameters.combine_min_vert, // final double minStrengthVert,
false, // final boolean no_weak,
false, // final boolean use_last, //
// TODO: when useCombo - pay attention to borders (disregard)
false, // final boolean usePoly) // use polynomial method to find max), valid if useCombo == false
true, // final boolean copyDebug)
// (num_expand == 9)? 2: debugLevel);
debugLevel);
// tp.filterOverBackground(
// combo_pass, // final CLTPass3d pass,
// comboMinStrength, // final double minStrength,
// comboMinStrengthHor, // final double minStrengthHor,
// comboMinStrengthVert, //final double minStrengthVert,
// tp.clt_3d_passes.get(bg_pass).getSelected(), // selected , // final boolean [] bg_tiles, // get from selected in clt_3d_passes.get(0);
// clt_parameters.ex_min_over);// final double ex_min_over, // when expanding over previously detected (by error) background, disregard far tiles
tp.clt_3d_passes.add(combo_pass);
// refine_pass = tp.clt_3d_passes.size();
// }
if (show_expand || (clt_parameters.show_expand && last_pass)) tp.showScan(
tp.clt_3d_passes.get(tp.clt_3d_passes.size() -1), // refine_pass), // CLTPass3d scan,
"after_combo_pass-"+(tp.clt_3d_passes.size() -1)); // (refine_pass)); //String title)
} // if (use_zMapExpansionStep) else
if (last_pass) {
break;
} else if (num_extended == 0){
......@@ -6867,7 +6256,7 @@ public class QuadCLT {
clt_parameters,
colorProcParameters,
rgbParameters,
this.image_name+"-img_bgnd", // +scanIndex,
this.image_name+"-img_infinity", // +scanIndex,
scanIndex,
threadsMax, // maximal number of threads to launch
updateStatus,
......@@ -6886,7 +6275,8 @@ public class QuadCLT {
generateClusterX3d(
x3dOutput,
texturePath,
"shape_id-bgnd", // (scanIndex - next_pass), // id
"INFINITY", // id (scanIndex - next_pass), // id
"INFINITY", // class
scan.getTextureBounds(),
scan.selected,
scan_disparity, // scan.disparity_map[ImageDtt.DISPARITY_INDEX_CM],
......@@ -6990,6 +6380,7 @@ public class QuadCLT {
x3dOutput,
texturePath,
"shape_id-"+(scanIndex - next_pass), // id
null, // class
scan.getTextureBounds(),
scan.selected,
scan_disparity, // scan.disparity_map[ImageDtt.DISPARITY_INDEX_CM],
......@@ -7022,6 +6413,7 @@ public class QuadCLT {
X3dOutput x3dOutput,
String texturePath,
String id,
String class_name,
Rectangle bounds,
boolean [] selected,
double [] disparity, // if null, will use min_disparity
......@@ -7084,6 +6476,7 @@ public class QuadCLT {
x3dOutput.addCluster(
texturePath,
id,
class_name,
texCoord,
worldXYZ,
triangles);
......
......@@ -2726,7 +2726,7 @@ public class SuperTiles{
smplRms, // final double smplRms, // = 0.1; // Maximal RMS of the remaining tiles in a sample
smplWnd, // final boolean smplWnd, // use window functions for the samples
debugLevel + 1, // + 2, // 1, // final int debugLevel,
debugLevel + 0, // 1, // + 2, // 1, // final int debugLevel,
dbg_X, // final int dbg_X,
dbg_Y); // final int dbg_Y)
this.planes = new_planes; // save as "measured" (as opposed to "smoothed" by neighbors) planes
......
......@@ -955,7 +955,7 @@ diff_best= 0.06731 diff9= 1.09087 weak_fgnd= 0.22250 flaps= 0.07229 ml_mismatch
// now diff is for the center, weight needs to be re-calculated
if (strengthDiffPwr > 0.0) {
if ((dispStrength[ml] == null) || (dispStrength[ml][nSurfTile] == null)){
System.out.println("getTileCosts() nSurfTile = "+nSurfTile+" ml = "+ml+" BUG - null pointer");
System.out.println("getTileCosts() nSurfTile = "+nSurfTile+" ml = "+ml+" is it really a BUG - null pointer here?");
weight = 1.0;
} else {
weight = dispStrength[ml][nSurfTile][1]; // null pointer
......
......@@ -5235,7 +5235,7 @@ public class TileProcessor {
lp.conditionSuperTiles(
st.planes, // final TilePlanes.PlaneData [][] planes,
10, // final int max_num_merge_try,
1); // debugLevel); // final int debugLevel);
0); // 1); // debugLevel); // final int debugLevel);
// Used only by conflicts (not processed currently)
lp.calcStarValueStrength(
true, // boolean set_start_planes,
......
......@@ -114,6 +114,7 @@ public class X3dOutput {
public void addCluster(
String url,
String id,
String class_name,
double [][] texCoord,
double [][] coordinate,
int [][] triangles)
......@@ -159,7 +160,8 @@ public class X3dOutput {
Element el_shape = x3dDoc.createElement("Shape");
el_Scene.appendChild(el_shape);
el_shape.setAttribute("id",id);
if (id != null) el_shape.setAttribute("id",id);
if (class_name != null) el_shape.setAttribute("class",class_name);
Element el_appearance = x3dDoc.createElement("Appearance");
el_shape.appendChild(el_appearance);
......
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