SLIP  1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PinholeCamera.hpp
Go to the documentation of this file.
1 /*
2  * Copyright(c):
3  * Signal Image and Communications (SIC) Department
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * - University of Poitiers, France http://www.univ-poitiers.fr
6  * - XLIM Institute UMR CNRS 7252 http://www.xlim.fr/
7  *
8  * and
9  *
10  * D2 Fluid, Thermic and Combustion
11  * - University of Poitiers, France http://www.univ-poitiers.fr
12  * - PPRIME Institute - UPR CNRS 3346 http://www.pprime.fr
13  * - ISAE-ENSMA http://www.ensma.fr
14  *
15  * Contributor(s):
16  * The SLIP team,
17  * Benoit Tremblais <tremblais_AT_sic.univ-poitiers.fr>,
18  * Laurent David <laurent.david_AT_lea.univ-poitiers.fr>,
19  * Ludovic Chatellier <ludovic.chatellier_AT_univ-poitiers.fr>,
20  * Lionel Thomas <lionel.thomas_AT_univ-poitiers.fr>,
21  * Denis Arrivault <arrivault_AT_sic.univ-poitiers.fr>,
22  * Julien Dombre <julien.dombre_AT_univ-poitiers.fr>.
23  *
24  * Description:
25  * The Simple Library of Image Processing (SLIP) is a new image processing
26  * library. It is written in the C++ language following as much as possible
27  * the ISO/ANSI C++ standard. It is consequently compatible with any system
28  * satisfying the ANSI C++ complience. It works on different Unix , Linux ,
29  * Mircrosoft Windows and Mac OS X plateforms. SLIP is a research library that
30  * was created by the Signal, Image and Communications (SIC) departement of
31  * the XLIM, UMR 7252 CNRS Institute in collaboration with the Fluids, Thermic
32  * and Combustion departement of the P', UPR 3346 CNRS Institute of the
33  * University of Poitiers.
34  *
35  * The SLIP Library source code has been registered to the APP (French Agency
36  * for the Protection of Programs) by the University of Poitiers and CNRS,
37  * under registration number IDDN.FR.001.300034.000.S.P.2010.000.21000.
38 
39  * http://www.sic.sp2mi.univ-poitiers.fr/slip/
40  *
41  * This software is governed by the CeCILL-C license under French law and
42  * abiding by the rules of distribution of free software. You can use,
43  * modify and/ or redistribute the software under the terms of the CeCILL-C
44  * license as circulated by CEA, CNRS and INRIA at the following URL
45  * http://www.cecill.info.
46  * As a counterpart to the access to the source code and rights to copy,
47  * modify and redistribute granted by the license, users are provided only
48  * with a limited warranty and the software's author, the holder of the
49  * economic rights, and the successive licensors have only limited
50  * liability.
51  *
52  * In this respect, the user's attention is drawn to the risks associated
53  * with loading, using, modifying and/or developing or reproducing the
54  * software by the user in light of its specific status of free software,
55  * that may mean that it is complicated to manipulate, and that also
56  * therefore means that it is reserved for developers and experienced
57  * professionals having in-depth computer knowledge. Users are therefore
58  * encouraged to load and test the software's suitability as regards their
59  * requirements in conditions enabling the security of their systems and/or
60  * data to be ensured and, more generally, to use and operate it in the
61  * same conditions as regards security.
62  *
63  * The fact that you are presently reading this means that you have had
64  * knowledge of the CeCILL-C license and that you accept its terms.
65  */
66 
67 
75 #ifndef SLIP_PINHOLECAMERA_HPP
76 #define SLIP_PINHOLECAMERA_HPP
77 
78 #include <iostream>
79 #include <cassert>
80 #include <cassert>
81 #include "Point2d.hpp"
82 #include "Point3d.hpp"
83 #include "Vector3d.hpp"
84 #include "Matrix.hpp"
85 #include "io_tools.hpp"
86 #include "linear_algebra.hpp"
87 
88 
89 #include "CameraModel.hpp"
90 #include "camera_algo.hpp"
91 
92 #include <boost/serialization/access.hpp>
93 #include <boost/serialization/split_member.hpp>
94 #include <boost/serialization/version.hpp>
95 #include <boost/serialization/base_object.hpp>
96 
97 
98 namespace slip {
99  template <typename Type>
101 
102  template <typename Type>
103  std::ostream& operator<<(std::ostream & out, const PinholeCamera<Type>& c);
104 
116  template <typename Type>
117  class PinholeCamera: public CameraModel<Type> {
118  typedef PinholeCamera<Type> self;
120  public:
125 
130  calibration_matrix_(new slip::Matrix<Type>(3,4)),
131  d_calibration_matrix_(new slip::Matrix<Type>(5,3))
132  {
133  }
138  PinholeCamera(const self& rhs):
139  base(rhs),
140  calibration_matrix_(new slip::Matrix<Type>(*(rhs.calibration_matrix_))),
141  d_calibration_matrix_(new slip::Matrix<Type>(*(rhs.d_calibration_matrix_)))
142  {}
143 
144 
149  {
150  if(calibration_matrix_ != 0)
151  {
152  delete calibration_matrix_;
153  }
154  if(d_calibration_matrix_ != 0)
155  {
156  delete d_calibration_matrix_;
157  }
158  }
159 
172  friend std::ostream& operator<< <>(std::ostream & out, const self& c);
193  void read(const std::string& file)
194  {
196  this->update_d_calibration_matrix();
197  }
198 
212  void write(const std::string& file)
213  {
214  slip::write_ascii_2d<slip::Matrix<Type>,Type>(*calibration_matrix_,file);
215  }
230  self& operator=(const self & rhs)
231  {
232  if(this != &rhs)
233  {
234  this->base::operator=(rhs);
235  if(this->calibration_matrix_ != 0)
236  {
237  delete this->calibration_matrix_;
238  }
239  this->calibration_matrix_ = new slip::Matrix<Type>(*(rhs.calibration_matrix_));
240  if(this->d_calibration_matrix_ != 0)
241  {
242  delete this->d_calibration_matrix_;
243  }
244  this->d_calibration_matrix_ = new slip::Matrix<Type>(*(rhs.d_calibration_matrix_));
245  }
246  return *this;
247  }
258  {
259  return *calibration_matrix_;
260  }
261 
266  {
267  return *d_calibration_matrix_;
268  }
269 
275  {
276  assert(calibration_matrix.rows() == 3);
277  assert(calibration_matrix.cols() == 4);
278  *(this->calibration_matrix_) = calibration_matrix;
279  this->update_d_calibration_matrix();
280  }
281 
287  {
288  assert(d_calibration_matrix.rows() == 5);
289  assert(d_calibration_matrix.cols() == 3);
290  *(this->d_calibration_matrix_) = d_calibration_matrix;
291  }
292 
293 
321  inline
323  {
324  Type px = (*calibration_matrix_)[0][0]*p[0]
325  + (*calibration_matrix_)[0][1]*p[1]
326  + (*calibration_matrix_)[0][2]*p[2]
327  + (*calibration_matrix_)[0][3];
328  Type py = (*calibration_matrix_)[1][0]*p[0]
329  + (*calibration_matrix_)[1][1]*p[1]
330  + (*calibration_matrix_)[1][2]*p[2]
331  + (*calibration_matrix_)[1][3];
332  Type s = (*calibration_matrix_)[2][0]*p[0]
333  + (*calibration_matrix_)[2][1]*p[1]
334  + (*calibration_matrix_)[2][2]*p[2]
335  + (*calibration_matrix_)[2][3];
336  Type inv_s = static_cast<Type>(1)/s;
337  px*=inv_s;
338  py*=inv_s;
339 
340  return slip::Point2d<Type>(px,py);
341  }
342 
352  // inline
353  // slip::Point3d<Type> backprojection(const slip::Point2d<Type>& p2, const Type& z) {
354 
355  // const Type zero = static_cast<Type>(0.0);
356 
357  // Type px = p2[0];
358  // Type py = p2[1];
359 
360  // Type P0 = p2[0]*(*calibration_matrix_)[2][0]-(*calibration_matrix_)[0][0];
361  // Type P1 = p2[0]*(*calibration_matrix_)[2][1]-(*calibration_matrix_)[0][1];
362  // Type P2 = p2[0]*(*calibration_matrix_)[2][2]-(*calibration_matrix_)[0][2];
363  // Type p = -(p2[0]*(*calibration_matrix_)[2][3]-(*calibration_matrix_)[0][3]);
364 
365  // Type Q0 = p2[1]*(*calibration_matrix_)[2][0]-(*calibration_matrix_)[1][0];
366  // Type Q1 = p2[1]*(*calibration_matrix_)[2][1]-(*calibration_matrix_)[1][1];
367  // Type Q2 = p2[1]*(*calibration_matrix_)[2][2]-(*calibration_matrix_)[1][2];
368  // Type q = -(p2[1]*(*calibration_matrix_)[2][3]-(*calibration_matrix_)[1][3]);
369 
370  // Type det = (P0*Q1)-(Q0*P1);
371 
372  // if (det != zero)
373  // {
374  // Type inv_det = static_cast<Type>(1)/det;
375  // px=((((P1*Q2)-(Q1*P2))*z)+(p*Q1)-(P1*q))*inv_det;
376  // py=((((P2*Q0)-(Q2*P0))*z)+(q*P0)-(Q0*p))*inv_det;
377  // }
378 
379  // return slip::Point3d<Type>(px,py,z);
380  // }
381 
382 
390  inline
392  const Type& z) {
393 
394 
395  const Type zero = static_cast<Type>(0.0);
396 
397  Type px =
398  (z*(*d_calibration_matrix_)[0][0] + (*d_calibration_matrix_)[2][0]) * p2[0] +
399  (z*(*d_calibration_matrix_)[0][1] + (*d_calibration_matrix_)[2][1]) * p2[1] +
400  (z*(*d_calibration_matrix_)[0][2] + (*d_calibration_matrix_)[2][2]);
401 
402  Type py =
403  (z*(*d_calibration_matrix_)[1][0] + (*d_calibration_matrix_)[3][0]) * p2[0] +
404  (z*(*d_calibration_matrix_)[1][1] + (*d_calibration_matrix_)[3][1]) * p2[1] +
405  (z*(*d_calibration_matrix_)[1][2] + (*d_calibration_matrix_)[3][2]);
406 
407  Type s =
408  ((*d_calibration_matrix_)[4][0]) * p2[0] +
409  ((*d_calibration_matrix_)[4][1]) * p2[1] +
410  ((*d_calibration_matrix_)[4][2]);
411 
412  if (s != zero)
413  {
414  Type inv_s = static_cast<Type>(1)/s;
415  px*=inv_s;
416  py*=inv_s;
417  }
418 
419  return slip::Point3d<Type>(px,py,z);
420  }
421 
443  virtual void compute(const slip::Matrix<Type>& P)
444  {
446  }
447 
448 
466  virtual int decompose(slip::Matrix<Type>& K,
467  slip::Matrix<Type>& R,
469  slip::DECOMP_TYPE flag)
470  {
471  int sing = 1;
472  if(flag == RQ)
473  {
474  sing=decompose_RQ(*calibration_matrix_,K,R,c);
475  }
476 
477  if(flag==direct)
478  {
480  }
481 
482  return sing;
483  }
489  //protected:
492 
493  private:
495  template<class Archive>
496  void save(Archive & ar, const unsigned int version) const
497  {
498  ar & boost::serialization::base_object<slip::CameraModel<Type> >(*this);
499  ar & calibration_matrix_;
501  }
502  template<class Archive>
503  void load(Archive & ar, const unsigned int version)
504  {
505  ar & boost::serialization::base_object<slip::CameraModel<Type> >(*this);
506  ar & calibration_matrix_;
508  }
509  BOOST_SERIALIZATION_SPLIT_MEMBER()
510 
511 
512  void update_d_calibration_matrix()
513  {
514  d_calibration_matrix_->fill(static_cast<Type>(0.0));
515 
516  (*d_calibration_matrix_)[0][0] = (((*calibration_matrix_)[1][1] * (*calibration_matrix_)[2][2])-((*calibration_matrix_)[1][2] * (*calibration_matrix_)[2][1]));
517  (*d_calibration_matrix_)[0][1] = (((*calibration_matrix_)[2][1] * (*calibration_matrix_)[0][2]) - ((*calibration_matrix_)[2][2] * (*calibration_matrix_)[0][1]));
518  (*d_calibration_matrix_)[0][2] = (((*calibration_matrix_)[0][1] * (*calibration_matrix_)[1][2]) - ((*calibration_matrix_)[0][2] * (*calibration_matrix_)[1][1]));
519 
520  (*d_calibration_matrix_)[1][0] = (((*calibration_matrix_)[1][2] * (*calibration_matrix_)[2][0]) - ((*calibration_matrix_)[1][0] * (*calibration_matrix_)[2][2]));
521  (*d_calibration_matrix_)[1][1] = (((*calibration_matrix_)[2][2] * (*calibration_matrix_)[0][0]) - ((*calibration_matrix_)[2][0] * (*calibration_matrix_)[0][2]));
522  (*d_calibration_matrix_)[1][2] = (((*calibration_matrix_)[0][2] * (*calibration_matrix_)[1][0]) - ((*calibration_matrix_)[0][0] * (*calibration_matrix_)[1][2]));
523 
524  (*d_calibration_matrix_)[2][0] = (((*calibration_matrix_)[1][1] * (*calibration_matrix_)[2][3]) - ((*calibration_matrix_)[1][3] * (*calibration_matrix_)[2][1]));
525  (*d_calibration_matrix_)[2][1] = (((*calibration_matrix_)[2][1] * (*calibration_matrix_)[0][3]) - ((*calibration_matrix_)[2][3] * (*calibration_matrix_)[0][1]));
526  (*d_calibration_matrix_)[2][2] = (((*calibration_matrix_)[0][1] * (*calibration_matrix_)[1][3]) - ((*calibration_matrix_)[0][3] * (*calibration_matrix_)[1][1]));
527 
528  (*d_calibration_matrix_)[3][0] = (((*calibration_matrix_)[1][3] * (*calibration_matrix_)[2][0]) - ((*calibration_matrix_)[1][0] * (*calibration_matrix_)[2][3]));
529  (*d_calibration_matrix_)[3][1] = (((*calibration_matrix_)[2][3] * (*calibration_matrix_)[0][0]) - ((*calibration_matrix_)[2][0] * (*calibration_matrix_)[0][3]));
530  (*d_calibration_matrix_)[3][2] = (((*calibration_matrix_)[0][3] * (*calibration_matrix_)[1][0]) - ((*calibration_matrix_)[0][0] * (*calibration_matrix_)[1][3]));
531 
532  (*d_calibration_matrix_)[4][0] = (((*calibration_matrix_)[1][0] * (*calibration_matrix_)[2][1]) - ((*calibration_matrix_)[1][1] * (*calibration_matrix_)[2][0]));
533  (*d_calibration_matrix_)[4][1] = (((*calibration_matrix_)[2][0] * (*calibration_matrix_)[0][1]) - ((*calibration_matrix_)[2][1] * (*calibration_matrix_)[0][0]));
534  (*d_calibration_matrix_)[4][2] = (((*calibration_matrix_)[0][0] * (*calibration_matrix_)[1][1]) - ((*calibration_matrix_)[0][1] * (*calibration_matrix_)[1][0]));
535  }
536  };
537 
538 }//slip::
539 
540 
541 namespace slip
542 {
543  template<typename Type>
544  std::ostream& operator<<(std::ostream & out, const PinholeCamera<Type>& c)
545  {
546  out<<*c.calibration_matrix_<<std::endl;
547  return out;
548  }
549 }//slip::
550 #endif //SLIP_PINHOLECAMERA_HPP
Provides a class to modelize 3d points.
self & operator=(const self &other)
Assign a CameraModel.
virtual void compute(const slip::Matrix< Type > &P)
Computes the parameters of the pinhole camera model.
int decompose_direct(const slip::Matrix< Type > &M, slip::Matrix< Type > &K, slip::Matrix< Type > &R, slip::Vector3d< Type > &c)
Direct-Decomposition a 3x4-Matrix into internal and external parameters.
This is a Vector3d struct. It is a specialization of kvector. It implements some specific 3d operatio...
Definition: Vector3d.hpp:96
Define a PinholeCamera class.
Provides a camera algorithms.
size_type cols() const
Returns the number of columns (second dimension size) in the Matrix.
Definition: Matrix.hpp:3512
slip::Point2d< Type > projection(const slip::Point3d< Type > &p)
Computes the projection of a 3d world point onto the image plane.
void calibration_matrix(const slip::Matrix< Type > &calibration_matrix)
Set the calibration matrix.
int decompose_RQ(const slip::Matrix< Type > &M, slip::Matrix< Type > &K, slip::Matrix< Type > &R, slip::Vector3d< Type > &c)
RQ-Decomposition 3x4-Matrix into internal and external parameters.
Provides common linear algebra algorithms.
slip::Matrix< Type > * d_calibration_matrix_
PinholeCamera(const self &rhs)
Constructs a copy of the PinholeCamera rhs.
This is a point2d class, a specialized version of Point<CoordType,DIM> with DIM = 2...
Definition: Array2d.hpp:132
PinholeCamera()
Default constructor of PinholeCamera.
Provides a class to manipulate 3d Vector.
Provides an abstract class to model cameras.
slip::Point3d< Type > backprojection(const slip::Point2d< Type > &p2, const Type &z)
Computes the 3d world point corresponding to the backprojection of an image point.
void d_calibration_matrix(const slip::Matrix< Type > &d_calibration_matrix)
Set the d_calibration matrix.
Provides some input/ouput algorithms.
slip::Matrix< Type > * calibration_matrix_
Numerical matrix class. This container statisfies the BidirectionnalContainer concepts of the STL...
void read(const std::string &file)
Read a calibration matrix from an ASCII file.
void getpars_Faugeras(const slip::Matrix< Type > &P, slip::Matrix< Type > &Mat)
Get calibration parameters using the Faugeras-Algorithm.
size_type rows() const
Returns the number of rows (first dimension size) in the Matrix.
Definition: Matrix.hpp:3499
virtual int decompose(slip::Matrix< Type > &K, slip::Matrix< Type > &R, slip::Vector3d< Type > &c, slip::DECOMP_TYPE flag)
Decomposes a pinhole camera matrix.
slip::Matrix< Type > & d_calibration_matrix() const
Get back d_calibration matrix.
void fill(const T &value)
Fills the container range [begin(),begin()+size()) with copies of value.
Definition: Matrix.hpp:1915
Provides a class to manipulate Numerical Matrix.
Provides a class to modelize 2d points.
self & operator=(const self &rhs)
Assign a PinholeCamera.
void write(const std::string &file)
Write a calibration matrix to an ASCII file.
void read_ascii_2d(Container2d &container, const std::string &file_path_name)
Read a Container2d from an ASCII file.
Definition: io_tools.hpp:544
~PinholeCamera()
Destructor of the PinholeCamera.
Define an abstract CameraModel class.
Definition: CameraModel.hpp:93
This is a point3d class, a specialized version of Point<CoordType,DIM> with DIM = 3...
friend class boost::serialization::access
slip::Matrix< Type > & calibration_matrix() const
Get calibration matrix.