Image Component Library (ICL)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Protected Member Functions | Static Private Member Functions | Private Attributes
icl::geom::Camera Class Reference

Camera class. More...

#include <Camera.h>

List of all members.

Classes

struct  NotEnoughDataPointsException
 We need at least 6 Data points in general positions. More...
struct  RenderParams

Public Types

typedef math::FixedMatrix
< icl32f, 3, 3 > 
Mat3x3
 internal typedef

Public Member Functions

utils::Point32f project (const Vec &Xw) const
 Project a world point onto the image plane. Caution: Set last component of world points to 1.
void project (const std::vector< Vec > &Xws, std::vector< utils::Point32f > &dst) const
 Project a vector of world points onto the image plane. Caution: Set last component of world points to 1.
const std::vector
< utils::Point32f
project (const std::vector< Vec > &Xws) const
 Project a vector of world points onto the image plane. Caution: Set last component of world points to 1.
Vec projectGL (const Vec &Xw) const
 Project a world point onto the image plane.
void projectGL (const std::vector< Vec > &Xws, std::vector< Vec > &dst) const
 Project a vector of world points onto the image plane.
const std::vector< VecprojectGL (const std::vector< Vec > &Xws) const
 Project a vector of world points onto the image plane.
ViewRay getViewRay (const utils::Point32f &pixel) const
 Returns a view-ray equation of given pixel location.
std::vector< ViewRaygetViewRays (const std::vector< utils::Point32f > &pixels) const
 returns a list of viewrays corresponding to a given set of pixels
utils::Array2D< ViewRaygetAllViewRays () const
 returns a 2D array of all viewrays
ViewRay getViewRay (const Vec &Xw) const
 Returns a view-ray equation of given point in the world.
Vec estimate3DPosition (const utils::Point32f &pixel, const PlaneEquation &plane) const throw (utils::ICLException)
 returns estimated 3D point for given pixel and plane equation
void setRotation (const Mat3x3 &rot)
 set the norm and up vectors according to the passed rotation matrix
void setRotation (const Vec &rot)
 set norm and up vectors according to the passed yaw, pitch and roll
void setTransformation (const Mat &m)
 sets the camera's rotation and position from given 4x4 homogeneous matrix
Mat getCSTransformationMatrix () const
 get world to image coordinate system transformation matrix
Mat getCSTransformationMatrixGL () const
 get world to image coordinate system transformation matrix
Mat getProjectionMatrix () const
 get projection matrix
Mat getProjectionMatrixGL () const
 get the projection matrix as expected by OpenGL
Mat getViewportMatrixGL () const
math::FixedMatrix< icl32f, 4, 3 > getQMatrix () const
 returns the common 4x3 camera matrix
math::FixedMatrix< icl32f, 3, 4 > getInvQMatrix () const
 returns the inverse QMatrix
void translate (const Vec &d)
 translates the current position vector
std::string toString () const
const std::string & getName () const
const VecgetPosition () const
const VecgetNorm () const
const VecgetUp () const
Vec getHoriz () const
float getFocalLength () const
utils::Point32f getPrincipalPointOffset () const
float getPrincipalPointOffsetX () const
float getPrincipalPointOffsetY () const
float getSamplingResolutionX () const
float getSamplingResolutionY () const
float getSkew () const
const RenderParamsgetRenderParams () const
RenderParamsgetRenderParams ()
void setName (const std::string &name)
void setPosition (const Vec &pos)
void setNorm (const Vec &norm)
 gets automatically normalized
void setUp (const Vec &up)
 gets automatically normalized
void setFocalLength (float value)
void setPrincipalPointOffset (float px, float py)
void setPrincipalPointOffset (const utils::Point32f &p)
void setSamplingResolutionX (float value)
void setSamplingResolutionY (float value)
void setSamplingResolution (float x, float y)
void setSkew (float value)
void setRenderParams (const RenderParams &rp)
void setResolution (const utils::Size &newScreenSize)
 Changes the camera resolution and adapts dependent values.
void setResolution (const utils::Size &newScreenSize, const utils::Point &newPrincipalPointOffset)
 Changes the camera resolution and adapts dependent values.
