Public Types | Public Member Functions

TRTK::PinholeCameraModel< T > Class Template Reference

A simple pinhole camera model. More...

#include <PinholeCameraModel.hpp>

List of all members.

Public Types

enum  Error { NOT_ENOUGH_INPUT_DATA, UNEQUAL_CARDINALITY_OF_INPUT_SETS, UNKNOWN_ESTIMATION_METHOD, UNKNOWN_ERROR }
enum  Constraints { NO_SKEW, SAME_FOCAL_LENGTHS, SAME_FOCAL_LENGTHS_AND_NO_SKEW }

Public Member Functions

 PinholeCameraModel ()
 Constructor.
virtual ~PinholeCameraModel ()
 Destructor.
Vector3T getCameraPosition () const
 Returns the camera's position in world coordinates.
Matrix3T getCameraOrientation () const
 Returns the camera's orientation in world coordinates.
Matrix4T getExtrinsicParameters () const
 Returns the extrinsic camera parameters (position and orientation) as homogeneous matrix.
Matrix34T getIntrinsicParameters () const
 Returns the intrinsic camera parameters.
Matrix34T getCameraParameters () const
 Returns the projection matrix.
std::tuple< T, T > getFocalLengths () const
 Returns the focal lengths in x- and y-direction.
std::tuple< T, T > getImageCenter () const
 Returns the image center a.k.a. principal point.
getSkew () const
 Returns the skew in the image plane.
void setCameraPosition (const Vector3T &position)
 Set the camera's position in world coordinates.
void setCameraOrientation (const Matrix3T &orientation)
 Set the camera's orientation in world coordinates.
void setExtrinsicParameters (const Matrix4T &parameters)
 Return the extrinsic camera parameters (position and orientation) as homogeneous matrix.
void setIntrinsicParameters (const Matrix34T &parameters)
 Return the intrinsic camera parameters.
void setFocalLengths (T f_x, T f_y)
 Set the focal lengths in x- and y-direction.
void setImageCenter (T c_x, T c_y)
 Set the image center a.k.a. principal point.
void setSkew (T skew)
 Return the skew in the image plane.
Vector2T operator* (const Vector3T &point) const
 Transforms / projects a 3D point onto the image plane.
Vector2T transform (const Vector3T &point) const
 Transforms / projects a 3D point onto the image plane.
estimate (const Range< Vector3T > &points_world, const Range< Vector2T > &points_display)
 Estimates the intrinsic and extrinsic camera parameters from two corresponding point sets.
estimateWithConstraints (const Range< Vector3T > &points_world, const Range< Vector2T > &points_display, Constraints constraints=SAME_FOCAL_LENGTHS_AND_NO_SKEW, bool initialize=true, bool constrained_decomposition=true)
 Estimates the intrinsic and extrinsic camera parameters from two corresponding point sets.

Detailed Description

template<class T>
class TRTK::PinholeCameraModel< T >

A simple pinhole camera model.

Template Parameters:
Tscalar (floating point) type

This class implements a simple pinhole camera model. The model parameters can be set / modified by the user or estimated given a set of corresponding point pairs.

Pinhole camera model.png

Pinhole camera model.

