Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FMatrix.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #include "FMatrix.hh"
27 #include "Base/Geometry/KMatrix.hh"
28 #include <MathAlgo/SVD.hh>
29 #include <Base/Math/Vector3.hh>
30 
31 using namespace BIAS;
32 using namespace std;
33 
34 
35 #define F_SVD_THRESH 0.1
36 
37 
39  BIAS::PMatrix &P2) {
40 
41  // invert P1 to get backprojected rays of coordinates
43  P1.GetPseudoInverse(P1Inv);
44 
45  // get center1, which is the null vector of P1
46  HomgPoint3D C1;
47  P1.GetNullVector(C1);
48 
49  // get epipol in image 2
50  BIAS::HomgPoint2D e(P2 * C1);
51 
52  // get cross product matrix of epipol
54 
55  // compose all
56  (*this) = Matrix3x3<double>(e_x * P2 * P1Inv);
57 
58  double maxentry = 0;
59  for (unsigned int i=0; i<3; i++) {
60  for (unsigned int j=0; j<3; j++) {
61  if (fabs((*this)[i][j])>maxentry) maxentry = fabs((*this)[i][j]);
62  }
63  }
64  if (maxentry>0.0) (*this) *= 1.0 / maxentry;
65 }
66 
67 
68 
69 int FMatrix::GetEpipoles(HomgPoint2D &Epipole1, HomgPoint2D &Epipole2) const
70 {
71  SVD svdF ( (Matrix<FMATRIX_TYPE>)(*this), F_SVD_THRESH );
72 #ifdef BIAS_DEBUG
73  if ((GetDebugLevel() & D_FMATRIX_GETEPIPOLES)!=0){
74  BIAS::FMatrix FCopy = (*this);
75  cerr << "F: " << FCopy;
76  Matrix<double> S(3,3);
77  S.SetIdentity();
78  for (int i=0; i<3; i++)
79  S[i][i]=svdF.GetS()[i];
80 
81  cerr << "U:" << svdF.GetU() << "\tS: " << svdF.GetS() << "\tV: "
82  << svdF.GetVT() << "\n U S Vt:"
83  << svdF.GetU() * S * svdF.GetVT() << "\nF:" << FCopy << endl;
84  cerr << "NullspaceDim(): " << svdF.NullspaceDim() << endl;
85  }
86 #endif
87  Vector<double> Ep1, Ep2;
88  if (!svdF.GetNullvector(Ep1)) {
89  Epipole1.Set(0,0,0);
90  return -1;
91  }
92  Epipole1 = Ep1;
93  Epipole1.Normalize();
94  if (!svdF.GetLeftNullvector(Ep2)) {
95  Epipole2.Set(0,0,0);
96  return -2;
97  }
98  Epipole2 = Ep2;
99  Epipole2.Normalize();
100  return 0;
101 }
102 
103 /*-----------------------------------------------------------------
104  decompose a f matrix to (skew)(rank3).
105  ----------------------------------------*/
107  BIAS::Matrix3x3<double> &rank3_matrix)
108 
109 {
110  HomgPoint2D Epipole1, Epipole2;
111  GetEpipoles(Epipole1, Epipole2);
112 
113  //ma2_static_trivec_to_crossmatrix (&epipole2_trivec, cross_matrix);
114  skew_matrix.SetAsCrossProductMatrix(Epipole2);
115 
116  //ma2_static_multiply_3x3_3x3 (cross_matrix, f_matrix, rank3_matrix);
117  rank3_matrix=skew_matrix*(*this);
118 }
119 
121 {
123  return *this;
124 }
125 
126 
128 {
129  /* result is true by default.
130  The wrong cases should be intercepted by if-clauses.
131  The first one that matches permanently sets the result to false.
132  mdunda 08 2003 */
133  bool result=true;
134 
135  SVD svdF ( Matrix<FMATRIX_TYPE>(*this) );
136 
137  // The nullspace dimension should be 1. In that case the rank is 2.
138  int dimN=svdF.NullspaceDim();
139  if ( dimN != 1 )
140  {
141  BIASERR("F-Matrix invalid due to wrong nullspace dimension."
142  << "dim(N)=" << dimN);
143  result=false;
144  }
145  return result;
146 }
147 
148 double FMatrix::GetResidualError(const std::vector<BIAS::HomgPoint2D> &p1,
149  const std::vector<BIAS::HomgPoint2D> &p2){
150 
151 
152  int numPoints = std::min(p1.size(), p2.size());
153  double res = 0;
154  HomgPoint2D temp2D_1, temp2D_2;
155 // double temp;
156  for(int i =0; i < numPoints; i++){
157  temp2D_1 = p1[i];
158  temp2D_2 = p2[i];
159 // temp = GetEpipolarError(temp2D_1, temp2D_2);
160  res += GetEpipolarError(temp2D_1, temp2D_2);
161 
162  }
163  res = res / numPoints;
164  return res;
165 }
166 
167 
Vector< double > GetNullvector(const int last_offset=0)
return one of the nullvectors.
Definition: SVD.hh:404
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
bool IsValid()
Returns true if all properties of the F-Matrix are correct, at the moment only rank 2 is checked...
Definition: FMatrix.cpp:127
const int NullspaceDim() const
return the dim of the nullspace.
Definition: SVD.hh:209
bool GetLeftNullvector(Vector< double > &nv, const int last_offset=0)
Return one of the left nullvectors.
Definition: SVD.hh:443
Matrix< T > GetSkewSymmetricMatrix() const
constructs a skew symmetric 3x3 matrix from (*this), which can be used instead of the cross product ...
Definition: Vector3.cpp:257
void DecomposetoSR(BIAS::Matrix3x3< double > &skew_matrix, BIAS::Matrix3x3< double > &rank3_matrix)
Decomposes f matrix to product (skew)(rank3)
Definition: FMatrix.cpp:106
double GetResidualError(const std::vector< BIAS::HomgPoint2D > &p1, const std::vector< BIAS::HomgPoint2D > &p2)
returns residual error as in Zisserman p.
Definition: FMatrix.cpp:148
const Matrix< double > & GetVT() const
return VT (=transposed(V))
Definition: SVD.hh:177
class representing a Fundamental matrix
Definition: FMatrix.hh:46
int GetNullVector(HomgPoint3D &C)
this is another way of getting C, especially interesting for non-metric cameras
Definition: PMatrix.cpp:137
const Vector< double > & GetS() const
return S which is a vector of the singular values of A in descending order.
Definition: SVD.hh:167
void ComputeFromPMatrices(BIAS::PMatrix &P1, BIAS::PMatrix &P2)
computes an F matrix from two cameras (defined by arbitrary P matrices, not only metric ones) ...
Definition: FMatrix.cpp:38
void SetIdentity()
Converts matrix to identity matrix.
Definition: Matrix.cpp:383
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
const Matrix< double > & GetU() const
return U U is a m x m orthogonal matrix
Definition: SVD.hh:187
FMatrixBase & operator=(const Matrix3x3< FMATRIX_TYPE > &mat)
assignment operators calling corresponding operator from base class &quot;TNT::Matrix&quot; if appropriate ...
Definition: FMatrixBase.hh:123
int GetEpipoles(HomgPoint2D &Epipole1, HomgPoint2D &Epipole2) const
Computes the epipoles from this F Matrix.
Definition: FMatrix.cpp:69
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrix.hh:88
FMatrix & operator=(const FMatrix &f)
Definition: FMatrix.cpp:120
int GetPseudoInverse(BIAS::Matrix< double > &Pinv)
returns 4x3 pseudo inverse
Definition: PMatrix.cpp:113
void SetAsCrossProductMatrix(const Vector3< T > &vec)
Sets matrix from vector as cross product matrix of this vector.
Definition: Matrix3x3.cpp:275
void Set(const HOMGPOINT2D_TYPE &x, const HOMGPOINT2D_TYPE &y)
set elementwise with given 2 euclidean scalar values.
Definition: HomgPoint2D.hh:174
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663