Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TrifocalTensor.cpp
1 #include "TrifocalTensor.hh"
2 #include <Base/Debug/DebugSimple.hh>
3 #include <MathAlgo/SVD.hh>
4 
5 using namespace std;
6 using namespace BIAS;
7 
8 
9 TrifocalTensor::TrifocalTensor()
10 {
11  Init();
12 }
13 
14 
15 TrifocalTensor::~TrifocalTensor()
16 {
17 }
18 
19 
20 TrifocalTensor::TrifocalTensor(BIAS::PMatrix &P1, BIAS::PMatrix &P2,
21  BIAS::PMatrix &P3)
22 {
23  Init();
24  Compose( P1, P2, P3 );
25 }
26 
27 
28 TrifocalTensor::TrifocalTensor(BIAS::PMatrix &P2, BIAS::PMatrix &P3)
29 {
30  Init();
31  Compose( P2, P3 );
32 }
33 
34 
35 void TrifocalTensor::Init()
36 {
37  Epipole21_ = NULL;
38  Epipole31_ = NULL;
39 }
40 
41 
42 void TrifocalTensor::Compose(BIAS::PMatrix &P1, BIAS::PMatrix &P2, BIAS::PMatrix &P3)
43 {
44  if ( P1.IsIdentity() ) Compose( P2, P3 ); // P1 is canonical ( P1=[I|0] )
45  P1.GetCanonicalH(CanH_);
46  PMatrix P2c(P2 * CanH_);
47  PMatrix P3c(P3 * CanH_);
48 // COUT("new P2 is " << P2c << endl);
49 // COUT("new P3 is " << P3c << endl);
50  Compose( P2c, P3c );
51 }
52 
53 
54 void TrifocalTensor::Compose(BIAS::PMatrix &P2, BIAS::PMatrix &P3)
55 {
57  Vector3<double> a,b,c,d;
58  for(int i=0;i<3;i++)
59  {
60  a = P2.GetCol(i);
61  b = P3.GetCol(3);
62  c = P2.GetCol(3);
63  d = P3.GetCol(i);
64  T[i] = a.OuterProduct(b) - c.OuterProduct(d);
65  }
66  SetFromMatrices( T[0], T[1], T[2] );
67 }
68 
69 
70 void TrifocalTensor::ComputeEpipoles()
71 {
72  if ( Epipole21_!=NULL ) delete Epipole21_;
73  if ( Epipole31_!=NULL ) delete Epipole31_;
75  Vector<TRIFOCALTENSOR_TYPE> u1(3),u2(3),u3(3);
76  Vector<TRIFOCALTENSOR_TYPE> v1(3),v2(3),v3(3);
77 
78  GetMatrices(T1, T2, T3);
79 
80  SVD svd1((Matrix<TRIFOCALTENSOR_TYPE>)(T1));
81  SVD svd2((Matrix<TRIFOCALTENSOR_TYPE>)(T2));
82  SVD svd3((Matrix<TRIFOCALTENSOR_TYPE>)(T3));
83 
84  // compute u_i^\top T_i = 0^\top
85  u1 = svd1.GetLeftNullvector();
86  u2 = svd2.GetLeftNullvector();
87  u3 = svd3.GetLeftNullvector();
88 
89  // compute T_i v_i = 0
90  v1 = svd1.GetNullvector();
91  v2 = svd2.GetNullvector();
92  v3 = svd3.GetNullvector();
93 
94  // compose [u1,u2,u3]
96  U[0][0] = u1[0]; U[0][1] = u2[0]; U[0][2] = u3[0];
97  U[1][0] = u1[1]; U[1][1] = u2[1]; U[1][2] = u3[1];
98  U[2][0] = u1[2]; U[2][1] = u2[2]; U[2][2] = u3[2];
99 
100  // compose [v1,v2,v3]
102  V[0][0] = v1[0]; V[0][1] = v2[0]; V[0][2] = v3[0];
103  V[1][0] = v1[1]; V[1][1] = v2[1]; V[1][2] = v3[1];
104  V[2][0] = v1[2]; V[2][1] = v2[2]; V[2][2] = v3[2];
105 
106  SVD svdu((Matrix<TRIFOCALTENSOR_TYPE>)(U));
107  SVD svdv((Matrix<TRIFOCALTENSOR_TYPE>)(V));
108 
109  // e'^\top [u1,u2,u3] = 0
110  Epipole21_ = new HomgPoint2D(Vector3<double>(svdu.GetLeftNullvector()));
111  // e''^\top [v1,v2,v3] = 0
112  Epipole31_ = new HomgPoint2D(Vector3<double>(svdv.GetLeftNullvector()));
113 }
114 
115 HomgPoint2D TrifocalTensor::GetEpipole21( bool ForceReCalc )
116 {
117  if ( Epipole21_==NULL || ForceReCalc ) ComputeEpipoles();
118  return *Epipole21_;
119 }
120 
121 
122 HomgPoint2D TrifocalTensor::GetEpipole31( bool ForceReCalc )
123 {
124  if ( Epipole31_==NULL || ForceReCalc ) ComputeEpipoles();
125  return *Epipole31_;
126 }
127 
128 FMatrix TrifocalTensor::GetFMatrix21( bool ForceReCalc )
129 {
130  FMatrix F;
131  Vector3<TRIFOCALTENSOR_TYPE> f1,f2,f3,tmp;
132  HomgPoint2D e2 = GetEpipole21(ForceReCalc);
133  HomgPoint2D e3 = GetEpipole31();
134  Vector3<TRIFOCALTENSOR_TYPE> e21(e2[0],e2[1],e2[2]);
135  Vector3<TRIFOCALTENSOR_TYPE> e31(e3[0],e3[1],e3[2]);
136 
138  GetMatrices(T1, T2, T3);
139 
140  T1.Mult(e31,tmp);
141  f1 = e21.CrossProduct(tmp);
142  T2.Mult(e31,tmp);
143  f2 = e21.CrossProduct(tmp);
144  T3.Mult(e31,tmp);
145  f3 = e21.CrossProduct(tmp);
146 
147  F[0][0] = f1[0]; F[0][1] = f2[0]; F[0][2] = f3[0];
148  F[1][0] = f1[1]; F[1][1] = f2[1]; F[1][2] = f3[1];
149  F[2][0] = f1[2]; F[2][1] = f2[2]; F[2][2] = f3[2];
150 
151  return F;
152 }
153 
154 
155 FMatrix TrifocalTensor::GetFMatrix31( bool ForceReCalc )
156 {
157  FMatrix F;
158  Vector3<TRIFOCALTENSOR_TYPE> f1,f2,f3,tmp;
159  HomgPoint2D e2 = GetEpipole21(ForceReCalc);
160  HomgPoint2D e3 = GetEpipole31();
161  Vector3<TRIFOCALTENSOR_TYPE> e21(e2[0],e2[1],e2[2]);
162  Vector3<TRIFOCALTENSOR_TYPE> e31(e3[0],e3[1],e3[2]);
163 
165  GetMatrices(T1, T2, T3);
166 
167  T1.Mult(e21,tmp);
168  f1 = e31.CrossProduct(tmp);
169  T2.Mult(e21,tmp);
170  f2 = e31.CrossProduct(tmp);
171  T3.Mult(e21,tmp);
172  f3 = e31.CrossProduct(tmp);
173 
174  F[0][0] = f1[0]; F[0][1] = f2[0]; F[0][2] = f3[0];
175  F[1][0] = f1[1]; F[1][1] = f2[1]; F[1][2] = f3[1];
176  F[2][0] = f1[2]; F[2][1] = f2[2]; F[2][2] = f3[2];
177 
178  return F;
179 }
180 
181 
182 PMatrix TrifocalTensor::GetPMatrix2( bool ForceReCalc )
183 {
184  PMatrix P;
185  HomgPoint2D e2 = GetEpipole21(ForceReCalc);
186  HomgPoint2D e3 = GetEpipole31();
187  e2.Normalize();
188  e3.Normalize();
189  Vector3<TRIFOCALTENSOR_TYPE> e31(e3[0],e3[1],e3[2]);
191 
193  GetMatrices(T1, T2, T3);
194 
195  T1.Mult(e31,p1);
196  T2.Mult(e31,p2);
197  T3.Mult(e31,p3);
198 
199  P[0][0] = p1[0]; P[0][1] = p2[0]; P[0][2] = p3[0]; P[0][3] = e2[0];
200  P[1][0] = p1[1]; P[1][1] = p2[1]; P[1][2] = p3[1]; P[1][3] = e2[1];
201  P[2][0] = p1[2]; P[2][1] = p2[2]; P[2][2] = p3[2]; P[2][3] = e2[2];
202 
203  return P;
204 }
205 
206 
207 PMatrix TrifocalTensor::GetPMatrix3( bool ForceReCalc )
208 {
209  PMatrix P;
210  HomgPoint2D e2 = GetEpipole21(ForceReCalc);
211  HomgPoint2D e3 = GetEpipole31();
212  e2.Normalize();
213  e3.Normalize();
214  Vector3<TRIFOCALTENSOR_TYPE> e21(e2[0],e2[1],e2[2]);
215  Vector3<TRIFOCALTENSOR_TYPE> p1,p2,p3,tmp;
216 
218  GetMatrices(T1, T2, T3);
219  T1 = T1.Transpose();
220  T2 = T2.Transpose();
221  T3 = T3.Transpose();
222 
224  // compute [e''e''^\top-I]
225  M[0][0] = e3[0]*e3[0]-1; M[0][1] = e3[1]*e3[0]; M[0][2] = e3[2]*e3[0];
226  M[1][0] = e3[0]*e3[1]; M[1][1] = e3[1]*e3[1]-1; M[1][2] = e3[2]*e3[1];
227  M[2][0] = e3[0]*e3[2]; M[2][1] = e3[1]*e3[2]; M[2][2] = e3[2]*e3[2]-1;
228 
229  T1.Mult(e21,tmp);
230  M.Mult(tmp,p1);
231  T2.Mult(e21,tmp);
232  M.Mult(tmp,p2);
233  T3.Mult(e21,tmp);
234  M.Mult(tmp,p3);
235 
236  P[0][0] = p1[0]; P[0][1] = p2[0]; P[0][2] = p3[0]; P[0][3] = e3[0];
237  P[1][0] = p1[1]; P[1][1] = p2[1]; P[1][2] = p3[1]; P[1][3] = e3[1];
238  P[2][0] = p1[2]; P[2][1] = p2[2]; P[2][2] = p3[2]; P[2][3] = e3[2];
239 
240  return P;
241 }
242 
243 
244 void
245 TrifocalTensor::GetEpipolarLines(Vector3<TRIFOCALTENSOR_TYPE> &Point1,
246  HomgLine2D &Line2,
247  HomgLine2D &Line3)
248 {
249  Matrix3x3<TRIFOCALTENSOR_TYPE> M = LeftContravariantContraction1(Point1);
250 
252 
253  Line2 = HomgLine2D(svd.GetLeftNullvector());
254  Line3 = HomgLine2D(svd.GetNullvector());
255 }
256 
257 
258 HomgPoint2D TrifocalTensor::TransferView3(Vector3<TRIFOCALTENSOR_TYPE> &x1,
260 {
261  HomgPoint2D p1(x1);
262  HomgPoint2D p2(x2);
263  p1.Normalize();
264  p2.Normalize();
265 
266  // compute epipolar line of x1 in view 2
267  HomgLine2D le(GetFMatrix21() * p1);
268  //cout << "le = " << le << endl;
269 
270  /* make line perpendicular and passing thru x2, as the epipolar line is
271  not good for transfer */
272  HomgLine2D l2;
273  le.GetPerpendicularLine(p2,l2);
274 
275  //cout << "l2 = " << l2 << endl;
276 
277  //cout << "l2*x2=" << l2.ScalarProduct(p2) << endl;;
278 
280  LeftContravariantContraction2(l2).TransposedMult(x1,x3);
281 
282  return HomgPoint2D(x3);
283 }
284 
285 TrifocalTensor& TrifocalTensor::operator=(const TrifocalTensor& t)
286 {
287  TrifocalTensorBase::operator=(t);
288  return *this;
289 }
Vector< double > GetNullvector(const int last_offset=0)
return one of the nullvectors.
Definition: SVD.hh:404
Matrix4x4< PMATRIX_TYPE > GetCanonicalH() const
Get the projective homography matrix so that P * H = [ I | 0 ].
Definition: PMatrix.cpp:865
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
Definition: SVD.hh:92
class for column vectors with arbitrary size
bool GetLeftNullvector(Vector< double > &nv, const int last_offset=0)
Return one of the left nullvectors.
Definition: SVD.hh:443
void OuterProduct(const Vector3< T > &v, Matrix3x3< T > &res) const
outer product, constructs a matrix.
Definition: Vector3.cpp:151
Vector< T > GetCol(const int &col) const
return a copy of column &quot;col&quot;, zero based counting
Definition: Matrix.cpp:252
void CrossProduct(const Vector3< T > &argvec, Vector3< T > &destvec) const
cross product of two vectors destvec = this x argvec
Definition: Vector3.hh:594
void Mult(const Vector3< T > &argvec, Vector3< T > &destvec) const
matrix - vector multiplicate this matrix with Vector3, storing the result in destvec calculates: dest...
Definition: Matrix3x3.hh:302
void GetPerpendicularLine(HomgPoint2D &point, HomgLine2D &perpline)
return perpendicular line throug point
Definition: HomgLine2D.hh:187
class representing a Fundamental matrix
Definition: FMatrix.hh:46
a line l = (a b c)^T is a form of the implicit straight line equation 0 = a*x + b*y + c if homogenize...
Definition: HomgLine2D.hh:48
is a &#39;fixed size&#39; quadratic matrix of dim.
Definition: Matrix.hh:54
matrix class with arbitrary size, indexing is row major.
Matrix3x3< T > Transpose() const
returns transposed matrix tested 12.06.2002
Definition: Matrix3x3.cpp:167
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrix.hh:88
bool IsIdentity(double eps=0.0) const
Checks if the matrix a an identity.
Definition: Matrix.cpp:669
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663