Commit 7ba9c309 authored by Andrey Filippov's avatar Andrey Filippov

Finished (not yet tested/debugged) CorrVector update for number of

cameras > 4
parent 36dcabff
...@@ -22,22 +22,14 @@ package com.elphel.imagej.tileprocessor; ...@@ -22,22 +22,14 @@ package com.elphel.imagej.tileprocessor;
** -----------------------------------------------------------------------------** ** -----------------------------------------------------------------------------**
*/ */
import java.util.ArrayList;
import com.elphel.imagej.common.GenericJTabbedDialog; import com.elphel.imagej.common.GenericJTabbedDialog;
//import com.elphel.imagej.tileprocessor.GeometryCorrection.CorrVector; //import com.elphel.imagej.tileprocessor.GeometryCorrection.CorrVector;
import Jama.Matrix; import Jama.Matrix;
public class CorrVector{ // TODO: Update to non-quad (extract to a file first)? public class CorrVector{ // TODO: Update to non-quad (extract to a file first)?
// get rid of these !
/*
private static final int LENGTH =19; // 10; // was public
private static final int LENGTH_ANGLES =10;
private static final int TILT_INDEX = 0;
private static final int AZIMUTH_INDEX = 3;
private static final int ROLL_INDEX = 6;
private static final int ZOOM_INDEX = 10;
private static final int IMU_INDEX = 13; // d_tilt/dt (rad/s), d_az/dt, d_roll/dt for ERS correction, dx/dt, dy/dt, dz/dt
*/
private static final double ROT_AZ_SGN = -1.0; // sign of first sin for azimuth rotation private static final double ROT_AZ_SGN = -1.0; // sign of first sin for azimuth rotation
private static final double ROT_TL_SGN = 1.0; // sign of first sin for tilt rotation private static final double ROT_TL_SGN = 1.0; // sign of first sin for tilt rotation
...@@ -513,15 +505,6 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)? ...@@ -513,15 +505,6 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)?
} }
} }
/*
public double setZoomsFromF(double f0, double f1, double f2, double f3) { // USED in lwir
double f_avg = (f0+f1+f2+f3)/4;
vector[10] = (f0 - f_avg)/f_avg;
vector[11] = (f1 - f_avg)/f_avg;
vector[12] = (f2 - f_avg)/f_avg;
return f_avg;
}
*/
public double setZoomsFromF(double [] f) { // USED in lwir public double setZoomsFromF(double [] f) { // USED in lwir
int indx = getZoomIndex(); int indx = getZoomIndex();
// double f_avg = (f0+f1+f2+f3)/4; // double f_avg = (f0+f1+f2+f3)/4;
...@@ -537,15 +520,6 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)? ...@@ -537,15 +520,6 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)?
} }
// Tilts in radians, theta in degrees // Tilts in radians, theta in degrees
/*
public double setTiltsFromThetas(double t0, double t1, double t2, double t3) { // USED in lwir
double t_avg = (t0+t1+t2+t3)/4;
vector[0] = (t0 - t_avg)*Math.PI/180.0;
vector[1] = (t1 - t_avg)*Math.PI/180.0;
vector[2] = (t2 - t_avg)*Math.PI/180.0;
return t_avg;
}
*/
public double setTiltsFromThetas(double [] t) { // USED in lwir public double setTiltsFromThetas(double [] t) { // USED in lwir
int indx = getTiltIndex(); int indx = getTiltIndex();
double t_avg = 0; double t_avg = 0;
...@@ -560,15 +534,6 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)? ...@@ -560,15 +534,6 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)?
} }
// Azimuths in radians, headings in degrees // Azimuths in radians, headings in degrees
/*
public double setAzimuthsFromHeadings(double h0, double h1, double h2, double h3) { // USED in lwir
double h_avg = (h0+h1+h2+h3)/4;
vector[3] = (h0 - h_avg)*Math.PI/180.0;
vector[4] = (h1 - h_avg)*Math.PI/180.0;
vector[5] = (h2 - h_avg)*Math.PI/180.0;
return h_avg;
}
*/
public double setAzimuthsFromHeadings(double [] h) { // USED in lwir public double setAzimuthsFromHeadings(double [] h) { // USED in lwir
int indx = getAzimuthIndex(); int indx = getAzimuthIndex();
double h_avg = 0; double h_avg = 0;
...@@ -583,18 +548,6 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)? ...@@ -583,18 +548,6 @@ public class CorrVector{ // TODO: Update to non-quad (extract to a file first)?
} }
// Include factory calibration rolls // Include factory calibration rolls
/*
public double [] getFullRolls() // USED in lwir
{
double d2r= Math.PI/180.0;
double [] rolls = {
vector[6] + d2r * geometryCorrection.roll[0],
vector[7] + d2r * geometryCorrection.roll[1],
vector[8] + d2r * geometryCorrection.roll[2],
vector[9] + d2r * geometryCorrection.roll[3]};
return rolls;
}
*/
public double [] getFullRolls() // USED in lwir public double [] getFullRolls() // USED in lwir
{ {
int indx =getRollIndex(); int indx =getRollIndex();
...@@ -944,6 +897,7 @@ Vector # 3 [-|+|-|+] 1.00<1.00 [1.0 | 1.0 | 1.0 | 1.0 ] l= 1.0 n=1(1) ...@@ -944,6 +897,7 @@ Vector # 3 [-|+|-|+] 1.00<1.00 [1.0 | 1.0 | 1.0 | 1.0 ] l= 1.0 n=1(1)
* 0: |⇗ ⇖| 1: |⇙ ⇖| 2: |⇖ ⇙| 3: |⇖ ⇗| 4: |⇗ ⇙| 5: |⇘ ⇖| * 0: |⇗ ⇖| 1: |⇙ ⇖| 2: |⇖ ⇙| 3: |⇖ ⇗| 4: |⇗ ⇙| 5: |⇘ ⇖|
* *
*/ */
/*
public double [][] dSym_j_dTar_i() // USED in lwir public double [][] dSym_j_dTar_i() // USED in lwir
{ {
double [][] tar_to_sym = { double [][] tar_to_sym = {
...@@ -979,6 +933,8 @@ Vector # 3 [-|+|-|+] 1.00<1.00 [1.0 | 1.0 | 1.0 | 1.0 ] l= 1.0 n=1(1) ...@@ -979,6 +933,8 @@ Vector # 3 [-|+|-|+] 1.00<1.00 [1.0 | 1.0 | 1.0 | 1.0 ] l= 1.0 n=1(1)
// Matrix sym_to_tar = new Matrix(symToTARArray()); // Matrix sym_to_tar = new Matrix(symToTARArray());
// Matrix tar_to_sym = sym_to_tar.inverse(); // Matrix tar_to_sym = sym_to_tar.inverse();
// return tar_to_sym.getArray(); // return tar_to_sym.getArray();
*/
/* /*
a=[ a=[
[-2.0, -2.0, 2.0, -2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [-2.0, -2.0, 2.0, -2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
...@@ -1010,6 +966,7 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0. ...@@ -1010,6 +966,7 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0.
[-0. , -0. , -0. , -0. , -0. , -0. , -0. , -0. , -0. , -0. , -0.5 , -0.5 , 0.5 ], [-0. , -0. , -0. , -0. , -0. , -0. , -0. , -0. , -0. , -0. , -0.5 , -0.5 , 0.5 ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , -0.5 , 0.5 , 0.5 ]]) [ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , -0.5 , 0.5 , 0.5 ]])
*/ */
/*
double [][] sym_to_tar= { // USED in lwir double [][] sym_to_tar= { // USED in lwir
// t0 t1 t2 a0 a1 a2 r0 r1 r2 r3 s0 s1 s2 // t0 t1 t2 a0 a1 a2 r0 r1 r2 r3 s0 s1 s2
{-0.125,-0.125, 0.125, 0.125,-0.125, 0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // sym0 {-0.125,-0.125, 0.125, 0.125,-0.125, 0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, // sym0
...@@ -1034,7 +991,7 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0. ...@@ -1034,7 +991,7 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0.
} ; } ;
return sym_to_tar; return sym_to_tar;
} }
*/
public boolean [] getParMask( // USED in lwir public boolean [] getParMask( // USED in lwir
boolean use_disparity, boolean use_disparity,
boolean use_aztilts, // Adjust azimuths and tilts excluding disparity boolean use_aztilts, // Adjust azimuths and tilts excluding disparity
...@@ -1122,11 +1079,27 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0. ...@@ -1122,11 +1079,27 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0.
* UPDATE * UPDATE
* @return * @return
*/ */
public double [][] getJtPartial( // USED in lwir public double [][] getJtPartial( // USED in lwir
double [][] port_coord_deriv, double [][] port_coord_deriv,
boolean [] par_mask) boolean [] par_mask)
{ {
Matrix from_sym = symmVectorsSet.from_sym;
if (par_mask != null) {
ArrayList<Integer> par_list = new ArrayList<Integer>();
for (int i = 0; i < par_mask.length; i++) {
if (par_mask[i]) {
par_list.add(i);
}
}
if (par_list.size() < par_mask.length) {
int[] sub_pars = par_list.stream().mapToInt(i -> i).toArray(); // Java8
from_sym = from_sym.getMatrix(0, par_mask.length,sub_pars); // remove masked columns
}
}
Matrix pcd = new Matrix (port_coord_deriv); // rows: px0,py0,... px[n-1], py[n-1], columns: tar
Matrix mjt_part = pcd.times(from_sym).transpose(); // rows: sym0..., columns: px0,py0,... px[n-1], py[n-1]
return mjt_part.getArray();
/*
int num_pars = 0; int num_pars = 0;
for (int npar = 0; npar < getLength(); npar++) if ((par_mask==null) || par_mask[npar]) { for (int npar = 0; npar < getLength(); npar++) if ((par_mask==null) || par_mask[npar]) {
num_pars++; num_pars++;
...@@ -1143,14 +1116,18 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0. ...@@ -1143,14 +1116,18 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0.
opar++; opar++;
} }
return jt_part; return jt_part;
*/
} }
// convert tilt0,... roll3 array to symmetrical coordinates [0] - to the center (disparity) // convert tilt0,... roll3 array to symmetrical coordinates [0] - to the center (disparity)
// Use public void setMatrix (int[] r, int[] c, Matrix X) ?
// symmVectorsSet.from_sym, symmVectorsSet.to_sym;
public double [] toSymArray(boolean [] par_mask) // USED in lwir public double [] toSymArray(boolean [] par_mask) // USED in lwir
{ {
return toSymArray(this.vector, par_mask); return toSymArray(this.vector, par_mask);
} }
/*
public double [] toSymArray( // USED in lwir public double [] toSymArray( // USED in lwir
double [] tar_array, double [] tar_array,
boolean [] par_mask) boolean [] par_mask)
...@@ -1186,4 +1163,49 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0. ...@@ -1186,4 +1163,49 @@ matrix([[-0.125, -0.125, 0.125, 0.125, -0.125, 0.125, -0. , -0. , -0.
} }
return tar_array; return tar_array;
} }
*/
public double [] toSymArray( // USED in lwir
double [] tar_array,
boolean [] par_mask)
{
Matrix to_sym = symmVectorsSet.to_sym;
if (par_mask != null) {
ArrayList<Integer> par_list = new ArrayList<Integer>();
for (int i = 0; i < par_mask.length; i++) {
if (par_mask[i]) {
par_list.add(i);
}
}
if (par_list.size() < par_mask.length) {
int[] sub_pars = par_list.stream().mapToInt(i -> i).toArray(); // Java8
to_sym = to_sym.getMatrix(sub_pars, 0, par_mask.length); // remove masked rows
}
}
Matrix tar = new Matrix(tar_array,tar_array.length);
Matrix sym = to_sym.times(tar);
return sym.getColumnPackedCopy();
}
public double [] toTarArray( // USED in lwir
double [] sym_array,
boolean [] par_mask)
{
Matrix from_sym = symmVectorsSet.from_sym;
if (par_mask != null) {
ArrayList<Integer> par_list = new ArrayList<Integer>();
for (int i = 0; i < par_mask.length; i++) {
if (par_mask[i]) {
par_list.add(i);
}
}
if (par_list.size() < par_mask.length) {
int[] sub_pars = par_list.stream().mapToInt(i -> i).toArray(); // Java8
from_sym = from_sym.getMatrix(0, par_mask.length,sub_pars); // remove masked columns
}
}
Matrix sym = new Matrix(sym_array,sym_array.length);
Matrix tar = from_sym.times(sym);
return tar.getColumnPackedCopy();
}
} }
...@@ -3,6 +3,8 @@ package com.elphel.imagej.tileprocessor; ...@@ -3,6 +3,8 @@ package com.elphel.imagej.tileprocessor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import Jama.Matrix;
/** /**
** **
** SymmVector - Generating symmetrical geometry correction vectors for multi-camera ** SymmVector - Generating symmetrical geometry correction vectors for multi-camera
...@@ -28,6 +30,9 @@ import java.util.HashMap; ...@@ -28,6 +30,9 @@ import java.util.HashMap;
*/ */
public class SymmVector { public class SymmVector {
public static int TILT_SIGN = -1;
public static int AZIMUTH_SIGN = 1;
public static int NUM_ERS = 6;
public static int R_MINUS = 0; // radial inwards public static int R_MINUS = 0; // radial inwards
public static int T_PLUS = 1; // tangential clockwise public static int T_PLUS = 1; // tangential clockwise
public static int R_PLUS = 2; // radial outwards public static int R_PLUS = 2; // radial outwards
...@@ -102,6 +107,9 @@ public class SymmVector { ...@@ -102,6 +107,9 @@ public class SymmVector {
rvs.dir_rt = sv.exportDirRT(); rvs.dir_rt = sv.exportDirRT();
rvs.rots = sv.exportRZ(false); // include common roll rvs.rots = sv.exportRZ(false); // include common roll
rvs.zooms = sv.exportRZ(true); // no common zoom rvs.zooms = sv.exportRZ(true); // no common zoom
Matrix[] fts = sv.fromToSym();
rvs.from_sym = fts[0];
rvs.to_sym = fts[1];
return rvs; return rvs;
} }
...@@ -1111,7 +1119,86 @@ public class SymmVector { ...@@ -1111,7 +1119,86 @@ public class SymmVector {
* *
* No need for _extra? * No need for _extra?
* *
public static int TILT_SIGN = -1;
public static int AZIMUTH_SIGN = 1;
*
*/
public Matrix taToSym() {
// restore last tilt, azimuth, reorder to {-tilt[0], azimuth[0], ... -tilt[N-1], azimuth[N-1]
Matrix ta2xy = new Matrix(2*N, 2*N-2);
for (int i = 0; i < N - 1; i++) {
ta2xy.set(2 * i + 0, N -1 + i, AZIMUTH_SIGN);
ta2xy.set(2 * N - 2, N -1 + i, -AZIMUTH_SIGN);
ta2xy.set(2 * i + 1, i, TILT_SIGN);
ta2xy.set(2 * N - 1, i, -TILT_SIGN);
}
// convert from "X,Y"
return null;
}
/**
* Create a submatrix to convert 2*N-2 sym vectors to concatenated {tilt[0:N-2],azimuth[0:N-2]}.
* @param xy alternating XY components of "symmetrical" vectors as generated
* @return
*/
public Matrix symToTA(double [][] xy) {
// rows - "symmetrical" vectors, columns {x0,y0,..., x{N-2],y[N-2]
Matrix sym2xy = (new Matrix(xy)).getMatrix(0, 2*N-3, 0, 2*N-3).transpose(); // drop last two columns
// reorder and change sign (for tilts
Matrix xy2ta = new Matrix (2*N-2, 2*N-2);
for (int i = 0; i < N - 1; i++) {
xy2ta.set( i, 2* i + 1, TILT_SIGN);
xy2ta.set(N-1+i, 2 *i + 0, AZIMUTH_SIGN);
}
return xy2ta.times(sym2xy);
}
/**
* Convert N symmetrical rotation vectors to individual cameras rolls
* @param rots symmetrical rotation vectors
* @return conversion Matrix
*/
public Matrix symToRoll(double [][] rots) {
return (new Matrix(rots)).transpose(); // columns - sym. vectors, rows - rolls of individual cameras
}
/**
* Convert N-1 symmetrical zoom vectors to zooms of the first N-1 cameras
* @param zooms symmetrical zoom vectors
* @return conversion matrix
*/ */
public Matrix symToZoom(double [][] zooms) { // average zoom == 0,
return (new Matrix(zooms)).getMatrix(0, N-2, 0, N-2).transpose(); // drop zooms of the last camera
}
public Matrix[] fromToSym() {
Matrix sym2ta = symToTA(exportXY()); // 2*N-2
Matrix sym2roll = symToRoll(exportRZ(false)); // N
Matrix sym2zoom = symToRoll(exportRZ(true)); // N-1
Matrix sym2ers = Matrix.identity(NUM_ERS,NUM_ERS);// NUM_ERS
int i0 = 0;
int i1 = i0 + sym2ta.getColumnDimension();
int i2 = i1 + sym2roll.getColumnDimension();
int i3 = i2 + sym2zoom.getColumnDimension();
int i4 = i3 + sym2ers.getColumnDimension();
Matrix from_sym = new Matrix(i4,i4);
from_sym.setMatrix(i0,i1-1,i0,i1-1, sym2ta);
from_sym.setMatrix(i1,i2-1,i1,i2-1, sym2roll);
from_sym.setMatrix(i2,i3-1,i2,i3-1, sym2zoom);
from_sym.setMatrix(i3,i4-1,i4,i4-1, sym2ers);
Matrix to_sym = new Matrix(i4,i4);
to_sym.setMatrix(i0,i1-1,i0,i1-1, sym2ta.inverse());
to_sym.setMatrix(i1,i2-1,i1,i2-1, sym2roll.inverse());
to_sym.setMatrix(i2,i3-1,i2,i3-1, sym2zoom.inverse());
to_sym.setMatrix(i3,i4-1,i4,i4-1, sym2ers.inverse());
return new Matrix[] {from_sym,to_sym};
}
//getColumnDimension
} }
class SymmVectorsSet { class SymmVectorsSet {
...@@ -1121,5 +1208,7 @@ class SymmVectorsSet { ...@@ -1121,5 +1208,7 @@ class SymmVectorsSet {
int [][] dir_rt; int [][] dir_rt;
double [][] rots; double [][] rots;
double [][] zooms; double [][] zooms;
Matrix from_sym;
Matrix to_sym;
} }
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