Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
CamPoseCalib.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 #ifndef __BIAS_CamPoseCalib_HH
26 #define __BIAS_CamPoseCalib_HH
27 
28 #include <bias_config.h>
29 #include <Base/Common/W32Compat.hh>
30 #include <math.h>
31 
32 #include <vector>
33 #include <iostream>
34 
35 //#include <Base/Common/BIASpragmaStart.hh>
36 
37 #include <Base/Debug/Debug.hh>
38 #include <Base/Math/Vector3.hh>
39 #include <Base/Math/Matrix.hh>
40 #include <Base/Math/Matrix2x2.hh>
41 #include <Geometry/RMatrix.hh>
42 #include <Geometry/PMatrix.hh>
43 
44 namespace BIAS {
45 
46 #define D_BIAS_CAMPOSE_ESTIMATE_STEPS 1<<0
47 #define D_BIAS_CAMPOSE_ESTIMATE_EQSYS 1<<1
48 #define D_BIAS_CAMPOSE_INIT 1<<2
49 #define D_BIAS_CAMPOSE_APPLY_SOL 1<<3
50 #define D_BIAS_CAMPOSE_ESTIMATE_ITER 1<<4
51 #define D_BIAS_CAMPOSE_EQSYS 1<<5
52 #define D_BIAS_CAMPOSE_LM 1<<6
53 #define D_BIAS_CAMPOSE_INITGUESS 1<<7
54 #define D_BIAS_CAMPOSE_SECD 1<<8
55 
56  /** @class CamPoseCalib
57  @ingroup g_geometry
58  @brief this classs allows estimation of the
59  internal (except skew) and external camera parameters by an
60  iterative non-linear algorithm from given 2D-3D correspondences
61 
62  A linearisation of the rotation is used therefore more than one
63  iteration is necessary. Iteration
64  stops if the change drops below minChange
65  or if a maximum of iterations is reached, while
66  the default iterations of Estimate() are more than enough usually.<br>
67  Minimum number of correspondences are 4, while the model
68  points may even lie on one plane.
69  It may also work with only 3 correspondences, but not guaranteed!
70 
71  usage:
72  - Set the initial camera either as complete PMatrix or just KMatrix
73  - optional: Set parameters like additional estimation of f, principal
74  - Add correspondences
75  - optional: add 2D coVariances of the correspondences
76 
77  - Call Estimate()
78 
79  - Get the new estimated projection matrix with GetP() or
80  get the resulting transformation by GetRotation() and GetTranslation()
81 
82  see also example ExampleCamPoseCalib.cc
83  @author Daniel Grest, Dec 2004
84  */
85 
86  class BIASGeometry_EXPORT CamPoseCalib : public BIAS::Debug
87  {
88  public:
89  CamPoseCalib();
91 
92  /** clears the correspondences, such that u can do a new estimate,
93  */
94  void Reset();
95 
96  /** add a corresponding point pair
97  */
98  int AddCorr(const BIAS::Vector3<double> &x,
99  const BIAS::Vector2<double> &y);
100 
101  /** add a corresponding 3D-point 2D-line pair
102  */
103  int AddCorr(const BIAS::Vector3<double> &x,
104  const BIAS::Vector2<double> &pointOnLine,
105  const BIAS::Vector2<double> &normalOfLine);
106 
107  /** activates an automatic initial guess for the projection matrix,
108  according to Christian Perwass' habil.
109  */
110  int SetInitialCamera(const BIAS::KMatrix &K);
111 
112  /** activates an automatic initial guess for the projection matrix,
113  according to Christian Perwass' habil.
114  */
115  int SetInitialCamera(double fx, double fy, double cx, double cy);
116 
117  /** Set the initial cam yourself if you have a good guess.
118  */
119  int SetInitialCamera(const BIAS::PMatrix &P);
120  /** Set the initial cam yourself if you have a good guess.
121  */
122  int SetInitialCamera(double fx, double fy, double cx, double cy,
123  const BIAS::RMatrix &R,
124  const BIAS::Vector3<double> &C);
125 
126  /** wether to do Levenberg-Maquardt estimation.
127  This guarantees an error decrease in each iteration,
128  but takes more time, default is on
129  */
130  inline void SetLM(bool on){ doLM_=on; }
131 
132  /** wether to estimate the focal length f also, default is NO
133  @param val 0 NO, 1 YES, 2 BOTH
134  */
135  inline void SetEstimateFocal(unsigned char val) { estimateF_=val; }
136 
137  /** wether to estimate the principal point also, default is NO
138  */
139  inline void SetEstimatePrincipal(bool yes) { estimatePrincipal_=yes; }
140 
141  /* what kind of extrinsics translation to estimate, default is all
142  */
143  inline void SetEstimateTranslation(const bool estimateTransX,
144  const bool estimateTransY,
145  const bool estimateTransZ) {
146  estimateTransX_=estimateTransX; estimateTransY_=estimateTransY;
147  estimateTransZ_=estimateTransZ;
148  }
149 
150  /** if the estimated translation in one iteration step is smaller
151  than this value, iteration stops, default is 1E-9
152  */
153  inline void SetChangeEpsilon(double transEpsilon, double rotEpsilon) {
154  transChangeEpsilon_ = transEpsilon;
155  rotChangeEpsilon_ = rotEpsilon;
156  }
157 
158  /** optional: set weights for each correspondence.<br>
159  */
160  inline void SetWeights(const std::vector<double> &weights)
161  { weights_=weights; }
162 
163  inline void SetWeightsLine(const std::vector<double> &weights)
164  { weightsLine_=weights; }
165 
166  /** optional: do robust estimation, if the error is larger than
167  k, an outlier is assumed <br>
168  @param func: choose the M-Estimator(google for it) function <br>
169  0 is Fair- function, 1 is Huber function and 2 is Tukey function
170  */
171  inline void SetWeighting(double k, int func=1)
172  { outlierError_=k; robustFunc_=func; }
173 
174 
175  /** If uncertainties for the 2D points is available set them here.
176  Expects the already inverted CoVariances, one for each 2D point.
177  */
178  inline void
179  SetVariances(const std::vector<BIAS::Matrix2x2<double> > &variances)
180  { variances_= variances; }
181 
182  /** Does the calculation with a certain number of iterations.
183  Less iterations may speed up the processing, but may result in a more
184  inaccurate estimation. <br>
185  If LM is active(default),
186  in each iteration there may be the same amount
187  of LM iterations, such that the total number of
188  function evaluation is up to iterations^2
189  @return 0=ok(epsilon reached), <0:error, >0: maxiter reached,
190  -5: all image points are on a line
191  */
192  int Estimate(unsigned int iterations=20);
193 
194  /** returns the estimated new projection matrix
195  */
196  void GetP(BIAS::PMatrix &P);
197 
198  /** this return the relative rotation from the initial camera orientation
199  to the new estimated camera rotation
200  */
201  inline BIAS::RMatrix GetRotation() const
202  { return resultR_.Transpose(); }
203 
204  /** this returns the translation from the initial camera center
205  to the new camera center
206  */
208  { return camR_* resultR_.Transpose() *
209  ((-1.0/scaleNumStabiltity_)*resultTrans_); }
210 
211  /** returns the covariance of the last estimate, which is
212  (H=Hessian): H^{-1} * eps^T*eps * 1/(2n-p)
213  The first 3 parameters are translation, then rotation.
214  The covariance is given in the camera coord system,
215  not the world coord system !
216  Also see dissertation of Prof. Koch, page 67.
217  @author grest, Jan. 2006 */
218  int GetCoVarMatrix(BIAS::Matrix<double> &coVar);
219 
220  /** returns the covarinace of the last estimate in the world coo system
221  @author woelk 04/2006 */
222  void GetCov(BIAS::Matrix<double>& cov);
223 
224  /** @brief returns the result vector, corresponding to the covariance
225  matrix
226  @author woelk 03/2006 */
227  BIAS::Vector<double> GetResult() const;
228 
229  /** returns the avg error of the estimation,
230  which is the average difference of
231  the projected points to their
232  corresponding image points . Uses the Mahalanobis-distance,
233  if variances are specified.
234  */
235  double GetAvgError();
236 
237 
238  /** for analyzing only. Set the known groundtruth, used in outputPose_()
239  */
241  BIAS::Vector3<double> upVector,
242  BIAS::Vector3<double> center) {
243  truthUpVec_= upVector;
244  truthCenter_=center;
245  truthOptAxis_=optAxis;
246  }
247 
248  /** @author woelk 05/2006 */
249  int TransformVec(const BIAS::Vector<double>& src,
250  BIAS::Vector<double>& dst);
251 
252 
253  // inline void SetCalcSecondDerivatives(bool on) {
254  // calcSecD_=on;
255  // }
256 
257  protected:
258  ///////////////////////// functions /////////////////////////////////////
259  int Solve_(BIAS::Matrix<double> &J, BIAS::Vector<double> &eps,
260  BIAS::Vector<double> &result);
261 
262  int SolveLM_(BIAS::Matrix<double> &J,BIAS::Vector<double> &eps,
263  BIAS::Vector<double> &result, unsigned int iterations);
264 
265 
266  /** returns the avg error of the estimation,
267  which is the weighted average squared difference of
268  the projected points to their corresponding image point
269  */
270  double GetAvgSquaredWeightedError_();
271 
272 
273  /** helper function for Estimate, creates the Jacobi matrix
274  */
275  int CreateEquationSys_();
276  /** adds rows for 3D-point-2D-point corrs
277  */
278  int AddConstraints2DLine_();
279 
280  /** helper function for Estimate
281  */
282  int ApplySolution_(BIAS::Vector<double> &result);
283 
284  /** for robust estimation
285  */
286  int SetWeightsByError_();
287 
288  // creates the second derivatives
289  int CreateSecDMatrix_();
290 
291  int GuessInitialCam_();
292 
293  int ApplyCoVariances_();
294 
295  // for logging and anaylze
296  void outputPose_(int iteration);
297  BIAS::Vector3<double> truthUpVec_, truthCenter_, truthOptAxis_;
298 
299  std::vector<BIAS::Vector3<double> > mps_,initialMps_, origMps_;
300  std::vector<BIAS::Vector2<double> > tps_; // target points
301 
302  // model points for 2Dlines
303  std::vector<BIAS::Vector3<double> > mpsLine_,origMpsLine_,initialMpsLine_;
304  std::vector<BIAS::Vector2<double> > tpsLinePoint_,tpsLineNormal_;
305 
306  double transChangeEpsilon_, rotChangeEpsilon_;
307 
308  // minimum depth value of a modelpoint, else the corr is not used
309  double minDepthModel_;
311 
312  // the scale of all model points, to achieve numerical stability
313  // most stable, if all entries in the Jacobian are near 1.0
315 
316  std::vector<double> weights_, weightsLine_;
317  BIAS::SVD svd_; // for linear system sloving
321 
322  // for switching on/off the use of second derivatives
323  const bool calcSecD_;
324 
326 
329  bool estimateTransX_,estimateTransY_,estimateTransZ_;
331 
332  // camera values, sx is the focal length in pixel in x-dir
333  double sx_,sy_,cx_,cy_;
334 
336  BIAS::RMatrix camR_,camRT_,resultR_;
338 
339  BIAS::Vector3<double> center_,avgRay_,avgModel_,origAvgModel_;
340 
342 
343  // for robust estimation
346 
347  std::vector<BIAS::Matrix2x2<double> > variances_;
348 
349  /// for LM algorithm extension
350  bool doLM_;
351  double mu_; // the weighting value for the Identity matrix;
352  double initMu_;
353  double lastError_;
356  };
357 
358 }
359 
360 
361 //#include <Base/Common/BIASpragmaEnd.hh>
362 
363 
364 #endif
void SetGroundTruth(BIAS::Vector3< double > optAxis, BIAS::Vector3< double > upVector, BIAS::Vector3< double > center)
for analyzing only.
std::vector< double > weightsLine_
std::vector< BIAS::Vector3< double > > origMps_
void SetChangeEpsilon(double transEpsilon, double rotEpsilon)
if the estimated translation in one iteration step is smaller than this value, iteration stops...
BIAS::Vector3< double > origAvgModel_
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
Definition: SVD.hh:92
BIAS::Matrix< double > coVarMat_
BIAS::Vector3< double > GetTranslation() const
this returns the translation from the initial camera center to the new camera center ...
BIAS::Vector< double > solveVector_
this classs allows estimation of the internal (except skew) and external camera parameters by an iter...
Definition: CamPoseCalib.hh:86
void SetWeightsLine(const std::vector< double > &weights)
void SetWeights(const std::vector< double > &weights)
optional: set weights for each correspondence.
bool doLM_
for LM algorithm extension
void SetVariances(const std::vector< BIAS::Matrix2x2< double > > &variances)
If uncertainties for the 2D points is available set them here.
3D rotation matrix
Definition: RMatrix.hh:49
BIAS::Vector3< double > truthUpVec_
std::vector< BIAS::Vector2< double > > tps_
void SetEstimatePrincipal(bool yes)
wether to estimate the principal point also, default is NO
const bool calcSecD_
BIAS::RMatrix resultR_
BIAS::Matrix< double > solveMatrix_
BIAS::RMatrix GetRotation() const
this return the relative rotation from the initial camera orientation to the new estimated camera rot...
BIAS::Vector3< double > resultTrans_
Matrix3x3< T > Transpose() const
returns transposed matrix tested 12.06.2002
Definition: Matrix3x3.cpp:167
std::vector< BIAS::Vector3< double > > origMpsLine_
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
void SetLM(bool on)
wether to do Levenberg-Maquardt estimation.
std::vector< BIAS::Vector2< double > > tpsLinePoint_
BIAS::Matrix< double > secDMatrix_
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrix.hh:88
void SetEstimateTranslation(const bool estimateTransX, const bool estimateTransY, const bool estimateTransZ)
void SetEstimateFocal(unsigned char val)
wether to estimate the focal length f also, default is NO
std::vector< BIAS::Matrix2x2< double > > variances_
BIAS::RMatrix lastRot_
BIAS::PMatrix camP_