Main MRPT website > C++ reference for MRPT 1.9.9
CCamModel.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef CCamModel_H
10 #define CCamModel_H
11 
12 #include <mrpt/utils/TCamera.h>
13 #include <mrpt/system/os.h>
14 #include <mrpt/vision/utils.h>
17 
18 namespace mrpt
19 {
20 namespace vision
21 {
22 /** This class represent a pinhole camera model for Monocular SLAM and
23  * implements some associated Jacobians
24  *
25  * The camera parameters are accessible in the public member CCamModel::cam
26  *
27  * - Versions:
28  * - First version: By Antonio J. Ortiz de Galistea.
29  * - 2009-2010: Rewritten by various authors.
30  *
31  * \sa mrpt::utils::TCamera, CMonoSlam, the application <a
32  * href="http://www.mrpt.org/Application:camera-calib-gui" >camera-calib-gui</a>
33  * for calibrating a camera
34  * \ingroup mrpt_vision_grp
35  */
37 {
38  public:
39  /** The parameters of a camera */
41 
42  /** Default Constructor */
43  CCamModel();
44 
45  void loadFromConfigFile(
47  const std::string& section) override; // See base docs
48  void dumpToTextStream(
49  mrpt::utils::CStream& out) const override; // See base docs
50 
51  /** Constructor from a ini file
52  */
54 
55  /** Jacobian for undistortion the image coordinates */
56  void jacob_undistor_fm(
57  const mrpt::utils::TPixelCoordf& uvd, math::CMatrixDouble& J_undist);
58 
59  /** Calculate the image coordinates undistorted
60  */
61  void jacob_undistor(
63  mrpt::math::CMatrixDouble& J_undist);
64 
65  /** Return the pixel position distorted by the camera
66  */
67  void distort_a_point(
69  mrpt::utils::TPixelCoordf& distorted_p);
70 
71  /** Return the pixel position undistorted by the camera
72  * The input values 'col' and 'row' will be replace for the new values
73  *(undistorted)
74  */
75  void undistort_point(
77  mrpt::utils::TPixelCoordf& undistorted_p);
78 
79  /** Return the (distorted) pixel position of a 3D point given in
80  * coordinates relative to the camera (+Z pointing forward, +X to the right)
81  * \sa unproject_3D_point
82  */
83  void project_3D_point(
84  const mrpt::math::TPoint3D& p3D,
85  mrpt::utils::TPixelCoordf& distorted_p) const;
86 
87  /** Return the 3D location of a point (at a fixed distance z=1), for the
88  * given (distorted) pixel position
89  * \sa project_3D_point
90  * \note Of course, there is a depth ambiguity, so the returned 3D point
91  * must be considered a direction from the camera focus, or a vector, rather
92  * than a meaninful physical point.
93  */
94  void unproject_3D_point(
95  const mrpt::utils::TPixelCoordf& distorted_p,
96  mrpt::math::TPoint3D& p3D) const;
97 
98  /** Jacobian of the projection of 3D points (with distortion), as done in
99  project_3D_point \f$ \frac{\partial h}{\partial y} \f$, evaluated at the
100  point p3D (read below the full explanation)
101 
102  We define \f$ h = (h_x ~ h_y) \f$ as the projected point in pixels (origin
103  at the top-left corner),
104  and \f$ y=( y_x ~ y_y ~ y_z ) \f$ as the 3D point in space, in coordinates
105  relative to the camera (+Z pointing forwards).
106 
107  Then this method computes the 2x3 Jacobian:
108 
109  \f[
110  \frac{\partial h}{\partial y} = \frac{\partial h}{\partial u}
111  \frac{\partial u}{\partial y}
112  \f]
113 
114  With:
115 
116  \f[
117  \frac{\partial u}{\partial y} =
118  \left( \begin{array}{ccc}
119  \frac{f_x}{y_z} & 0 & - y \frac{f_x}{y_z^2} \\
120  0 & \frac{f_y}{y_z} & - y \frac{f_y}{y_z^2} \\
121  \end{array} \right)
122  \f]
123 
124  where \f$ f_x, f_y \f$ is the focal length in units of pixel sizes in x and
125  y, respectively.
126  And, if we define:
127 
128  \f[
129  f = 1+ 2 k_1 (u_x^2+u_y^2)
130  \f]
131 
132  then:
133 
134  \f[
135  \frac{\partial h}{\partial u} =
136  \left( \begin{array}{cc}
137  \frac{ 1+2 k_1 u_y^2 }{f^{3/2}} & -\frac{2 u_x u_y k_1 }{f^{3/2}} \\
138  -\frac{2 u_x u_y k_1 }{f^{3/2}} & \frac{ 1+2 k_1 u_x^2 }{f^{3/2}}
139  \end{array} \right)
140  \f]
141 
142  \note JLBC: Added in March, 2009. Should be equivalent to Davison's
143  WideCamera::ProjectionJacobian
144  \sa project_3D_point
145  */
147  const mrpt::math::TPoint3D& p3D, math::CMatrixDouble& dh_dy) const;
148 
149  /** Jacobian of the unprojection of a pixel (with distortion) back into a 3D
150  point, as done in unproject_3D_point \f$ \frac{\partial y}{\partial h} \f$,
151  evaluated at the pixel p
152  \note JLBC: Added in March, 2009. Should be equivalent to Davison's
153  WideCamera::UnprojectionJacobian
154  \sa unproject_3D_point
155  */
157  const mrpt::utils::TPixelCoordf& p, math::CMatrixDouble& dy_dh) const;
158 
159  template <typename T>
161  {
162  T x_, y_;
163  T x_2, y_2;
164  T R;
165  T K;
166  T x__, y__;
167  };
168  template <typename T, typename POINT>
170  const POINT& p, CameraTempVariables<T>& v) const
171  {
172  v.x_ = p[1] / p[0];
173  v.y_ = p[2] / p[0];
174  v.x_2 = square(v.x_);
175  v.y_2 = square(v.y_);
176  v.R = v.x_2 + v.y_2;
177  v.K = 1 + v.R * (cam.k1() + v.R * (cam.k2() + v.R * cam.k3()));
178  T xy = v.x_ * v.y_, p1 = cam.p1(), p2 = cam.p2();
179  v.x__ = v.x_ * v.K + 2 * p1 * xy + p2 * (3 * v.x_2 + v.y_2);
180  v.y__ = v.y_ * v.K + p1 * (v.x_2 + 3 * v.y_2) + 2 * p2 * xy;
181  }
182 
183  template <typename T, typename POINT, typename PIXEL>
184  inline void getFullProjection(const POINT& pIn, PIXEL& pOut) const
185  {
188  getFullProjectionT(tmp, pOut);
189  }
190 
191  template <typename T, typename PIXEL>
192  inline void getFullProjectionT(
193  const CameraTempVariables<T>& tmp, PIXEL& pOut) const
194  {
195  pOut[0] = cam.fx() * tmp.x__ + cam.cx();
196  pOut[1] = cam.fy() * tmp.y__ + cam.cy();
197  }
198 
199  template <typename T, typename POINT, typename MATRIX>
200  inline void getFullJacobian(const POINT& pIn, MATRIX& mOut) const
201  {
204  getFullJacobianT(pIn, tmp, mOut);
205  }
206 
207  template <typename T, typename POINT, typename MATRIX>
209  const POINT& pIn, const CameraTempVariables<T>& tmp, MATRIX& mOut) const
210  {
211  T x_ = 1 / pIn[0];
212  T x_2 = square(x_);
213  // First two jacobians...
215  T tmpK = 2 * (cam.k1() + tmp.R * (2 * cam.k2() + 3 * tmp.R * cam.k3()));
216  T tmpKx = tmpK * tmp.x_;
217  T tmpKy = tmpK * tmp.y_;
218  T yx2 = -pIn[1] * x_2;
219  T zx2 = -pIn[2] * x_2;
220  J21.set_unsafe(0, 0, yx2);
221  J21.set_unsafe(0, 1, x_);
222  J21.set_unsafe(0, 2, 0);
223  J21.set_unsafe(1, 0, zx2);
224  J21.set_unsafe(1, 1, 0);
225  J21.set_unsafe(1, 2, x_);
226  J21.set_unsafe(2, 0, tmpKx * yx2 + tmpKy * zx2);
227  J21.set_unsafe(2, 1, tmpKx * x_);
228  J21.set_unsafe(2, 2, tmpKy * x_);
229  // Last two jacobians...
230  T pxpy = 2 * (cam.p1() * tmp.x_ + cam.p2() * tmp.y_);
231  T p1y = cam.p1() * tmp.y_;
232  T p2x = cam.p2() * tmp.x_;
234  T fx = cam.fx(), fy = cam.fy();
235  J43.set_unsafe(0, 0, fx * (tmp.K + 2 * p1y + 6 * p2x));
236  J43.set_unsafe(0, 1, fx * pxpy);
237  J43.set_unsafe(0, 2, fx * tmp.x_);
238  J43.set_unsafe(1, 0, fy * pxpy);
239  J43.set_unsafe(1, 1, fy * (tmp.K + 6 * p1y + 2 * p2x));
240  J43.set_unsafe(1, 2, fy * tmp.y_);
241  mOut.multiply(J43, J21);
242  // cout<<"J21:\n"<<J21<<"\nJ43:\n"<<J43<<"\nmOut:\n"<<mOut;
243  }
244 
245  private:
246  // These functions are little tricks to avoid multiple initialization.
247  // They are intended to initialize the common parts of the jacobians just
248  // once,
249  // and not in each iteration.
250  // They are mostly useless outside the scope of this function.
252  {
254  res.set_unsafe(0, 1, 0);
255  res.set_unsafe(1, 0, 0);
256  return res;
257  }
259  {
261  res.set_unsafe(0, 0, 1);
262  res.set_unsafe(0, 1, 0);
263  res.set_unsafe(1, 0, 0);
264  res.set_unsafe(1, 1, 1);
265  return res;
266  }
268  {
270  res.set_unsafe(0, 1, 0);
271  res.set_unsafe(0, 2, 0);
272  res.set_unsafe(1, 0, 0);
273  res.set_unsafe(1, 2, 0);
274  res.set_unsafe(2, 0, 0);
275  res.set_unsafe(2, 1, 0);
276  res.set_unsafe(2, 2, 1);
277  res.set_unsafe(2, 3, 0);
278  return res;
279  }
280 
281  public:
282  template <typename POINTIN, typename POINTOUT, typename MAT22>
284  const POINTIN& pIn, POINTOUT& pOut, MAT22& jOut) const
285  {
286  // Temporary variables (well, there are some more, but these are the
287  // basics)
288  // WARNING!: this shortcut to avoid repeated initialization makes the
289  // method somewhat
290  // faster, but makes it incapable of being used in more than one thread
291  // simultaneously!
292  using mrpt::math::square;
299  static mrpt::math::CMatrixFixedNumeric<double, 2, 3> J4; // This is not
300  // initialized
301  // in a
302  // special
303  // way,
304  // although
305  // declaring
306  // it
308  mrpt::math::CArrayNumeric<double, 2> tmp2; // This would be a
309  // array<double,3>, but to
310  // avoid copying, we let
311  // "R2" lie in tmp1.
312  // Camera Parameters
313  double cx = cam.cx(), cy = cam.cy(), ifx = 1 / cam.fx(),
314  ify = 1 / cam.fy();
315  double K1 = cam.k1(), K2 = cam.k2(), p1 = cam.p1(), p2 = cam.p2(),
316  K3 = cam.k3();
317  // First step: intrinsic matrix.
318  tmp1[0] = (pIn[0] - cx) * ifx;
319  tmp1[1] = (pIn[1] - cy) * ify;
320  J1.set_unsafe(0, 0, ifx);
321  J1.set_unsafe(1, 1, ify);
322  // Second step: adding temporary variables, related to the distortion.
323  tmp1[2] = square(tmp1[0]) + square(tmp1[1]);
324  double sK1 = square(K1);
325  double K12 = sK1 - K2;
326  double K123 = -K1 * sK1 + 2 * K1 * K2 - K3; //-K1^3+2K1K2-K3
327  // tmp1[3]=1-K1*tmp1[2]+K12*square(tmp1[2]);
328  tmp1[3] = 1 + tmp1[2] * (-K1 + tmp1[2] * (K12 + tmp1[2] * K123));
329  J2.set_unsafe(2, 0, 2 * tmp1[0]);
330  J2.set_unsafe(2, 1, 2 * tmp1[1]);
331  double jTemp = -2 * K1 + 4 * tmp1[2] * K12 + 6 * square(tmp1[2]) * K123;
332  J2.set_unsafe(3, 0, tmp1[0] * jTemp);
333  J2.set_unsafe(3, 1, tmp1[1] * jTemp);
334  // Third step: radial distortion. Really simple, since most work has
335  // been done in the previous step.
336  tmp2[0] = tmp1[0] * tmp1[3];
337  tmp2[1] = tmp1[1] * tmp1[3];
338  J3.set_unsafe(0, 0, tmp1[3]);
339  J3.set_unsafe(0, 3, tmp1[0]);
340  J3.set_unsafe(1, 1, tmp1[3]);
341  J3.set_unsafe(1, 3, tmp1[1]);
342  // Fourth step: tangential distorion. A little more complicated, but not
343  // much more.
344  double prod = tmp2[0] * tmp2[1];
345  // References to tmp1[2] are not errors! That element is "R2".
346  pOut[0] = tmp2[0] - p1 * prod - p2 * (tmp1[2] + 2 * square(tmp2[0]));
347  pOut[1] = tmp2[1] - p1 * (tmp1[2] + 2 * square(tmp2[1])) - p2 * prod;
348  J4.set_unsafe(0, 0, 1 - p1 * tmp2[1] - 4 * p2 * tmp2[0]);
349  J4.set_unsafe(0, 1, -p1 * tmp2[0]);
350  J4.set_unsafe(0, 2, -p2);
351  J4.set_unsafe(1, 0, -p2 * tmp2[1]);
352  J4.set_unsafe(1, 1, 1 - 4 * p1 * tmp2[1] - p2 * tmp2[0]);
353  J4.set_unsafe(1, 2, -p1);
354  // As fast as possible, and without more temporaries, let the jacobian
355  // be J4*J3*J2*J1;
356  jOut.multiply_ABC(J4, J3, J2); // Note that using the other order is
357  // not possible due to matrix sizes
358  // (jOut may, and most probably will, be
359  // fixed).
360  jOut.multiply(jOut, J1);
361  }
362 
363 }; // end class
364 
365 } // end namespace
366 } // end namespace
367 #endif //__CCamModel_H
mrpt::utils::TCamera cam
The parameters of a camera.
Definition: CCamModel.h:40
A pair (x,y) of pixel coordinates (subpixel resolution).
Definition: TPixelCoord.h:21
void getFullProjection(const POINT &pIn, PIXEL &pOut) const
Definition: CCamModel.h:184
double p1() const
Get the value of the p1 distortion parameter.
Definition: TCamera.h:194
double cy() const
Get the value of the principal point y-coordinate (in pixels).
Definition: TCamera.h:176
void jacobian_project_with_distortion(const mrpt::math::TPoint3D &p3D, math::CMatrixDouble &dh_dy) const
Jacobian of the projection of 3D points (with distortion), as done in project_3D_point ...
Definition: CCamModel.cpp:200
CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...
Definition: CArrayNumeric.h:26
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string &section) override
This method load the options from a ".ini"-like file or memory-stored string list.
Definition: CCamModel.cpp:300
void getFullInverseModelWithJacobian(const POINTIN &pIn, POINTOUT &pOut, MAT22 &jOut) const
Definition: CCamModel.h:283
This class allows loading and storing values and vectors of different types from a configuration text...
T square(const T x)
Inline function for the square of a number.
Definition: bits.h:55
double fx() const
Get the value of the focal length x-value (in pixels).
Definition: TCamera.h:178
double fy() const
Get the value of the focal length y-value (in pixels).
Definition: TCamera.h:180
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
A numeric matrix of compile-time fixed size.
double k1() const
Get the value of the k1 distortion parameter.
Definition: TCamera.h:190
void jacob_undistor_fm(const mrpt::utils::TPixelCoordf &uvd, math::CMatrixDouble &J_undist)
Jacobian for undistortion the image coordinates.
Definition: CCamModel.cpp:25
void getTemporaryVariablesForTransform(const POINT &p, CameraTempVariables< T > &v) const
Definition: CCamModel.h:169
void jacobian_unproject_with_distortion(const mrpt::utils::TPixelCoordf &p, math::CMatrixDouble &dy_dh) const
Jacobian of the unprojection of a pixel (with distortion) back into a 3D point, as done in unproject_...
Definition: CCamModel.cpp:265
double p2() const
Get the value of the p2 distortion parameter.
Definition: TCamera.h:196
void unproject_3D_point(const mrpt::utils::TPixelCoordf &distorted_p, mrpt::math::TPoint3D &p3D) const
Return the 3D location of a point (at a fixed distance z=1), for the given (distorted) pixel position...
Definition: CCamModel.cpp:179
void getFullProjectionT(const CameraTempVariables< T > &tmp, PIXEL &pOut) const
Definition: CCamModel.h:192
void project_3D_point(const mrpt::math::TPoint3D &p3D, mrpt::utils::TPixelCoordf &distorted_p) const
Return the (distorted) pixel position of a 3D point given in coordinates relative to the camera (+Z p...
Definition: CCamModel.cpp:150
void jacob_undistor(const mrpt::utils::TPixelCoordf &p, mrpt::math::CMatrixDouble &J_undist)
Calculate the image coordinates undistorted.
Definition: CCamModel.cpp:56
GLsizei const GLchar ** string
Definition: glext.h:4101
double cx() const
Get the value of the principal point x-coordinate (in pixels).
Definition: TCamera.h:174
void distort_a_point(const mrpt::utils::TPixelCoordf &p, mrpt::utils::TPixelCoordf &distorted_p)
Return the pixel position distorted by the camera.
Definition: CCamModel.cpp:103
void getFullJacobian(const POINT &pIn, MATRIX &mOut) const
Definition: CCamModel.h:200
const GLdouble * v
Definition: glext.h:3678
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
This class represent a pinhole camera model for Monocular SLAM and implements some associated Jacobia...
Definition: CCamModel.h:36
double k3() const
Get the value of the k3 distortion parameter.
Definition: TCamera.h:198
void dumpToTextStream(mrpt::utils::CStream &out) const override
This method displays clearly all the contents of the structure in textual form, sending it to a CStre...
Definition: CCamModel.cpp:332
mrpt::math::CMatrixFixedNumeric< double, 4, 2 > secondInverseJacobian() const
Definition: CCamModel.h:258
T square(const T x)
Inline function for the square of a number.
GLsizei GLsizei GLchar * source
Definition: glext.h:4082
void getFullJacobianT(const POINT &pIn, const CameraTempVariables< T > &tmp, MATRIX &mOut) const
Definition: CCamModel.h:208
void undistort_point(const mrpt::utils::TPixelCoordf &p, mrpt::utils::TPixelCoordf &undistorted_p)
Return the pixel position undistorted by the camera The input values &#39;col&#39; and &#39;row&#39; will be replace ...
Definition: CCamModel.cpp:125
mrpt::math::CMatrixFixedNumeric< double, 3, 4 > thirdInverseJacobian() const
Definition: CCamModel.h:267
GLuint res
Definition: glext.h:7268
double k2() const
Get the value of the k2 distortion parameter.
Definition: TCamera.h:192
Lightweight 3D point.
CCamModel()
Default Constructor.
Definition: CCamModel.cpp:23
GLfloat GLfloat p
Definition: glext.h:6305
This is a virtual base class for sets of options than can be loaded from and/or saved to configuratio...
Structure to hold the parameters of a pinhole camera model.
Definition: TCamera.h:32
mrpt::math::CMatrixFixedNumeric< double, 2, 2 > firstInverseJacobian() const
Definition: CCamModel.h:251



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019