Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FMatrixBase.hh
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 #ifndef _BIAS_FMatrixBase_hh_
27 #define _BIAS_FMatrixBase_hh_
28 
29 #include <bias_config.h>
30 
31 #include <math.h>
32 
33 #include <Base/Debug/Error.hh>
34 #include <Base/Debug/Debug.hh>
35 
36 #include <Base/Math/Matrix3x3.hh>
37 #include <Base/Math/Vector3.hh>
38 
39 #include "RMatrixBase.hh"
40 #include "KMatrix.hh"
41 #include "HomgPoint2D.hh"
42 #include "HomgLine2D.hh"
43 
44 
45 #define FMATRIX_TYPE double
46 namespace BIAS {
47 
48  /** @class FMatrixBase
49  @ingroup g_geometry
50  @brief describes the epipolar relationship between a point and his
51  mapping on a corresponding epipolar line.
52 
53  The 3x3 matrix F is the fundamental matrix of an image pair (b1, b2).
54  In particular, with p' = transpose(p) this results in the epipolar
55  constraint:
56  p1' F p2 = 0 for every pair (p1, p2) of corresponding image points in
57  b1 and b2 respectively.
58 
59  Only implementation very specific to FMatrixBase (and not valid for a
60  general 3x3 matrix) should be implemented here.
61  @author Jan Woetzel
62  @status untested (04/18/2002) now derived from Matrix3x3 and not
63  directly from Matrix<double>
64  status alpha (02/26/2002)
65  **/
66 
67  class BIASGeometryBase_EXPORT FMatrixBase : public Matrix3x3<FMATRIX_TYPE> {
68 
69  public:
70 
71  /** destructor
72  @status untested (04/18/2002) **/
73  ~FMatrixBase();
74 
75  /** default constructor
76  @status untested (04/18/2002)**/
77  FMatrixBase() : Matrix3x3<FMATRIX_TYPE>() { _isDecomposed=false; };
78 
79  /** constructor setting identity or zero
80  @brief author koeser **/
81  explicit FMatrixBase(const MatrixInitType& i) :
82  Matrix3x3<FMATRIX_TYPE>(i) {_isDecomposed=false; };
83 
84  // DEPRECATED due to instantiation problem JW
85  //explicit FMatrixBase(const char *s) : Matrix3x3<FMATRIX_TYPE>(s) { _isDecomposed=false; };
86 
87  /** @author Jan Woetzel
88  @status untested (04/18/2002) **/
90  : Matrix3x3<FMATRIX_TYPE>(A)
91  { _isDecomposed=false; };
92 
93  /** constructor
94  for convenience to build form a c-style aaray amtrix
95  @author Jan Woetzel (07/15/2002) **/
96  explicit FMatrixBase(const FMATRIX_TYPE *d) {
97  // get F from the c-style roww-wise data array d
98  for (int i=0; i<9;i++) {
99  (this->GetData())[i] = d[i];
100  };
101  _isDecomposed=false;
102  };
103 
104  /// see Set(Vector3<FMATRIX_TYPE>& epipole, RMatixBase& R);
105  inline FMatrixBase(const Vector3<FMATRIX_TYPE>& epipole,
106  const RMatrixBase& R)
107  : Matrix3x3<FMATRIX_TYPE>()
108  { Set(epipole, R); }
109 
110  /// see Set(Vector3<FMATRIX_TYPE>& epipole,
111  /// Vector3<FMATRIX_TYPE>& EulerAngXYZ);
112  inline FMatrixBase(const Vector3<FMATRIX_TYPE>& epipole,
113  const Vector3<FMATRIX_TYPE>& EulerAngXYZ)
114  : Matrix3x3<FMATRIX_TYPE>()
115  { Set(epipole, EulerAngXYZ); };
116 
117  /** assignment operators
118  calling corresponding operator from base class "TNT::Matrix"
119  if appropriate
120  @author Jan Woetzel
121  @status untested (04/18/2002)
122  status alpha (02/25/2002) **/
125  _isDecomposed=false;
126  return *this;
127  };
128 
129  /** set it from epipole and rotation matrix
130  in order to generate essential matrix from image 1 to image 2
131  (i.e. generating the epipolar line in image 2, gfiven a point in
132  image 1), use epipole in second image and rotation matrix from image 1
133  to image 2
134  @author woelk 07/2004 */
135  inline void Set(const Vector3<FMATRIX_TYPE>& epipole,
136  const RMatrixBase& R);
137 
138  /** see constructor from epipole and rotation matrix
139  builds rotation matrix in x, y, z order with moving axis
140  see RMatrixBase
141  @author woelk 07/2004 */
142  inline void Set(const Vector3<FMATRIX_TYPE>& epipole,
143  const Vector3<FMATRIX_TYPE>& EulerAngXYZ);
144 
145  /** set function, it is undocumented if this really works with the
146  camer center C, I doubt it, woelk 12/2004 */
147  inline void Set(RMatrixBase &R, Vector3<FMATRIX_TYPE> &C);
148 
149 
150  /** @brief computes error in epipolar geometry for the given
151  correspondence P1;P2
152 
153  this error is the sum of squared distances to epipolar lines in both
154  images, for inliers it should typically be of one or two pixels
155  (if not-normalized pixel coordinates are used)
156  @attention P1 and P2 HAVE TO BE homogenized
157  @param P1 homogenized first point of correspondence to check
158  @param P2 homogenized second point of correspondence to check
159  @status tested, optimized
160  @author koeser 09/2003 */
161  inline double GetEpipolarErrorHomogenized(const BIAS::HomgPoint2D& P1,
162  const BIAS::HomgPoint2D& P2) const;
163 
164  /** @brief computes error in epipolar geometry for the given
165  correspondence P1,P2 using above function after homogenizing the points
166  @author koeser 09/2003 */
168  BIAS::HomgPoint2D& P2)
169  { P1.Homogenize(); P2.Homogenize();
170  return GetEpipolarErrorHomogenized(P1,P2);}
171 
172  /** returns the cosine of the angle bewteen epipolar line
173  and match line */
174  inline double GetCosAngleErrorHomogenized(const BIAS::HomgPoint2D& p1,
175  const BIAS::HomgPoint2D& p2);
176 
177  /** Returns epipolar line in image 1 for point in image 2. */
178  HomgLine2D GetEpipolarLineImage1(const HomgPoint2D& point) const ;
179 
180  /** Returns epipolar line in image 1 for point in image 2. */
181  void GetEpipolarLineImage1(const HomgPoint2D& point,
182  HomgLine2D& homline) const;
183 
184  /** Returns epipolar line in image 2 for point in image 1. */
185  HomgLine2D GetEpipolarLineImage2(const HomgPoint2D& point) const;
186 
187  /** Returns epipolar line in image 2 for point in image 1. */
188  void GetEpipolarLineImage2(const HomgPoint2D& point,
189  HomgLine2D& homline) const;
190 
191  /** constructs the FMatrix from image 1 to image 2 as K1 [e]_x R K2
192  @author woelk 08/2004 */
193  void Compose(const KMatrix& K1, const RMatrixBase& R1,
194  const Vector3<double>& C1, const KMatrix& K2,
195  const RMatrixBase& R2, const Vector3<double>& C2);
196 
197  /** constructs the FMatrix from image 1 to image 2 as
198  [e]_x R, assumes K1=K2=Identity()
199  @author woelk 08/2004 */
200  void Compose(const RMatrixBase& R1, const Vector3<double>& C1,
201  const RMatrixBase& R2, const Vector3<double>& C2);
202  protected:
203  // cache for e and r
207 
208  }; // class FMatrixBase
209 
210 
211  ///////////////////////////////////////////////////////////////////////////
212  /// implementation
213  ///////////////////////////////////////////////////////////////////////////
214 
216  const RMatrixBase& R)
217  {
219  HomgPoint2D he=epipole; he.Homogenize();
221  e.Mult(R, *this);
222  _isDecomposed=true;
223  _epipole=he;
224  _R=R;
225  }
226 
228  const Vector3<FMATRIX_TYPE>& EulerAngXYZ)
229  {
230  RMatrixBase R;
231  R.SetXYZ(EulerAngXYZ[0], EulerAngXYZ[1], EulerAngXYZ[2]);
232  Set(epipole, R);
233  }
234 
236  // We have two matrices, P0 = [id | 0] and P1 = [R^T | -R^TC]
237  // Now compute essential matrix.
238  // C0 = [0 0 0 1] mapped by P1 yields (-R^TC), the epipole in image 1
239  // This must be in the left null space of E.
240  // Vice versa C is directly the epipole in image 0 and must be
241  // in the right null space of E
242 
243  // this sets the left null space to what we want:
244  (*this).SetAsCrossProductMatrix(R.Transpose()*C);
245  // Unfortunately, the right null space of (*this) is now also R^T*C,
246  // right-multiplying by R^T corrects for that problem:
247  (*this) = (*this)*R.Transpose();
248  }
249 
251  const BIAS::HomgPoint2D& P2) const
252  {
253  /*
254  // old version, quite slow but readable ;-)
255 
256  // use F Matrix to get epipolar line in other image
257  HomgLine2D EpiLineInImage;
258  F.GetEpipolarLineImage1(P2,EpiLineInImage);
259 
260  // compute (perpendicular) distance of point to line and square it
261  double dError1 = EpiLineInImage.DistanceSquared(P1);
262 
263  // do the same for the inverse direction and add error value
264  F.GetEpipolarLineImage2(P1,EpiLineInImage);
265 
266  double dErrorAll = (dError1 + EpiLineInImage.DistanceSquared(P2));
267  return dErrorAll;
268 
269  */
270  HomgLine2D EL;
271 
272  // computation of epipolar line relying on homogenized point
273  const register double *matP = GetData();
274  EL[0] = P2[0] * matP[0]
275  + P2[1] * matP[3]
276  + matP[6];
277  EL[1] = P2[0] * matP[1]
278  + P2[1] * matP[4]
279  + matP[7];
280  EL[2] = P2[0] * matP[2]
281  + P2[1] * matP[5]
282  + matP[8];
283 
284  double dist = EL[0] * P1[0] + EL[1] * P1[1] + EL[2];
285  // dist is now = x'Fx (zero for perfect correspondence)
286 
287  double dError = dist = dist * dist;
288  dError /= (EL[0]*EL[0]+EL[1]*EL[1]);
289  // dError contains now the perpendicular distance to epiline in image1
290 
291  // do the same for the inverse direction and add error value
292  // EL = F * P1:
293  EL[0] = matP[0]*P1[0]+ matP[1]*P1[1] + matP[2];
294  EL[1] = matP[3]*P1[0]+ matP[4]*P1[1] + matP[5];
295  // EL[2] is not needed
296 
297  return (dError + (dist / (EL[0]*EL[0]+EL[1]*EL[1])));
298 
299  }
300 
301  /// @todo optimze
303  const BIAS::HomgPoint2D& p2)
304  {
305  BIASASSERT(_isDecomposed);
306  double result;
307  HomgLine2D l1, l2;
308  HomgPoint2D rcp2;
309  // l1 is the line between the epipole an p1
310  l1.Set(_epipole, p1);
311  l1.Homogenize();
312  // now apply 'homography' to p2
313  _R.Mult(p2, rcp2);
314  // l2 is the line between p1 and R*p2
315  l2.Set(p1, rcp2);
316  l2.Homogenize();
317  // now calculate the angle between these two lines
318  result=l1[0]*l2[0]+l1[1]*l2[1];
319  // crop inaccurate results
320  if (result>=1.0) { result=1.0; }
321  if (result<=-1.0) { result=-1.0; }
322  BIASASSERT(result>=-1.0 && result <=1.0);
323  return 1.0-result;
324  }
325 
326 } // namespace
327 #endif // FMatrixBase
328 
MatrixInitType
can be passed to matrix constructors to init the matrix with the most often used values ...
Definition: Matrix.hh:59
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
void SetXYZ(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order XYZ.
HomgPoint2D _epipole
Definition: FMatrixBase.hh:205
FMatrixBase(const Vector3< FMATRIX_TYPE > &epipole, const RMatrixBase &R)
see Set(Vector3&lt;FMATRIX_TYPE&gt;&amp; epipole, RMatixBase&amp; R);
Definition: FMatrixBase.hh:105
double GetCosAngleErrorHomogenized(const BIAS::HomgPoint2D &p1, const BIAS::HomgPoint2D &p2)
returns the cosine of the angle bewteen epipolar line and match line
Definition: FMatrixBase.hh:302
FMatrixBase(const Vector3< FMATRIX_TYPE > &epipole, const Vector3< FMATRIX_TYPE > &EulerAngXYZ)
see Set(Vector3&lt;FMATRIX_TYPE&gt;&amp; epipole, Vector3&lt;FMATRIX_TYPE&gt;&amp; EulerAngXYZ);
Definition: FMatrixBase.hh:112
double GetEpipolarError(BIAS::HomgPoint2D &P1, BIAS::HomgPoint2D &P2)
computes error in epipolar geometry for the given correspondence P1,P2 using above function after hom...
Definition: FMatrixBase.hh:167
FMatrixBase(const MatrixInitType &i)
constructor setting identity or zero
Definition: FMatrixBase.hh:81
HomgPoint2D & Homogenize()
homogenize class data member elements to W==1 by divison by W
Definition: HomgPoint2D.hh:215
void Set(const Vector3< FMATRIX_TYPE > &epipole, const RMatrixBase &R)
set it from epipole and rotation matrix in order to generate essential matrix from image 1 to image 2...
Definition: FMatrixBase.hh:215
FMatrixBase(const Matrix3x3< FMATRIX_TYPE > &A)
Definition: FMatrixBase.hh:89
describes the epipolar relationship between a point and his mapping on a corresponding epipolar line...
Definition: FMatrixBase.hh:67
void Set(const HomgPoint2D &p1, const HomgPoint2D &p2)
constructing a line through two points
Definition: HomgLine2D.hh:131
double GetEpipolarErrorHomogenized(const BIAS::HomgPoint2D &P1, const BIAS::HomgPoint2D &P2) const
computes error in epipolar geometry for the given correspondence P1;P2
Definition: FMatrixBase.hh:250
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
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
void Homogenize()
aequivalent to homogenize for points the gradient triangle is normed to hypothenuse length of 1 ...
Definition: HomgLine2D.hh:149
is a &#39;fixed size&#39; quadratic matrix of dim.
Definition: Matrix.hh:54
class Vector3 contains a Vector of fixed dim.
Definition: Matrix.hh:53
Matrix3x3< T > Transpose() const
returns transposed matrix tested 12.06.2002
Definition: Matrix3x3.cpp:167
Matrix3x3< T > & operator=(const Matrix3x3< T > &mat)
assignment operator
Definition: Matrix3x3.cpp:704
RMatrixBase _R
Definition: FMatrixBase.hh:206
FMatrixBase(const FMATRIX_TYPE *d)
constructor for convenience to build form a c-style aaray amtrix
Definition: FMatrixBase.hh:96
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
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
Implements a 3D rotation matrix.
Definition: RMatrixBase.hh:44
FMatrixBase()
default constructor untested (04/18/2002)
Definition: FMatrixBase.hh:77
void SetAsCrossProductMatrix(const Vector3< T > &vec)
Sets matrix from vector as cross product matrix of this vector.
Definition: Matrix3x3.cpp:275