Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleCamPoseCalib.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  @example ExampleCamPoseCalib.cpp
27  @relates CamPoseCalib
28  @brief Example for estimating camera pose with CamPoseCalib
29  @ingroup g_examples
30  @author MIP
31 */
32 
33 #include "Geometry/CamPoseCalib.hh"
34 #include "Base/Math/Random.hh"
35 
36 using namespace BIAS;
37 using namespace std;
38 
39 int nrPoints=100;
40 int percentOutlier=0;
41 double boxSize=10, boxDepth=1, boxDistance=30; // boxSize in xy-direction
42 double sigmaNoise=0.5, outlier=5; // in pixels !
43 
44 //int main(int argc, char *argv[])
45 int main(int, char **)
46 {
47  BIAS::Random ra;
48  // create random 3D points
49  std::vector<Vector3<double> > mps;
50  Vector3<double> mp(3);
51  for (int i=0;i<nrPoints;i++) {
52  mp[0]=ra.GetUniformDistributed(-boxSize/2.0,boxSize/2.0);
53  mp[1]=ra.GetUniformDistributed(-boxSize/2.0,boxSize/2.0);
54  mp[2]=ra.GetUniformDistributed(boxDistance-boxDepth/2.0,
55  boxDistance+boxDepth/2.0);
56  mps.push_back(mp);
57  }
58  // mps[0]= Vector3<double>(1,0,18);
59  // mps[1]= Vector3<double>(-1,1,20);
60  // mps[2]= Vector3<double>(1,1,22);
61  // mps[3]= Vector3<double>(0,0,20);
62 
63  double fx=912/2.0,fy=912/2.0,cx=383/2.0,cy=287/2.0;
64  cx=343/2.0,cy=247/2.0;
66 
67  CamPoseCalib estimator;
68  // estimator.SetDebugLevel( estimator.GetDebugLevel() |
69  // D_BIAS_CAMPOSE_ESTIMATE_STEPS);
70  // estimator.SetDebugLevel( estimator.GetDebugLevel() |
71  // D_BIAS_CAMPOSE_ESTIMATE_EQSYS);
72  // estimator.SetDebugLevel( estimator.GetDebugLevel() |
73  // D_BIAS_CAMPOSE_APPLY_SOL);
74  estimator.SetDebugLevel( estimator.GetDebugLevel() |
75  D_BIAS_CAMPOSE_ESTIMATE_ITER);
76  //estimator.AddDebugLevel( D_BIAS_CAMPOSE_LM );
77  // estimator.SetDebugLevel( estimator.GetDebugLevel() |
78  // D_BIAS_CAMPOSE_EQSYS);
79  // estimator.AddDebugLevel(D_BIAS_CAMPOSE_SECD);
80  /////////////////////////////////////
81  cout<<endl<<endl<<
82  "---- estimating external parameters --------"<<endl;
83 
84  /// set the initial projection matrix
85  KMatrix K;
86  K.SetIdentity();
87  K[0][0]= fx; K[0][2]= cx;
88  K[1][0]= 0; K[1][1]= fy; K[1][2]= cy; // virtual image size of 320x240
89  RMatrix R,resR;
90  R.SetXYZ(0,0,0);
91  C.Set(0,0,0);
92  PMatrix P1;
93  P1.Compose(K,R,C);
94  estimator.SetInitialCamera(P1);
95  // estimator.SetInitialCamera(K);
96 
97  // now change it a little and project the model points
98  K[0][0]= fx ; K[0][2]= cx;
99  K[1][1]= fy; K[1][2]= cy;
100  R.SetXYZ(0, -45.0/180.0*M_PI, 0/180.0*M_PI);
101  C.Set(100,0,0);
102  PMatrix P;
103  P.Compose(K,R,C);
104 
105  // only estimatiion of the external params and the focal length
106  // estimator.SetEstimateFocal(2);
107 
108  std::vector<Vector2<double> > tps;
109  Vector2<double> y;
110  //project the model points
111  for (unsigned int i=0;i<mps.size();i++) {
112  HomgPoint2D(P*HomgPoint3D(mps[i])).GetEuclidean(y);
113  tps.push_back(y);
114  }
115 
116  // add some "noise"
117  if (sigmaNoise>1E-15)
118  for (unsigned int i=0;i<tps.size();i++) {
119  tps[i][0]+=ra.GetNormalDistributed(0,sigmaNoise);
120  tps[i][1]+=ra.GetNormalDistributed(0,sigmaNoise);
121  }
122 
123  // and a few "outlier"
124  if (percentOutlier>0.000001)
125  for (unsigned int i=0;i<tps.size()/(percentOutlier*100);) {
126  double offset=ra.GetNormalDistributed(0,outlier);
127  if (fabs(offset)>(3*sigmaNoise)) {
128  tps[i][0]+=offset;
129  i++;
130  }
131  offset=ra.GetNormalDistributed(0,outlier);
132  if (fabs(offset)>(3*sigmaNoise)) {
133  tps[i][1]+=offset;
134  i++;
135  }
136  }
137 
138  // /// test covars
139  // std::vector<BIAS::Matrix2x2<double> > covars;
140  // covars.push_back(Matrix2x2<double>( 1,0, 0,1 ));
141  // covars.push_back(Matrix2x2<double>( 1,0, 0,1 ));
142  // covars.push_back(Matrix2x2<double>( 1,0, 0,1 ));
143  // covars.push_back(Matrix2x2<double>( 1001,999, 999,1001 )); //diagonal covar
144  // covars[3]= covars[3].Invert();
145 
146  // tps[3][0]+=9; tps[3][1]+=9; // should have no effect, cause of diag covar
147 
148  for (unsigned int i=0;i<mps.size();i++) {
149  estimator.AddCorr(mps[i],tps[i]);
150  }
151 
152 
153  // estimator.SetVariances(covars);
154  estimator.Estimate(50);
155 
156  ///////// output the result
157  resR=estimator.GetRotation();
158  cout<<"estimated R:"<<resR<<endl;
160  double angle;
161  resR.GetRotationAxisAngle(axis,angle);
162  cout<<"Rotation axis:"<<axis<<" angle:"<<angle/M_PI*180.0<<endl;
163  cout<<"estimated trans:"<<estimator.GetTranslation()<<endl;
164  PMatrix Pest;
165  estimator.GetP(Pest);
166  Vector2<double> yEst;
167  HomgPoint2D(Pest*HomgPoint3D(mps[4])).GetEuclidean(yEst);
168  cout<<"avg error:"<<estimator.GetAvgError()<<endl<<
169  " y5:"<<tps[4]<<" estimatedP*mp5:"<<yEst<<endl;
170  cout<<"Real K:"<<K<<endl
171  <<"Estimated K:"<<Pest.GetK()<<endl;
172  Matrix<double> coVar;
173  estimator.GetCoVarMatrix(coVar);
174  cout<<"CoVariance of Estimation:"<<coVar<<endl;
175 
176 
177 
178  cout<<endl<<endl<<
179  "---- Reestimating with principal point and Huber weighting function ----"
180  <<endl;
181  // now all 10 parameters are estimated, starting point is the
182  // last estimated P
183  estimator.SetEstimatePrincipal(1);
184  estimator.SetWeighting(1.0,1);
185  estimator.Estimate(50);
186 
187  resR=estimator.GetRotation();
188  cout<<"estimated R:"<<resR<<endl;
189  resR.GetRotationAxisAngle(axis,angle);
190  cout<<"Rotation axis:"<<axis<<" angle:"<<angle/M_PI*180.0<<endl;
191  cout<<"estimated trans:"<<estimator.GetTranslation()<<endl;
192  estimator.GetP(Pest);
193  HomgPoint2D(Pest*HomgPoint3D(mps[4])).GetEuclidean(yEst);
194  cout<<"avg error:"<<estimator.GetAvgError()<<endl<<
195  " y5:"<<tps[4]<<" estimatedP*mp5:"<<yEst<<endl;
196  cout<<"Real K:"<<K<<endl
197  <<"Estimated K:"<<Pest.GetK()<<endl;
198  estimator.GetCoVarMatrix(coVar);
199  cout<<"CoVariance of Estimation:"<<coVar<<endl;
200 
201 
202 
203  // // for profiling
204 // for (unsigned int r=0;r<200;r++) {
205 // estimator.Reset();
206 
207 // for (unsigned int i=0;i<mps.size();i++) {
208 // estimator.AddCorr(mps[i],tps[i]);
209 // }
210 // estimator.SetWeighting(1.0,-1);
211 // estimator.Estimate(50);
212 // }
213 }
214 
void Set(const T *pv)
copy the array of vectorsize beginning at *T to this-&gt;data_
Definition: Vector3.hh:532
void SetXYZ(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order XYZ.
int GetCoVarMatrix(BIAS::Matrix< double > &coVar)
returns the covariance of the last estimate, which is (H=Hessian): H^{-1} * eps^T*eps * 1/(2n-p) The ...
BIAS::Vector3< double > GetTranslation() const
this returns the translation from the initial camera center to the new camera center ...
this classs allows estimation of the internal (except skew) and external camera parameters by an iter...
Definition: CamPoseCalib.hh:86
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
Definition: Random.hh:84
double GetAvgError()
returns the avg error of the estimation, which is the average difference of the projected points to t...
int GetDebugLevel() const
Definition: Debug.hh:332
void GetP(BIAS::PMatrix &P)
returns the estimated new projection matrix
3D rotation matrix
Definition: RMatrix.hh:49
void SetEstimatePrincipal(bool yes)
wether to estimate the principal point also, default is NO
int SetInitialCamera(const BIAS::KMatrix &K)
activates an automatic initial guess for the projection matrix, according to Christian Perwass&#39; habil...
void SetDebugLevel(const long int lv)
Definition: Debug.hh:318
BIAS::RMatrix GetRotation() const
this return the relative rotation from the initial camera orientation to the new estimated camera rot...
void SetWeighting(double k, int func=1)
optional: do robust estimation, if the error is larger than k, an outlier is assumed ...
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
int GetRotationAxisAngle(Vector3< ROTATION_MATRIX_TYPE > &axis, ROTATION_MATRIX_TYPE &angle) const
Calculates angle and rotation axis representation for this rotation matrix.
double GetNormalDistributed(const double mean, const double sigma)
on succesive calls return normal distributed random variable with mean and standard deviation sigma ...
Definition: Random.hh:71
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrix.hh:88
int AddCorr(const BIAS::Vector3< double > &x, const BIAS::Vector2< double > &y)
add a corresponding point pair
class for producing random numbers from different distributions
Definition: Random.hh:51
class BIASGeometryBase_EXPORT HomgPoint2D
void Compose(const Matrix3x3< double > &K, const Matrix3x3< double > &R, const Vector3< double > &C)
composes this from K, R and C using P = [ K R&#39; | -K R&#39; C ] with R&#39; = transpose(R) ...
Definition: PMatrix.cpp:581
class BIASGeometryBase_EXPORT HomgPoint3D
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429
int Estimate(unsigned int iterations=20)
Does the calculation with a certain number of iterations.
int GetK(KMatrix &K)
calibration matrix
Definition: PMatrix.cpp:220