const utils::SizegetResolution () const
 returns the current chipSize (camera resolution in pixels)

Static Public Member Functions

static Camera createFromProjectionMatrix (const math::FixedMatrix< icl32f, 4, 3 > &Q, float focalLength=1)
 Compute all camera parameters from the 4x3 projection matrix.
static Camera calibrate (std::vector< Vec > Xws, std::vector< utils::Point32f > xis, float focalLength=1) throw (NotEnoughDataPointsException,math::SingularMatrixException)
 Uses the passed world point -- image point references to estimate the projection parameters.
static Camera calibrate_pinv (std::vector< Vec > Xws, std::vector< utils::Point32f > xis, float focalLength=1) throw (NotEnoughDataPointsException,math::SingularMatrixException)
 Uses the passed world point -- image point references to estimate the projection parameters.
static Vec getIntersection (const ViewRay &v, const PlaneEquation &plane) throw (utils::ICLException)
 calculates the intersection point between this view ray and a given plane
static Vec estimate_3D (const std::vector< Camera * > cams, const std::vector< utils::Point32f > &UVs, bool removeInvalidPoints=false) throw (utils::ICLException)
 computes the 3D position of a n view from n cameras
static Vec estimate_3D_svd (const std::vector< Camera * > cams, const std::vector< utils::Point32f > &UVs)
 multiview 3D point estimation using svd-based linear optimization (should not be used)

Static Protected Member Functions

static Mat createTransformationMatrix (const Vec &norm, const Vec &up, const Vec &pos)

Static Private Member Functions

static void checkAndFixPoints (std::vector< Vec > &worldPoints, std::vector< utils::Point32f > &imagePoints) throw (NotEnoughDataPointsException)
 internally used utility function
static void load_camera_from_stream (std::istream &is, const std::string &prefix, Camera &cam)
 intenal helper function

Private Attributes

std::string m_name
 name of the camera (visualized in the scene if set)
Vec m_pos
 center position vector
Vec m_norm
 normal vector of image plane
Vec m_up
 vector pointing to pos. y axis on image plane
float m_f
 focal length
float m_px
float m_py
 principal point offset
float m_mx
float m_my
 sampling resolution
float m_skew
 skew parameter in the camera projection, should be zero
RenderParams m_renderParams

constructors

 Camera (const Vec &pos=Vec(0, 0, 10, 1), const Vec &norm=Vec(0, 0,-1, 1), const Vec &up=Vec(1, 0, 0, 1), float f=3, const utils::Point32f &principalPointOffset=utils::Point32f(320, 240), float sampling_res_x=200, float sampling_res_y=200, float skew=0, const RenderParams &renderParams=RenderParams())
 basic constructor that gets all possible parameters
 Camera (const std::string &filename, const std::string &prefix="config.") throw (utils::ParseException)
 loads a camera from given file
 Camera (std::istream &configDataStream, const std::string &prefix="config.") throw (utils::ParseException)
 loads a camera from given input stream

Detailed Description

Camera class.

This camera class implements a model of a central projection camera with finite focal length. It is very general and can be applied to most cameras, e.g. CCD cameras. Because it assumes a linear projection, any distortion in the camera image should be corrected before using it in this class.

The Camera Model

The camera model was explicitly designed close to the camera model that is used in OpenGL. It is described by a set of extrinsic and intrinsic parameters:

The Intrinsic camera parameters are used to create the camera's projection matrix P

\[ P = \left(\begin{array}{cccc} fm_x & s & p_x & 0 \\ 0 & f m_y & p_y & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \end{array}\right) \]

Please note, that OpenGL's definition of the projection matrix looks different. OpenGL uses a flipped y-axis, and it's definition of projection also contains entries in the 3rd row. In our case, z values are not needed after the projection.

The cameras coordinate system transformation matrix C is defined by:

\[ C = \left(\begin{array}{cc} h^T & -h^T p \\ u^T & -u^T p \\ n^T & -n^T p \\ (0,0,0) & 1 \\ \end{array}\right) \]

Together, P and C are used to describe the projection model of the camera. A 3D utils::Point pw in the world is projected to the camera screen ps by