The camera is modeled by a projection matrix \( T_{proj} \) which maps a three-dimensional point \( p \) to the two-dimensional point \( p' = T_{proj} * p \) that lies in the image plane of the camera. The optical properties of the camera are defined by the focal lengths \( f_x \) and \( f_y \), the image center \( (c_x, c_y) \) where the optical axis intersects the image plane, and a parameter \( \tau \) which models the skew of the image plane axes. The camera's pose (i.e., its location and orientation) in world coordinates is described by the mapping \( T_{pose} \) which maps from the world coordinate system to the camera coordinate system. Thus, the overall system is described with the following equation:

\[ p' \sim T_{proj} T_{pose} p \]

Here, the matrix entries are described in more detail:

\[ \begin{pmatrix} x' \\ y' \\ 1 \end{pmatrix} \sim \begin{pmatrix} f_x & \tau & c_x & 0 \\ 0 & f_y & c_y & 0 \\ 0 & 0 & 1 & 0 \end{pmatrix} \begin{pmatrix} r_{11} & r_{12} & r_{13} & t_1 \\ r_{21} & r_{22} & r_{23} & t_2 \\ r_{31} & r_{32} & r_{33} & t_3 \\ 0 & 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix} \]

For more details, please be referred to [1], [2], [3], and [4].

Example:
 #include <iostream>
 #include <iomanip>
 #include <vector>

 #include<Eigen/Core>
 #include<Eigen/StdVector>

 #include <TRTK/Coordinate.hpp>
 #include <TRTK/PinholeCameraModel.hpp>
 #include <TRTK/Tools.hpp>
 #include <TRTK/Transform3D.hpp>


 using namespace Eigen;
 using namespace std;
 using namespace TRTK;
 using namespace TRTK::Tools;

 using Point3D = PinholeCameraModel<double>::Vector3T;
 using Point2D = PinholeCameraModel<double>::Vector2T;


 struct GenerateTestData
 {
     GenerateTestData()
     {
         // Instantiate a pinhole camera model.

         PinholeCameraModel<double> camera_model;

         // Set the intrinsic camera parameters.

         camera_model.setFocalLengths(80, 79);
         camera_model.setImageCenter(250, 251);
         camera_model.setSkew(0.1);

         // Set the extrinsic camera parameters.

         Transform3D<double> T;
         T.rotateAxis(40, Point3D(1, 2, 3), Transform3D<double>::DEGREES);
         T.translate(130, 135, 90);
         camera_model.setExtrinsicParameters(T.getTransformationMatrix());

         // Generate some test data.

         const int number_of_points = 6;

         for (int i = 0; i < number_of_points; ++i) // generate points in the world COS
         {
             auto x = randn(0.0, 30.0);    // in the camera COS
             auto y = randn(0.0, 30.0);    // in the camera COS
             auto z = randn(600.0, 10.0);  // in the camera COS
             Point3D p = T.inverse() * Point3D(x, y, z);  // in the world COS
             points_world.emplace_back(p);
         }

         for (auto const & p_W : points_world) // generate points in the camera COS
         {
             Point2D p_D = camera_model.transform(p_W);
             points_display.push_back(p_D);
         }
     }

     vector<Point3D> points_world;
     vector<Point2D> points_display; // image plane
 };


 int main()
 {

     srand(0);
     GenerateTestData test_data;

     PinholeCameraModel<double> model;
     auto rmse = model.estimate(make_range(test_data.points_world), make_range(test_data.points_display));

     cout << setprecision(4);
     cout << fixed;
     cout << "RMSE: " << rmse << endl << endl;
     cout << "Extrinsic camera parameters: " << endl << model.getExtrinsicParameters() << endl << endl;
     cout << "Intrinsic camera parameters: " << endl << model.getIntrinsicParameters() << endl;

     return 0;
 }
Output:

       RMSE: 0.0000

       Extrinsic camera parameters:
         0.7828  -0.4820   0.3937 130.0000
         0.5488   0.8329  -0.0715 135.0000
        -0.2935   0.2721   0.9164  90.0000
         0.0000   0.0000   0.0000   1.0000

       Intrinsic camera parameters:
        80.0000   0.1000 250.0000   0.0000
         0.0000  79.0000 251.0000   0.0000
         0.0000   0.0000   1.0000   0.0000

       
Note:

The estimateWithConstraints() function is only available if the CPPOPTLIB_FOUND macro is defined. Then, the include directory of the CppOptimizationLibrary must be set appropriately. In CMake you might want to insert the following lines in your CMakeLists.txt file.

       find_path(CPPOPTLIB NAMES cppoptlib cppoptlib-1.0.0)
       if(CPPOPTLIB)
           set(CPPOPTLIB_FOUND 1)
           include_directories(${CPPOPTLIB})
           add_definitions(-DCPPOPTLIB_FOUND)
       endif()
       

The library can be found at https://github.com/PatWie/CppNumericalSolvers .

References:

[1] Hartley and Zisserman, "Multiple view geometry in computer vision", 2003

[2] Szeliski, "Computer Vision - Algorithms and Applications", 2011, Springer

[4] Sutherland, "Three-Dimensional Data Input by Tablet", 1974, IEEE

[3] Tuceryan et al., "Single point active alignment method (SPAAM) for optical see-through HMD calibration for AR", 2000, IEEE

See also:
TRTK::Transform3D
Author:
Christoph Hänisch
Version:
1.1.0
Date:
last changed on 2019-07-02

Definition at line 348 of file PinholeCameraModel.hpp.


Member Enumeration Documentation

template<class T >
enum TRTK::PinholeCameraModel::Constraints
Enumerator:
NO_SKEW 

Constraints w.r.t. the projection matrix.

The parameter tau is assumed to be zero (no skewed image plane).

SAME_FOCAL_LENGTHS 

The focal lengths are assumed to be equal to each other.

SAME_FOCAL_LENGTHS_AND_NO_SKEW 

The focal lengths are assumed to be equal to each other and there is no skewed image plane.

Definition at line 358 of file PinholeCameraModel.hpp.


Member Function Documentation

template<class T >
T TRTK::PinholeCameraModel< T >::estimate ( const Range< Vector3T > &  points_world,
const Range< Vector2T > &  points_display 
)

Estimates the intrinsic and extrinsic camera parameters from two corresponding point sets.

Parameters:
[in]points_world3d points in the world coordinate system.
[in]points_displayCorresponding 2d points in the image plane.

The intrinsic and extrinsic camera parameters are estimated from two corresponding point sets (i.e., the i-th elements of both point sets correspond to each other). It is assumed that the camera is fixed in the world coordinate system (COS) and that the transition from the world COS into the camera COS is described by the pose matrix.

The 2d points \( (x'_i, y'_i)^T \) in points_display are assumed to be normalized:

\[ \begin{pmatrix} x'_i \\ y'_i \end{pmatrix} = \begin{pmatrix} u_i / w_i \\ v_i / w_i \end{pmatrix}, \quad \begin{pmatrix} u_i \\ v_i \\ w_i \end{pmatrix} = T_{proj} T_{pose} \begin{pmatrix} x_i \\ y_i \\ z_i \\ 1 \end{pmatrix} \]

At least 6 corresponding point pairs must be given. The focal lengths are assumed to be positive.

Returns:

If \( f \) describes the above mapping, i.e., \( p' = f(p) \) with \( p' = (x', y')^T \) and \( p = (x, y, z)^T \), then this function returns the root mean square error

\[ rmse = \sqrt{ \frac{1}{N} \sum_{i=1}^N \left\Vert \hat f(p_i) - p'_i \right\Vert^2 } \]

where \( \hat f \) is the function estimate.

Exceptions:
ErrorObjIf the input set sizes do not match, an error object is thrown and its error code is set to UNEQUAL_CARDINALITY_OF_INPUT_SETS.
ErrorObjIf there are not enough point pairs (at least six), an error object is thrown and its error code is set to NOT_ENOUGH_POINTS.

Definition at line 496 of file PinholeCameraModel.hpp.

template<class T >
T TRTK::PinholeCameraModel< T >::estimateWithConstraints ( const Range< Vector3T > &  points_world,
const Range< Vector2T > &  points_display,
Constraints  constraints = SAME_FOCAL_LENGTHS_AND_NO_SKEW,
bool  initialize = true,
bool  constrained_decomposition = true 
)

Estimates the intrinsic and extrinsic camera parameters from two corresponding point sets.

Parameters:
[in]points_world3d points in the world coordinate system.
[in]points_displayCorresponding 2d points in the image plane.
[in]constraintsConstraints with respect to the projection matrix.
[in]initializeSee below for more details.
[in]constrained_decompositionSee below for more details.

This function estimates the intrinsic and extrinsic camera parameters from two corresponding point sets (i.e., the i-th elements of both point sets correspond to each other). The estimation is constrained in such a way that the focal lengths \( f_x \) and \( f_y \) are equal and/or the skew parameter \( \tau \) is zero.

It is assumed that the camera is fixed in the world coordinate system (COS) and that the transition from the world COS into the camera COS is described by the pose matrix. The 2d points \( (x'_i, y'_i)^T \) in points_display are assumed to be normalized:

\[ \begin{pmatrix} x'_i \\ y'_i \end{pmatrix} = \begin{pmatrix} u_i / w_i \\ v_i / w_i \end{pmatrix}, \quad \begin{pmatrix} u_i \\ v_i \\ w_i \end{pmatrix} = T_{proj} T_{pose} \begin{pmatrix} x_i \\ y_i \\ z_i \\ 1 \end{pmatrix} \]

At least 6 corresponding point pairs must be given. The focal lengths are assumed to be positive.

If initialize is set to true, the camera parameters are estimated by calling estimate(). Thereby, the internal parameters are overwritten. If the flag is set to false, the currently set camera parameters are used during the optimization.

The camera parameters are decomposed into the intrinsic and extrinsic camera parameters using the RQ decomposition. Then, these two matrices are modified during the iterative optimization procedure in order to reduce the root mean square error. The user-specified constraints are taken into account during the optimization but not when decomposing the camera parameters. By setting the constrained_decomposition flag to true, the constraints are also taken into account when performing the decomposition. Depending on the nature of the data the one or other may be more advantageous.

Returns:

If \( f \) describes the above mapping, i.e., \( p' = f(p) \) with \( p' = (x', y')^T \) and \( p = (x, y, z)^T \), then this function returns the root mean square error

\[ rmse = \sqrt{ \frac{1}{N} \sum_{i=1}^N \left\Vert \hat f(p_i) - p'_i \right\Vert^2 } \]

where \( \hat f \) is the function estimate.

Exceptions:
ErrorObjIf the input set sizes do not match, an error object is thrown and its error code is set to UNEQUAL_CARDINALITY_OF_INPUT_SETS.
ErrorObjIf there are not enough point pairs (at least six), an error object is thrown and its error code is set to NOT_ENOUGH_POINTS.
Important note

This function is only available if the CPPOPTLIB_FOUND macro is defined. Then, the include directory of the CppOptimizationLibrary must be set appropriately. In CMake you might want to insert the following lines in your CMakeLists.txt file.

       find_path(CPPOPTLIB NAMES cppoptlib cppoptlib-1.0.0)
       if(CPPOPTLIB)
           set(CPPOPTLIB_FOUND 1)
           include_directories(${CPPOPTLIB})
           add_definitions(-DCPPOPTLIB_FOUND)
       endif()
       

The library can be found at https://github.com/PatWie/CppNumericalSolvers .

Definition at line 1117 of file PinholeCameraModel.hpp.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines