SLIP  1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SoloffCamera.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 
68 
76 #ifndef SLIP_SOLOFFCAMERA_HPP
77 #define SLIP_SOLOFFCAMERA_HPP
78 
79 #include <iostream>
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 "CameraModel.hpp"
87 #include "camera_algo.hpp"
88 #include "polynomial_algo.hpp"
89 
90 #include <boost/serialization/access.hpp>
91 #include <boost/serialization/split_member.hpp>
92 #include <boost/serialization/version.hpp>
93 #include <boost/serialization/base_object.hpp>
94 
95 namespace slip
96 {
97  template <typename Type>
98  class SoloffCamera;
99 
100  template <typename Type>
101  std::ostream& operator<<(std::ostream & out, const slip::SoloffCamera<Type>& c);
102 
116  template <typename Type>
117  class SoloffCamera:public slip::CameraModel<Type> {
118  typedef slip::SoloffCamera<Type> self;
120  public:
125 
130  calibration_polynomial_x_(new slip::MultivariatePolynomial<Type,3>((std::size_t)3)),
131  calibration_polynomial_y_(new slip::MultivariatePolynomial<Type,3>((std::size_t)3)),
132  calibration_polynomial_X_(new slip::MultivariatePolynomial<Type,3>((std::size_t)3)),
133  calibration_polynomial_Y_(new slip::MultivariatePolynomial<Type,3>((std::size_t)3)),
134  calibration_polynomial_coeff_x_(new slip::Array<Type>(20)),
135  calibration_polynomial_coeff_y_(new slip::Array<Type>(20)),
136  calibration_polynomial_coeff_X_(new slip::Array<Type>(20)),
137  calibration_polynomial_coeff_Y_(new slip::Array<Type>(20))
138  {
139  }
144  SoloffCamera(const self& rhs):
145  base(rhs),
154 
155  {}
156 
161  {
170  }
178 
184  friend std::ostream& operator<< <>(std::ostream & out, const self& c);
185 
201  self& operator=(const self & rhs)
202  {
203  if(this != &rhs)
204  {
205  this->base::operator=(rhs);
206 
208  {
210  }
211  calibration_polynomial_x_ = new slip::MultivariatePolynomial<Type,3>(*(rhs.calibration_polynomial_x_));
213  {
215  }
216  calibration_polynomial_y_ = new slip::MultivariatePolynomial<Type,3>(*(rhs.calibration_polynomial_y_));
218  {
220  }
221  calibration_polynomial_X_ = new slip::MultivariatePolynomial<Type,3>(*(rhs.calibration_polynomial_X_));
223  {
225  }
226  calibration_polynomial_Y_ = new slip::MultivariatePolynomial<Type,3>(*(rhs.calibration_polynomial_Y_));
228  {
230  }
231  calibration_polynomial_coeff_x_ = new slip::Array<Type>(*(rhs.calibration_polynomial_coeff_x_));
233  {
235  }
236  calibration_polynomial_coeff_y_ = new slip::Array<Type>(*(rhs.calibration_polynomial_coeff_y_));
238  {
240  }
241  calibration_polynomial_coeff_X_ = new slip::Array<Type>(*(rhs.calibration_polynomial_coeff_X_));
243  {
245  }
246  calibration_polynomial_coeff_Y_ = new slip::Array<Type>(*(rhs.calibration_polynomial_coeff_Y_));
247 
248  }
249  return *this;
250  }
263  {
265  }
266 
273  {
274  assert(calibration_polynomial_x.degree() == 3);
275  *(this->calibration_polynomial_x_) = calibration_polynomial_x;
276  calibration_polynomial_x.all_coeff(this->calibration_polynomial_coeff_x_->begin(),
278  }
279 
285  {
287  }
288 
295  {
296  assert(calibration_polynomial_y.degree() == 3);
297  *(this->calibration_polynomial_y_) = calibration_polynomial_y;
298  calibration_polynomial_y.all_coeff(this->calibration_polynomial_coeff_y_->begin(),
300  }
301 
302 
308  {
310  }
311 
318  {
319  assert(calibration_polynomial_X.degree() == 3);
320  *(this->calibration_polynomial_X_) = calibration_polynomial_X;
321  calibration_polynomial_X.all_coeff(this->calibration_polynomial_coeff_X_->begin(),
323  }
324 
330  {
332  }
333 
340  {
341  assert(calibration_polynomial_Y.degree() == 3);
342  *(this->calibration_polynomial_Y_) = calibration_polynomial_Y;
343  calibration_polynomial_Y.all_coeff(this->calibration_polynomial_coeff_Y_->begin(),
345  }
346 
352  {
354  }
362  template <typename RandomAccessIterator>
363  void calibration_polynomial_coeff_x(RandomAccessIterator first,
364  RandomAccessIterator last)
365  {
366  assert((last-first) == 20);
367  *calibration_polynomial_coeff_x_ = slip::Array<Type>(static_cast<std::size_t>(last-first),first,last);
369 
370  }
376  {
378  }
379 
387  template <typename RandomAccessIterator>
388  void calibration_polynomial_coeff_y(RandomAccessIterator first,
389  RandomAccessIterator last)
390  {
391  assert((last-first) == 20);
392  *calibration_polynomial_coeff_y_ = slip::Array<Type>(static_cast<std::size_t>(last-first),first,last);
394 
395  }
401  {
403  }
404 
412  template <typename RandomAccessIterator>
413  void calibration_polynomial_coeff_X(RandomAccessIterator first,
414  RandomAccessIterator last)
415  {
416  assert((last-first) == 20);
417  *calibration_polynomial_coeff_X_ = slip::Array<Type>(static_cast<std::size_t>(last-first),first,last);
419 
420  }
421 
427  {
429  }
430 
438  template <typename RandomAccessIterator>
439  void calibration_polynomial_coeff_Y(RandomAccessIterator first,
440  RandomAccessIterator last)
441  {
442  assert((last-first) == 20);
443  *calibration_polynomial_coeff_Y_ = slip::Array<Type>(static_cast<std::size_t>(last-first),first,last);
445 
446  }
460  inline
462  {
463 
464  Type px =
465  (*calibration_polynomial_coeff_x_)[0]
466  + p[0]*( (*calibration_polynomial_coeff_x_)[1]
467  + p[0]*((*calibration_polynomial_coeff_x_)[2] + (*calibration_polynomial_coeff_x_)[3]*p[0])
468  + p[1]*((*calibration_polynomial_coeff_x_)[5] +
469  (*calibration_polynomial_coeff_x_)[6] *p[0] +
470  (*calibration_polynomial_coeff_x_)[8] *p[1] +
471  (*calibration_polynomial_coeff_x_)[14]*p[2])
472  + p[2]*((*calibration_polynomial_coeff_x_)[11] +
473  (*calibration_polynomial_coeff_x_)[12]*p[0] +
474  (*calibration_polynomial_coeff_x_)[17]*p[2]))
475  + p[1] * ((*calibration_polynomial_coeff_x_)[4] +
476  p[1]*((*calibration_polynomial_coeff_x_)[7]+
477  (*calibration_polynomial_coeff_x_)[9]*p[1]))
478  + p[2] * ((*calibration_polynomial_coeff_x_)[10] +
479  p[1]*((*calibration_polynomial_coeff_x_)[13] +
480  (*calibration_polynomial_coeff_x_)[15]*p[1] +
481  (*calibration_polynomial_coeff_x_)[18]*p[2]) +
482  p[2]*((*calibration_polynomial_coeff_x_)[16] +
483  (*calibration_polynomial_coeff_x_)[19]*p[2]));
484  Type py =
485  (*calibration_polynomial_coeff_y_)[0]
486  + p[0]*( (*calibration_polynomial_coeff_y_)[1]
487  + p[0]*((*calibration_polynomial_coeff_y_)[2] + (*calibration_polynomial_coeff_y_)[3]*p[0])
488  + p[1]*((*calibration_polynomial_coeff_y_)[5] +
489  (*calibration_polynomial_coeff_y_)[6] *p[0] +
490  (*calibration_polynomial_coeff_y_)[8] *p[1] +
491  (*calibration_polynomial_coeff_y_)[14]*p[2])
492  + p[2]*((*calibration_polynomial_coeff_y_)[11] +
493  (*calibration_polynomial_coeff_y_)[12]*p[0] +
494  (*calibration_polynomial_coeff_y_)[17]*p[2]))
495  + p[1] * ((*calibration_polynomial_coeff_y_)[4] +
496  p[1]*((*calibration_polynomial_coeff_y_)[7]+
497  (*calibration_polynomial_coeff_y_)[9]*p[1]))
498  + p[2] * ((*calibration_polynomial_coeff_y_)[10] +
499  p[1]*((*calibration_polynomial_coeff_y_)[13] +
500  (*calibration_polynomial_coeff_y_)[15]*p[1] +
501  (*calibration_polynomial_coeff_y_)[18]*p[2]) +
502  p[2]*((*calibration_polynomial_coeff_y_)[16] +
503  (*calibration_polynomial_coeff_y_)[19]*p[2]));
504 
505  return slip::Point2d<Type>(px,py);
506  }
507 
516  inline
518  const Type& z)
519  {
520  Type pX =
521  (*calibration_polynomial_coeff_X_)[0]
522  + p2[0]*( (*calibration_polynomial_coeff_X_)[1]
523  + p2[0]*((*calibration_polynomial_coeff_X_)[2] + (*calibration_polynomial_coeff_X_)[3]*p2[0])
524  + p2[1]*((*calibration_polynomial_coeff_X_)[5] +
525  (*calibration_polynomial_coeff_X_)[6] *p2[0] +
526  (*calibration_polynomial_coeff_X_)[8] *p2[1] +
527  (*calibration_polynomial_coeff_X_)[14]*z)
528  + z*((*calibration_polynomial_coeff_X_)[11] +
529  (*calibration_polynomial_coeff_X_)[12]*p2[0] +
530  (*calibration_polynomial_coeff_X_)[17]*z))
531  + p2[1] * ((*calibration_polynomial_coeff_X_)[4] +
532  p2[1]*((*calibration_polynomial_coeff_X_)[7]+
533  (*calibration_polynomial_coeff_X_)[9]*p2[1]))
534  + z * ((*calibration_polynomial_coeff_X_)[10] +
535  p2[1]*((*calibration_polynomial_coeff_X_)[13] +
536  (*calibration_polynomial_coeff_X_)[15]*p2[1] +
537  (*calibration_polynomial_coeff_X_)[18]*z) +
539  (*calibration_polynomial_coeff_X_)[19]*z));
540  Type pY =
541  (*calibration_polynomial_coeff_Y_)[0]
542  + p2[0]*( (*calibration_polynomial_coeff_Y_)[1]
543  + p2[0]*((*calibration_polynomial_coeff_Y_)[2] + (*calibration_polynomial_coeff_Y_)[3]*p2[0])
544  + p2[1]*((*calibration_polynomial_coeff_Y_)[5] +
545  (*calibration_polynomial_coeff_Y_)[6] *p2[0] +
546  (*calibration_polynomial_coeff_Y_)[8] *p2[1] +
547  (*calibration_polynomial_coeff_Y_)[14]*z)
548  + z*((*calibration_polynomial_coeff_Y_)[11] +
549  (*calibration_polynomial_coeff_Y_)[12]*p2[0] +
550  (*calibration_polynomial_coeff_Y_)[17]*z))
551  + p2[1] * ((*calibration_polynomial_coeff_Y_)[4] +
552  p2[1]*((*calibration_polynomial_coeff_Y_)[7]+
553  (*calibration_polynomial_coeff_Y_)[9]*p2[1]))
554  + z * ((*calibration_polynomial_coeff_Y_)[10] +
555  p2[1]*((*calibration_polynomial_coeff_Y_)[13] +
556  (*calibration_polynomial_coeff_Y_)[15]*p2[1] +
557  (*calibration_polynomial_coeff_Y_)[18]*z) +
559  (*calibration_polynomial_coeff_Y_)[19]*z));
560 
561  return slip::Point3d<Type>(pX,pY,z);
562  }
563 
584  void compute(const slip::Matrix<Type>& P)
585  {
596  }
597 
618  void read(const std::string& file) {
620  slip::read_ascii_2d(F,file);
621  slip::Vector<Type> mu(20), mv(20),mX(20), mY(20);
622  for(int i=0; i<20; i++) {
623  mu[i]=F[i][0]; mv[i]=F[i][1]; mX[i]=F[i][2]; mY[i]=F[i][3];
624  }
625  slip::MultivariatePolynomial<Type,3> Pu(3,mu.begin(),mu.end());
626  slip::MultivariatePolynomial<Type,3> Pv(3,mv.begin(),mv.end());
627  slip::MultivariatePolynomial<Type,3> PX(3,mX.begin(),mX.end());
633  std::copy(mu.begin(),mu.end(),calibration_polynomial_coeff_x_->begin());
634  std::copy(mv.begin(),mv.end(),calibration_polynomial_coeff_y_->begin());
635  std::copy(mX.begin(),mX.end(),calibration_polynomial_coeff_X_->begin());
637  }
652  void write(const std::string& file) {
653 
654  std::ofstream output(file.c_str(),std::ios::out);
655  slip::Vector<Type> mu(20), mv(20),mX(20), mY(20);
656  calibration_polynomial_x_->all_coeff(mu.begin(),mu.end());
657  calibration_polynomial_y_->all_coeff(mv.begin(),mv.end());
658  calibration_polynomial_X_->all_coeff(mX.begin(),mX.end());
659  calibration_polynomial_Y_->all_coeff(mY.begin(),mY.end());
660  for(int i=0;i<20; i++){
661  output<<mu[i]<<" "<<mv[i]<<" "<<mX[i]<<" "<<mY[i]<<std::endl;
662  }
663  output.close();
664 
665  }
667  //protected:
676 
677  private:
679  template<class Archive>
680  void save(Archive & ar, const unsigned int version) const
681  {
682  ar & boost::serialization::base_object<slip::CameraModel<Type> >(*this);
691 
692  }
693  template<class Archive>
694  void load(Archive & ar, const unsigned int version)
695  {
696  ar & boost::serialization::base_object<slip::CameraModel<Type> >(*this);
705  }
706  BOOST_SERIALIZATION_SPLIT_MEMBER()
707  };
708 
709 }//slip::
710 
711 
712 namespace slip {
713 
714  template<typename Type>
715  std::ostream& operator<<(std::ostream & out, const slip::SoloffCamera<Type>& c) {
716  slip::MultivariatePolynomial<Type,3> MPx=*c.calibration_polynomial_x_;
717  slip::MultivariatePolynomial<Type,3> MPy=*c.calibration_polynomial_y_;
718  slip::MultivariatePolynomial<Type,3> MPX=*c.calibration_polynomial_X_;
719  slip::MultivariatePolynomial<Type,3> MPY=*c.calibration_polynomial_Y_;
720 
721  out<<MPx<<std::endl;
722  out<<MPy<<std::endl;
723  out<<MPX<<std::endl;
724  out<<MPY<<std::endl;
725  return out;
726  }
727 
728 }//slip::
729 #endif //SLIP_SOLOFFCAMERA_HPP
slip::Array< Type > & calibration_polynomial_coeff_x() const
Get the image x calibration polynomial.
Provides a class to modelize 3d points.
slip::Array< Type > * calibration_polynomial_coeff_Y_
self & operator=(const self &other)
Assign a CameraModel.
slip::Array< Type > & calibration_polynomial_coeff_Y() const
Get the real world Y calibration polynomial.
slip::MultivariatePolynomial< Type, 3 > & calibration_polynomial_y() const
Get the image y calibration polynomial.
slip::MultivariatePolynomial< Type, 3 > * calibration_polynomial_y_
slip::MultivariatePolynomial< Type, 3 > & calibration_polynomial_X() const
Get the real world X calibration polynomial.
iterator end()
Returns a read/write iterator that points one past the last element in the Vector. Iteration is done in ordinary element order.
Definition: Vector.hpp:1481
self & operator=(const self &rhs)
Assign a SoloffCamera.
Provides a camera algorithms.
iterator begin()
Returns a read/write iterator that points to the first element in the Array. Iteration is done in ord...
Definition: Array.hpp:1077
slip::Array< Type > & calibration_polynomial_coeff_y() const
Get the image y calibration polynomial.
void calibration_polynomial_X(const slip::MultivariatePolynomial< Type, 3 > &calibration_polynomial_X)
Set the real world X calibration polynomial equal to calibration_polynomial_X.
slip::MultivariatePolynomial< Type, 3 > * calibration_polynomial_X_
slip::Array< Type > * calibration_polynomial_coeff_X_
void calibration_polynomial_x(const slip::MultivariatePolynomial< Type, 3 > &calibration_polynomial_x)
Set the image x calibration polynomial equal to calibration_polynomial_x.
void calibration_polynomial_coeff_y(RandomAccessIterator first, RandomAccessIterator last)
Set the image y calibration polynomial coefficient to the range [first,last)
void getpars_SoloffUV(const slip::Matrix< Type > &P, slip::MultivariatePolynomial< Type, 3 > &Pol_x, slip::MultivariatePolynomial< Type, 3 > &Pol_y)
Get calibration parameters using a polynomial fit (computation "by hand")
void calibration_polynomial_coeff_Y(RandomAccessIterator first, RandomAccessIterator last)
Set the real world Y calibration polynomial coefficient to the range [first,last) ...
slip::Array< Type > * calibration_polynomial_coeff_x_
void calibration_polynomial_y(const slip::MultivariatePolynomial< Type, 3 > &calibration_polynomial_y)
Set the image y calibration polynomial equal to calibration_polynomial_x.
This is a point2d class, a specialized version of Point<CoordType,DIM> with DIM = 2...
Definition: Array2d.hpp:132
void calibration_polynomial_coeff_X(RandomAccessIterator first, RandomAccessIterator last)
Set the real world X calibration polynomial coefficient to the range [first,last) ...
slip::Point2d< Type > projection(const slip::Point3d< Type > &p)
Computes the projection of a 3d world point onto the image plane.
Provides some polynomial algorithms.
Numerical MultivariatePolynomial class.
slip::Array< Type > & calibration_polynomial_coeff_X() const
Get the real world X calibration polynomial.
SoloffCamera()
Default constructor of SoloffCamera.
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.
size_type degree() const
Returns the degree of the MultivariatePolynomial.
~SoloffCamera()
Destructor of the SoloffCamera.
slip::MultivariatePolynomial< Type, 3 > & calibration_polynomial_Y()
Get the real world Y calibration polynomial.
iterator end()
Returns a read/write iterator that points one past the last element in the Array. Iteration is done i...
Definition: Array.hpp:1084
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
Definition: copy_ext.hpp:177
Provides a class to manipulate 3d Vector.
friend class boost::serialization::access
Provides an abstract class to model cameras.
void read(const std::string &file)
Read a multivariate polynomial from an ASCII file.
void calibration_polynomial_Y(const slip::MultivariatePolynomial< Type, 3 > &calibration_polynomial_Y)
Set the real world Y calibration polynomial equal to calibration_polynomial_Y.
SoloffCamera(const self &rhs)
Constructs a copy of the SoloffCamera rhs.
slip::Array< Type > * calibration_polynomial_coeff_y_
Provides some input/ouput algorithms.
slip::MultivariatePolynomial< Type, 3 > * calibration_polynomial_Y_
slip::MultivariatePolynomial< Type, 3 > & calibration_polynomial_x() const
Get the image x calibration polynomial.
slip::MultivariatePolynomial< Type, 3 > * calibration_polynomial_x_
Provides a class to manipulate Numerical Matrix.
Provides a class to modelize 2d points.
void read_ascii_2d(Container2d &container, const std::string &file_path_name)
Read a Container2d from an ASCII file.
Definition: io_tools.hpp:544
This is a linear (one-dimensional) dynamic template container. This container statisfies the RandomAc...
Definition: Array.hpp:94
void write(const std::string &file)
Write a multivariate polynomial to an ASCII file.
void calibration_polynomial_coeff_x(RandomAccessIterator first, RandomAccessIterator last)
Set the image x calibration polynomial coefficient to the range [first,last)
Define a SoloffCamera class.
void getpars_SoloffXY(const slip::Matrix< Type > &P, slip::MultivariatePolynomial< Type, 3 > &Pol_x, slip::MultivariatePolynomial< Type, 3 > &Pol_y)
Get calibration parameters using a polynomial fit (computation "by hand")
This is a two-dimensional dynamic and generic container. This container statisfies the Bidirectionnal...
Definition: Array2d.hpp:135
iterator begin()
Returns a read/write iterator that points to the first element in the Vector. Iteration is done in or...
Definition: Vector.hpp:1474
Define an abstract CameraModel class.
Definition: CameraModel.hpp:93
This is a point3d class, a specialized version of Point<CoordType,DIM> with DIM = 3...
void compute(const slip::Matrix< Type > &P)
Computes the parameters of the Soloff camera model.
void all_coeff(RandomAccessIterator first, RandomAccessIterator last) const
Returns all the coefficients of the polynomial including zero ones.