Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Parametrization.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 "Parametrization.hh"
27 #include <Base/Common/BIASpragma.hh>
28 #include <Base/Geometry/Quaternion.hh>
29 
30 #include <vector>
31 
32 using namespace std;
33 using namespace BIAS;
34 
35 
36 Parametrization::Parametrization() {}
37 Parametrization::~Parametrization() {}
38 
39 bool Parametrization::FMatrixToParams( const FMatrix &Mat,
40  vector<double> &Params )
41 {
42  if ( Mat.IsZero() )
43  {
44  BIASERR("A parametrization of a null matrix doesn't make sense!");
45  return false;
46  }
47 
48  F_ = Mat; // set class member
49  Params.clear();
50 
51  double scale = GetBiggestAbsEntry();
52  Fscale_ = 1/scale;
53 
54  Mat.Scale(Fscale_, F_);
55 
56  double a,b,c;
57 
58  HomgPoint2D FEpipole1,FEpipole2;
59  F_.GetEpipoles(FEpipole1,FEpipole2);
60  FEpipole1.Homogenize();
61  FEpipole2.Homogenize();
62 
63  if ( Frow_ == 0 && Fcol_ == 0 )
64  {
65  a=F_[0][1];
66  b=F_[1][0];
67  c=F_[1][1];
68  }
69  else if ( Frow_ == 1 && Fcol_ == 0 )
70  {
71  a=F_[0][0];
72  b=F_[0][1];
73  c=F_[1][1];
74  }
75  else if ( Frow_ == 0 && Fcol_ == 1 )
76  {
77  a=F_[0][0];
78  b=F_[1][0];
79  c=F_[1][1];
80  }
81  else if ( Frow_ == 1 && Fcol_ == 1 )
82  {
83  a=F_[0][0];
84  b=F_[0][1];
85  c=F_[1][0];
86  }
87 
88  Params.push_back(a);
89  Params.push_back(b);
90  Params.push_back(c);
91 
92  Params.push_back(-FEpipole1[0]);
93  Params.push_back(-FEpipole1[1]);
94  Params.push_back(-FEpipole2[0]);
95  Params.push_back(-FEpipole2[1]);
96 
97  return true;
98 }
99 
100 
101 bool Parametrization::ParamsToFMatrix( FMatrix &Mat,
102  const vector<double> &Params )
103 {
104  if ( Params.size() != 7 )
105  {
106  BIASERR("There must be 7 parameters to compose the F matrix!");
107  return false;
108  }
109  FParams_ = Params; // set class member
110 
111  double a=0.0,b=0.0,c=0.0,d=0.0;
112  double e10,e11,e20,e21;
113 
114  if ( Frow_ == 0 && Fcol_ == 0 )
115  {
116  a = 1;
117  b = Params[0];
118  c = Params[1];
119  d = Params[2];
120  }
121  else if ( Frow_ == 1 && Fcol_ == 0 )
122  {
123  a = Params[0];
124  b = Params[1];
125  c = 1;
126  d = Params[2];
127  }
128  else if ( Frow_ == 0 && Fcol_ == 1 )
129  {
130  a = Params[0];
131  b = 1;
132  c = Params[1];
133  d = Params[2];
134  }
135  else if ( Frow_ == 1 && Fcol_ == 1 )
136  {
137  a = Params[0];
138  b = Params[1];
139  c = Params[2];
140  d = 1;
141  }
142 
143  e10 = Params[3];
144  e11 = Params[4];
145  e20 = Params[5];
146  e21 = Params[6];
147 
148  Mat[0][0] = a;
149  Mat[0][1] = b;
150  Mat[0][2] = e10 * a + e11 * b;
151 
152  Mat[1][0] = c;
153  Mat[1][1] = d;
154  Mat[1][2] = e10 * c + e11 * d;
155 
156  Mat[2][0] = e20 * a + e21 * c;
157  Mat[2][1] = e20 * b + e21 * d;
158  Mat[2][2] = e20 * e10 * a + e20 * e11 * b + e21 * e10 * c + e21 * e11 * d;
159 
160  return true;
161 }
162 
163 
164 bool Parametrization::HMatrixToParams( const HMatrix &Mat,
165  vector<double> &Params )
166 {
167  if ( Mat.IsZero() )
168  {
169  BIASERR("A parametrization of a null matrix doesn't make sense!");
170  return false;
171  }
172 
173  H_ = Mat; // set class member
174  Params.clear();
175 
176  // make sure that 3,3 element is positive
177  if ( H_[2][2] < 0 )
178  H_.Scale( -1, H_);
179 
180  // compute the Frobenius norm
181  double Hnorm =
182  H_[0][0] * H_[0][0] + H_[0][1] * H_[0][1] + H_[0][2] * H_[0][2] +
183  H_[1][0] * H_[1][0] + H_[1][1] * H_[1][1] + H_[1][2] * H_[1][2] +
184  H_[2][0] * H_[2][0] + H_[2][1] * H_[2][1] + H_[2][2] * H_[2][2];
185  Hnorm = sqrt(Hnorm);
186 
187  Hscale_ = Hnorm;
188 
189  Params.push_back(H_[0][0]/Hnorm);
190  Params.push_back(H_[0][1]/Hnorm);
191  Params.push_back(H_[0][2]/Hnorm);
192  Params.push_back(H_[1][0]/Hnorm);
193  Params.push_back(H_[1][1]/Hnorm);
194  Params.push_back(H_[1][2]/Hnorm);
195  Params.push_back(H_[2][0]/Hnorm);
196  Params.push_back(H_[2][1]/Hnorm);
197 
198  return true;
199 }
200 
201 
202 bool Parametrization::ParamsToHMatrix( HMatrix &Mat,
203  const vector<double> &Params )
204 {
205  if ( Params.size() != 8 )
206  {
207  BIASERR("There must be 8 parameters to compose the H matrix!");
208  return false;
209  }
210  HParams_ = Params; // set class member
211 
212  Mat[0][0]=Params[0];
213  Mat[0][1]=Params[1];
214  Mat[0][2]=Params[2];
215  Mat[1][0]=Params[3];
216  Mat[1][1]=Params[4];
217  Mat[1][2]=Params[5];
218  Mat[2][0]=Params[6];
219  Mat[2][1]=Params[7];
220 
221  /* compute the 3,3 element, using the property from parametrization
222  where ||H|| = 1 (||.|| = Frobenius norm) */
223  Mat[2][2]=sqrt(1 -
224  (Params[0] * Params[0] +
225  Params[1] * Params[1] +
226  Params[2] * Params[2] +
227  Params[3] * Params[3] +
228  Params[4] * Params[4] +
229  Params[5] * Params[5] +
230  Params[6] * Params[6] +
231  Params[7] * Params[7] ));
232  return true;
233 }
234 
235 
236 double Parametrization::GetBiggestAbsEntry()
237 {
238  double max=0.0;
239  for (int r=0;r<2;r++)
240  for (int c=0;c<2;c++)
241  if ( abs(F_[r][c])>abs(max) )
242  {
243  max = F_[r][c];
244  Frow_ = r;
245  Fcol_ = c;
246  }
247  return max;
248 }
249 
250 
251 
252 bool Parametrization::EMatrixToParams( BIAS::EMatrix &Mat,
253  Vector<double> &Params,
254  std::vector<BIAS::HomgPoint2D> &inlier1,
255  std::vector<BIAS::HomgPoint2D> &inlier2,
256  bool UseQuaternion)
257 {
258  if (Params.size() != ((UseQuaternion)?6:NUM_PARAM_ESSENTIAL)){
259  BIASERR (" parameter vector must have length "
260  <<((UseQuaternion)?(6):(NUM_PARAM_ESSENTIAL))
261  << " instead of " << Params.size());
262  BIASABORT;
263  }
264  RMatrix R;
265  Vector3<double> C;
266  Mat.GetRotationTranslation(R,C,inlier1,inlier2);
267  // now parameterization of translation
268  Vector3<double> CSpherical(C.CoordEuclideanToSphere());
269 
270  // parameterize translation
271  Params[0] = CSpherical[1];
272  Params[1] = CSpherical[2];
273 
274  if (UseQuaternion){
276  if (R.GetQuaternion(q)!=0){
277  BIASERR("unable to extract quaternion from R");
278  BIASABORT;
279  }
280  Params[2] = q[0]; Params[3]=q[1]; Params[4]=q[2]; Params[5]=q[3];
281  } else {
282  // now parameterization of rotation
283  double angle;
284  Vector3<double> rax;
285  R.GetRotationAxisAngle(rax,angle);
286  if (fabs(angle)<MINIMUM_ROTATION){
287  rax.Set(1.0, 0.0, 0.0);
288  angle = 0;
289  }
290  rax *= angle/rax.NormL2();
291 
292 
293  // parameterize rotation
294  Params[2] = rax[0]; Params[3]=rax[1]; Params[4]=rax[2];
295  }
296  //cout << "params: "<<Params<<endl;
297  return true;
298 }
299 
300 
301 bool Parametrization::ParamsToEMatrix( BIAS::EMatrix &Mat,
302  const Vector<double> &Params,
303  bool UseQuaternion){
304  double c1 = 1.0;//-Params[0]*Params[0]-Params[1]*Params[1];
305  // c3 = (c3 >= 0.0) ? sqrt(c3) : sqrt(-1.0*c3);
306  Vector3<double> C(c1, Params[0],Params[1]);
307  C = C.CoordSphereToEuclidean();
308  RMatrix R;
309  if (UseQuaternion){
310  if (Params.size() != 6){
311  BIASERR("invalid length of parameter vector "<<Params.Size());
312  BIASABORT;
313  }
314  Quaternion<double> q(Params[2],Params[3],Params[4], Params[5]);
315  R.SetFromQuaternion(q);
316  } else {
317  if (Params.size() != NUM_PARAM_ESSENTIAL){
318  BIASERR (" parameter vector has length "<<Params.size()<<" instead of "
319  << NUM_PARAM_ESSENTIAL);
320  BIASABORT;
321  }
322  Vector3<double> rax(Params[2],Params[3],Params[4]);
323  double angle = rax.NormL2();
324 
325  if (fabs(angle)<MINIMUM_ROTATION){
326  rax[0] = 1;
327  rax[1] = 0;
328  rax[2] = 0;
329  angle = 0;
330  } else {
331  angle = rax.NormL2();
332  rax /= rax.NormL2();
333  }
334 
335  //RMatrix R(rax,angle);
336  R.Set(rax, angle);
337  }
338 
339  Mat.Set(R,C);
340  //cout << "ParamsToEMatrix: Params="<<Params<<" R=" << R << ", C = " << C <<endl;
341  Mat /= Mat.NormFrobenius();
342 
343  return true;
344 
345 }
void Set(const T *pv)
copy the array of vectorsize beginning at *T to this-&gt;data_
Definition: Vector3.hh:532
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
BIAS::Vector3< T > CoordEuclideanToSphere() const
coordinate transform.
Definition: Vector3.cpp:113
int GetRotationTranslation(RMatrix &R, Vector3< double > &C, const std::vector< HomgPoint2D > &inlier1, const std::vector< HomgPoint2D > &inlier2)
find R and C(direction), such that maximum number of 3d points triangulated from correspondences inli...
Definition: EMatrix.cpp:64
a 3x3 Matrix describing projective transformations between planes
Definition: HMatrix.hh:39
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
int SetFromQuaternion(const Quaternion< ROTATION_MATRIX_TYPE > &q)
Set rotation matrix from a quaternion.
unsigned int Size() const
length of the vector
Definition: Vector.hh:143
class representing an Essential matrix
Definition: EMatrix.hh:52
int GetQuaternion(Quaternion< ROTATION_MATRIX_TYPE > &quat) const
Calculates quaternion representation for this rotation matrix.
3D rotation matrix
Definition: RMatrix.hh:49
void Set(const Vector3< ROTATION_MATRIX_TYPE > &w, const ROTATION_MATRIX_TYPE phi)
Set from rotation axis w and angle phi (in rad)
double NormFrobenius() const
Definition: Matrix3x3.hh:446
class representing a Fundamental matrix
Definition: FMatrix.hh:46
bool IsZero(const T eps=std::numeric_limits< T >::epsilon()) const
Definition: Matrix3x3.cpp:508
BIAS::Vector3< T > CoordSphereToEuclidean() const
coordinate transfrom.
Definition: Vector3.cpp:78
void Scale(const T &scalar, Matrix3x3< T > &destmat) const
scalar-matrix multiplication
Definition: Matrix3x3.hh:374
int GetRotationAxisAngle(Vector3< ROTATION_MATRIX_TYPE > &axis, ROTATION_MATRIX_TYPE &angle) const
Calculates angle and rotation axis representation for this rotation matrix.
Subscript size() const
Definition: vec.h:262
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633