\[ p_s' = homogenize(P C p_w) \]

ps contains just the first two components of p's. The homogenized operation devided a homogeneous 3D vector by it's 4th component.

In literature, sometimes are simgle 3x4 camera matrix is used. We call this matrix the camera's Q-matrix. The matrix contains all information that is neccessary for creating a camera. Usually, it can be decomposed into P and C using QR-decomposition. The icl::Camera class provides function to directly obtain a camera's Q-matrix. Q is defined by the first two and the last row of the matrix product P C.

Camera Calibration

Valid camera instances can either be set up manually, or they can be created by camera calibration. ICL uses a quite simple yet very powerful calibration technique, which needs a set of at least 8 non-coplanar world points and their corresponding image coordinates. ICL features an easy to use camera calibration tool, which is discribed on ICL's website.


Member Typedef Documentation

internal typedef


Constructor & Destructor Documentation

icl::geom::Camera::Camera ( const Vec pos = Vec(0,0,10,1),
const Vec norm = Vec(0,0,-1,1),
const Vec up = Vec(1,0,0,1),
float  f = 3,
const utils::Point32f principalPointOffset = utils::Point32f(320,240),
float  sampling_res_x = 200,
float  sampling_res_y = 200,
float  skew = 0,
const RenderParams renderParams = RenderParams() 
) [inline]

basic constructor that gets all possible parameters

icl::geom::Camera::Camera ( const std::string &  filename,
const std::string &  prefix = "config." 
) throw (utils::ParseException)

loads a camera from given file

Parameters:
filenamefile name of valid configuration file (in ICL's ConfigFile core::format)
prefixvalid prefix that determines wheret to find the camera within the given config file (note, that this prefix must end with '.')
icl::geom::Camera::Camera ( std::istream &  configDataStream,
const std::string &  prefix = "config." 
) throw (utils::ParseException)

loads a camera from given input stream

Parameters:
configDataStreamstream object to read and interpret input file name of valid configuration file (in ICL's ConfigFile core::format)
prefixvalid prefix that determines where to find the camera within the given config file (note, that this prefix must end with '.')

Member Function Documentation

static Camera icl::geom::Camera::calibrate ( std::vector< Vec Xws,
std::vector< utils::Point32f xis,
float  focalLength = 1 
) throw (NotEnoughDataPointsException,math::SingularMatrixException) [static]

Uses the passed world point -- image point references to estimate the projection parameters.

At least 6 data points references are needed. It is not possible to estimate the focal length f directly, but only the products f*m_x and f*m_y (which is sufficient for defining the projection). Therefore an arbitrary value for f != 0 may be passed to the function. The method minimizes the algebraic error with the direct linear transform algorithm in which a SVD is used. If IPP is not available, this function uses calibrate_pinv(std::vector<Vec>,std::vector<utils::Point32f>,float)

static Camera icl::geom::Camera::calibrate_pinv ( std::vector< Vec Xws,
std::vector< utils::Point32f xis,
float  focalLength = 1 
) throw (NotEnoughDataPointsException,math::SingularMatrixException) [static]

Uses the passed world point -- image point references to estimate the projection parameters.

Same as the method calibrate, but using a pseudoinvers instead of the SVD for the estimation. This method is less stable and less exact.

static void icl::geom::Camera::checkAndFixPoints ( std::vector< Vec > &  worldPoints,
std::vector< utils::Point32f > &  imagePoints 
) throw (NotEnoughDataPointsException) [static, private]

internally used utility function

static Camera icl::geom::Camera::createFromProjectionMatrix ( const math::FixedMatrix< icl32f, 4, 3 > &  Q,
float  focalLength = 1 
) [static]

Compute all camera parameters from the 4x3 projection matrix.

static Mat icl::geom::Camera::createTransformationMatrix ( const Vec norm,
const Vec up,
const Vec pos 
) [static, protected]
Vec icl::geom::Camera::estimate3DPosition ( const utils::Point32f pixel,
const PlaneEquation plane 
) const throw (utils::ICLException)

returns estimated 3D point for given pixel and plane equation

static Vec icl::geom::Camera::estimate_3D ( const std::vector< Camera * >  cams,
const std::vector< utils::Point32f > &  UVs,
bool  removeInvalidPoints = false 
) throw (utils::ICLException) [static]

computes the 3D position of a n view from n cameras

Parameters:
camslist of cameras
UVslist of image points (in image coordinates)
removeInvalidPointsif this flag is set to true, all given points are checked to be within the cameras viewport. If not, these points are removed internally.

Method:

This function uses a standard linear approach using a pseudo-inverse to solve the problem in a "least-square"-manner:

The camera is essentially represented by the 3x4-Q-Matrix, which can be obtained using icl::Camera::getQMatrix() const. Q is defined as follows:

                      | -- x --  tx |
          Q = [R|t] = | -- y --  ty |
                      | -- z --  tz |
          

The camera projection is trivial now. For a given projected point [u,v]' (in image coordinates) and a position in the world Pw (homogeneous):

          [u,v,1*]' = hom( Q Pw )
          

Where '1*' becomes a real 1.0 just because of the homogenization step using hom(). Component-wise, this can be re-written as:

          u  = x Pw + tx
          v  = y Pw + ty
          1* = z Pw + tz
          

In order to ensure, '1*' becomes a real 1.0, the upper two equations have to be devided by (z Pw + tz), which provides us the following two equations:

          u = (x Pw + tx) / (z Pw + tz)
          v = (y Pw + ty) / (z Pw + tz)
          

These equations have to be reorganized so that Pw can be factored out:

          (u z - x) Pw = tx - u tz
          (v z - y) Pw = ty - v tz
          

Now we can write this in matrix notation again:

          A Pw = B      ,where
          A = | u z - x |
              | v z - y |
          B = | tx - u tz |
              | ty - v tz |
          

The obviously under-determined equation-system above uses only a single camera. If we put the results from several views together into a single equation system, it becomes unambigoulsly solvable using a pseudo-inverse approach:

          | A1 |      | B1 |             | A1 |+ | B1 |
          | A2 | Pw = | B2 |    => Pw =  | A2 |  | B2 |
          |....|      |....|             |....|  |....|
          

where 'A+' means the pseudo-inverse of A

static Vec icl::geom::Camera::estimate_3D_svd ( const std::vector< Camera * >  cams,
const std::vector< utils::Point32f > &  UVs 
) [static]

multiview 3D point estimation using svd-based linear optimization (should not be used)

This functions seems to provide false results for more than 2 views: use estimate_3D instead

returns a 2D array of all viewrays

This method is much faster than using getViewRay several times since the projection matrix inversion that is necessary must only be done once

get world to image coordinate system transformation matrix

get world to image coordinate system transformation matrix

float icl::geom::Camera::getFocalLength ( ) const [inline]
Vec icl::geom::Camera::getHoriz ( ) const [inline]
static Vec icl::geom::Camera::getIntersection ( const ViewRay v,
const PlaneEquation plane 
) throw (utils::ICLException) [static]

calculates the intersection point between this view ray and a given plane

Throws an utils::ICLException in case of parallel plane and line A ViewRay is defined by $V: \mbox{offset} + \lambda \cdot \mbox{direction} $ A Plane is given by $ P: < (X - \mbox{planeOffset}), \mbox{planeNormal}> = 0 $ Intersection is described by $<(\mbox{offset} + \lambda \cdot \mbox{direction}) - \mbox{planeOffset},planeNormal> = 0$ which yields:

\[ \lambda = - \frac{<\mbox{offset}-\mbox{planeOffset},\mbox{planeNormal}>}{<\mbox{direction},\mbox{planeNormal}>} \]

and .. obviously, we get no intersection if direction is parallel to planeNormal

returns the inverse QMatrix

const std::string& icl::geom::Camera::getName ( ) const [inline]
const Vec& icl::geom::Camera::getNorm ( ) const [inline]
const Vec& icl::geom::Camera::getPosition ( ) const [inline]

get projection matrix

get the projection matrix as expected by OpenGL

returns the common 4x3 camera matrix

const utils::Size& icl::geom::Camera::getResolution ( ) const [inline]

returns the current chipSize (camera resolution in pixels)

float icl::geom::Camera::getSkew ( ) const [inline]
const Vec& icl::geom::Camera::getUp ( ) const [inline]

Returns a view-ray equation of given pixel location.

ViewRay icl::geom::Camera::getViewRay ( const Vec Xw) const

Returns a view-ray equation of given point in the world.

std::vector<ViewRay> icl::geom::Camera::getViewRays ( const std::vector< utils::Point32f > &  pixels) const

returns a list of viewrays corresponding to a given set of pixels

This method is much faster than using getViewRay several times since the projection matrix inversion that is necessary must only be done once

static void icl::geom::Camera::load_camera_from_stream ( std::istream &  is,
const std::string &  prefix,
Camera cam 
) [static, private]

intenal helper function

Project a world point onto the image plane. Caution: Set last component of world points to 1.

void icl::geom::Camera::project ( const std::vector< Vec > &  Xws,
std::vector< utils::Point32f > &  dst 
) const

Project a vector of world points onto the image plane. Caution: Set last component of world points to 1.

const std::vector<utils::Point32f> icl::geom::Camera::project ( const std::vector< Vec > &  Xws) const

Project a vector of world points onto the image plane. Caution: Set last component of world points to 1.

Vec icl::geom::Camera::projectGL ( const Vec Xw) const

Project a world point onto the image plane.

void icl::geom::Camera::projectGL ( const std::vector< Vec > &  Xws,
std::vector< Vec > &  dst 
) const

Project a vector of world points onto the image plane.

const std::vector<Vec> icl::geom::Camera::projectGL ( const std::vector< Vec > &  Xws) const

Project a vector of world points onto the image plane.

void icl::geom::Camera::setFocalLength ( float  value) [inline]
void icl::geom::Camera::setName ( const std::string &  name) [inline]
void icl::geom::Camera::setNorm ( const Vec norm) [inline]

gets automatically normalized

void icl::geom::Camera::setPosition ( const Vec pos) [inline]
void icl::geom::Camera::setPrincipalPointOffset ( float  px,
float  py 
) [inline]
void icl::geom::Camera::setRenderParams ( const RenderParams rp) [inline]
void icl::geom::Camera::setResolution ( const utils::Size newScreenSize)

Changes the camera resolution and adapts dependent values.

Internally, this function also adapts the render parameters chipSize and viewport Furthermore, the prinizipal-point-offset is automatically set to the center of the new screen

void icl::geom::Camera::setResolution ( const utils::Size newScreenSize,
const utils::Point newPrincipalPointOffset 
)

Changes the camera resolution and adapts dependent values.

Internally, this function also adapts the render parameters chipSize and viewport Furthermore, the prinizipal-point-offset is set to the new given value

void icl::geom::Camera::setRotation ( const Mat3x3 rot)

set the norm and up vectors according to the passed rotation matrix

void icl::geom::Camera::setRotation ( const Vec rot)

set norm and up vectors according to the passed yaw, pitch and roll

void icl::geom::Camera::setSamplingResolution ( float  x,
float  y 
) [inline]
void icl::geom::Camera::setSamplingResolutionX ( float  value) [inline]
void icl::geom::Camera::setSamplingResolutionY ( float  value) [inline]
void icl::geom::Camera::setSkew ( float  value) [inline]

sets the camera's rotation and position from given 4x4 homogeneous matrix

void icl::geom::Camera::setUp ( const Vec up) [inline]

gets automatically normalized

std::string icl::geom::Camera::toString ( ) const
void icl::geom::Camera::translate ( const Vec d) [inline]

translates the current position vector


Member Data Documentation

float icl::geom::Camera::m_f [private]

focal length

float icl::geom::Camera::m_mx [private]
float icl::geom::Camera::m_my [private]

sampling resolution

std::string icl::geom::Camera::m_name [private]

name of the camera (visualized in the scene if set)

normal vector of image plane

center position vector

float icl::geom::Camera::m_px [private]
float icl::geom::Camera::m_py [private]

principal point offset

float icl::geom::Camera::m_skew [private]

skew parameter in the camera projection, should be zero

vector pointing to pos. y axis on image plane


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