Follow this link to skip to the main content

claraty::Tsai_Camera_Model Class Reference
[Data Structure]

#include <tsai_camera_model.h>

Inheritance diagram for claraty::Tsai_Camera_Model:

Inheritance graph
[legend]
Collaboration diagram for claraty::Tsai_Camera_Model:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 Tsai_Camera_Model ()
 Tsai_Camera_Model (int width, int height, const float *projection_matrix, const float *distortion_vector, Frame *frame)
Camera_Modelclone () const
 ~Tsai_Camera_Model ()
void ray_to_pixel (const Ray &vector, Pixel_Coord &pixel_coord) const
void pixel_to_ray (const Pixel_Coord &pixel_coord, Ray &vector) const
bool map_model (Camera_Model &mapped_model, Map_Op &map_op) const
Pixel_Coord get_mapped_coordinates (Pixel_Coord unmapped_coord) const
Pixel_Coord get_unmapped_coordinates (Pixel_Coord mapped_coord) const
void set_distortion_parameters (const Vector< float > &d)
void set_intrinsic_parameters (const Matrix< float > &p)
const Vector< float > & get_distortion_parameters () const
const Matrix< float > & get_intrinsic_parameters () const
void subsample (int subsampleFactor)
std::string get_typename () const
bool io (FDM_Map m)
void read (std::istream &str)
void write (std::ostream &str) const
bool operator== (const Tsai_Camera_Model &rhs) const
bool operator== (const Camera_Model &rhs) const
void set_frame (Frame *f)
void set_name (const std::string &new_name)
virtual const Frameget_frame () const
const std::string & get_name () const

Static Public Member Functions

static Camera_Modelbuild ()
static Camera_Modelbuild_from_file (const char *filename)
static Camera_Modelbuild_from_stream (std::istream &stream)
static Camera_Modelbuild_from_typename (const std::string type_name)

Static Public Attributes

static Factory< Camera_Model,
std::string > * 
factory

Protected Attributes

Frame_mounting_frame
std::string _name

Private Attributes

int _image_width
int _image_height
bool _distorted
Vector< float > _distortion
Matrix< float > _intrinsic

Detailed Description

The extrinsic parameters are implicitly contained in the frame inherited from the base class. The camera pointing vector is the frame's z unit vector, and the image plane is aligned such that the positive x-pixel direction (normal to the pointing vector) is the frame's x vector, and the positive y-pixel direction is the frame's y vector. Internally the matrix is represented in the canonical form, as

[ fx 0 cx ]
A= [ 0 fy cy ]
[ 0 0 1 ]

with fx, fy the focal length of the system (in horizontal and vertical pixels), and (cx, cy) the pixel coordinates of the central pixel (through the center of projection). When projecting a real-world point of (x, y, z), then, we have to do:

[ row ] [ x ]
p = [ col ] = A * [ y ]
[ w ] [ z ]

p is then in homogeneous coordinates, so the w has to be divided out.

Definition at line 69 of file tsai_camera_model.h.


Constructor & Destructor Documentation

claraty::Tsai_Camera_Model::Tsai_Camera_Model (  ) 

Definition at line 55 of file tsai_camera_model.cc.

Referenced by clone().

00056   : _image_width  (0),
00057     _image_height (0),
00058     _distorted(false),
00059     _distortion(4, 0.0F),
00060     _intrinsic (3, IDENTITY)
00061 {
00062 }

claraty::Tsai_Camera_Model::Tsai_Camera_Model ( int  width,
int  height,
const float *  projection_matrix,
const float *  distortion_vector,
Frame frame 
)

Definition at line 66 of file tsai_camera_model.cc.

References _distorted, and _distortion.

00070   : Camera_Model (frame),
00071     _image_width    (width), 
00072     _image_height   (height),
00073     _distorted      (false),
00074     _distortion     (4, distortion_vector), 
00075     _intrinsic      (3, 3, projection_matrix)
00076 {
00077   for (int i = 0; i < 4 && !_distorted; i++)
00078     if (_distortion(i) != 0)
00079       _distorted = true;
00080 }

claraty::Tsai_Camera_Model::~Tsai_Camera_Model (  )  [inline]

Definition at line 87 of file tsai_camera_model.h.

00087 { }


Member Function Documentation

Camera_Model* claraty::Tsai_Camera_Model::clone (  )  const [inline, virtual]

Implements claraty::Camera_Model.

Definition at line 85 of file tsai_camera_model.h.

References Tsai_Camera_Model().

00085 { return new Tsai_Camera_Model(*this); }

Here is the call graph for this function:

static Camera_Model* claraty::Tsai_Camera_Model::build (  )  [inline, static]

Definition at line 89 of file tsai_camera_model.h.

00089 { return new Tsai_Camera_Model; }

void claraty::Tsai_Camera_Model::ray_to_pixel ( const Ray vector,
Pixel_Coord pixel_coord 
) const [virtual]

Computes the 2D pixel location in the image from a 3D ray described by the pointing 'vector' with respect to the model's coordinate frame

Implements claraty::Camera_Model.

Definition at line 94 of file tsai_camera_model.cc.

References _distorted, _intrinsic, get_unmapped_coordinates(), and claraty::N_2D_Point< T >::set().

00096 {
00097   Ray projection = _intrinsic * pointing_direction;
00098 
00099   float c = projection(0) / projection(2);
00100   float r = projection(1) / projection(2);
00101 
00102   pixel.set(c, r);
00103  
00104   if (_distorted) pixel = get_unmapped_coordinates(pixel);
00105 }

Here is the call graph for this function:

void claraty::Tsai_Camera_Model::pixel_to_ray ( const Pixel_Coord pixel,
Ray pointing_direction 
) const [virtual]

This assumes that the camera model is situated in a frame with the origin at the center of projection, and that the frame is oriented with the z-axis pointing along the optical axis, the x-axis parallel to the x-pixel-axis, and the y-axis parallel to the y-pixel-axis.

Implements claraty::Camera_Model.

Definition at line 116 of file tsai_camera_model.cc.

References _distorted, _intrinsic, get_mapped_coordinates(), claraty::N_2D_Point< T >::get_x(), and claraty::N_2D_Point< T >::get_y().

00118 { 
00119   Pixel_Coord mapped_pixel;
00120   if (_distorted)  // if distorted, find the undistorted / mapped coordinates
00121     mapped_pixel = get_mapped_coordinates(pixel);
00122   else
00123     mapped_pixel = pixel;
00124 
00125   float fx = _intrinsic(0, 0);  // focal length in x-pixels
00126   float fy = _intrinsic(1, 1);  // focal length in y-pixels
00127   float cx = _intrinsic(0, 2);  // principal point x coordinate
00128   float cy = _intrinsic(1, 2);  // principal point y coordinate
00129 
00130   Ray & vec = pointing_direction;
00131 
00132   float rx = mapped_pixel.get_x(), ry = mapped_pixel.get_y();
00133 
00134   vec(0) = (mapped_pixel(0) - cx) / fx;
00135   vec(1) = (mapped_pixel(1) - cy) / fy;
00136   vec(2) = 1.0;
00137   vec /= sqrt(vec(0) * vec(0) + vec(1) * vec(1) + 1); // normalize
00138 }

Here is the call graph for this function:

bool claraty::Tsai_Camera_Model::map_model ( Camera_Model mapped_model,
Map_Op &  map_op 
) const [virtual]

This function provides a way for the user to correct models and images for lens distortion. Subclasses should do the right thing to ensure that a reasonable new camera model is built and returned in the mapped_model argument. This should return true if it's possible to build a processed model and mapping op for this model, and false otherwise. Pretty much all subclasses should have a function here that returns true.

Parameters:
[in] mapped_model The linearized model.
[in] map_op The rectified map.
Returns:
False under all input conditions.

Reimplemented from claraty::Camera_Model.

Definition at line 144 of file tsai_camera_model.cc.

00146 {
00147 /*  rectify.set_camera_model(*this);
00148   Tsai_Camera_Model *cmm = new Tsai_Camera_Model(*this);
00149   Vector<float> no_distortion(4, 0.0);
00150   cmm->set_distortion_parameters(no_distortion);
00151   linearized_model = cmm;
00152 */  return true;
00153 }

Pixel_Coord claraty::Tsai_Camera_Model::get_mapped_coordinates ( Pixel_Coord  unmapped_coord  )  const [virtual]

Inverse operation of the above function. This probably needs to be solved numerically.

Reimplemented from claraty::Camera_Model.

Definition at line 251 of file tsai_camera_model.cc.

References AT_FUNCTION, and claraty::ND_Function_Minimizer::minimize().

Referenced by pixel_to_ray().

00252 {
00253   double scales  [2] = {0.1, 0.1};
00254   double solution[2] = {unmapped_coord(0), unmapped_coord(1)};
00255 
00256   Mapped_Pixel_Evaluator eval(*this, unmapped_coord);
00257   ND_Function_Minimizer  nmm;
00258 
00259   int num_steps = nmm.minimize(solution, scales, 0.001, eval, 2, 100);
00260   if (num_steps == 0)
00261     cerr << AT_FUNCTION << "get_undistorted_coordinates failed to converge "
00262          << unmapped_coord <<" -> " << solution[0] << ", "
00263          << solution[1] << ")" << endl;
00264   return Pixel_Coord(solution[0], solution[1]);
00265 }

Here is the call graph for this function:

Pixel_Coord claraty::Tsai_Camera_Model::get_unmapped_coordinates ( Pixel_Coord  mapped_coord  )  const [virtual]

Most camera models deal with lens distortion by mapping raw images that contain lens distortion to some form of "ideal" images that filter out this distortion. This function maps coordinates from the processed (linearized) image back to the original raw image. For mapping between processed and raw images, subclasses should override this function. Default implementation models no distortion at all. This function provides the inverse mapping of the above function. Lens distortion models are often difficult to invert, and must be inverted numerically. So typically one of these two functions is going significantly more expensive to call than the other. Map_Op assumes that the previous function is low-cost; subclasses should document complexity of both.

Parameters:
[in] mapped_coord The (x,y) coordinates of the pixel in the mapped image.
Returns:
The (x,y) pixel coordinates of the original raw (or unrectified) image.

Reimplemented from claraty::Camera_Model.

Definition at line 178 of file tsai_camera_model.cc.

References _distortion, and _intrinsic.

Referenced by claraty::Mapped_Pixel_Evaluator::operator()(), and ray_to_pixel().

00179 {
00180   // Algorithm from OpenCV.  This is used to create the LUT for rectification,
00181   // for example by Rectify_Op
00182   
00183   // The equations which produce these are:
00184   // (u, v) = mapped coordinates
00185   // (u', v') = unmapped (raw) coordinates
00186   // (x, y) = object coordinates of projected point
00187   // r2 = x * x + y * y   -- square of distance from object to primary vector
00188   // k1, k2 are radial distortion parameters; p1, p2 are tangential distortion
00189   // parameters. principal point is at (cx, cy).
00190 
00191   // u' = u + (u - cx) * (k1 * r2 + k2 * r4 + 2 * p1 * y + p2 * (r2/x + 2x))
00192   // v' = v + (v - cy) * (k1 * r2 + k2 * r4 + 2 * p2 * x + p1 * (r2/y + 2y))
00193 
00194   // k1 is distortion(0)
00195   // k2 is distortion(1)
00196   // p1 is distortion(2)
00197   // p2 is distortion(3)
00198   float rx = mapped_coord(0), ry = mapped_coord(1);
00199 
00200   float du = rx - _intrinsic(0, 2);
00201   float dv = ry - _intrinsic(1, 2);
00202 
00203   float x = du / _intrinsic(0, 0);  // find (x, y) using similar triangles;
00204   float y = dv / _intrinsic(1, 1);  // assumed z=1.
00205 
00206   float x1 = _distortion(3) / x;
00207   float y1 = _distortion(2) / y;
00208   
00209   float r2 = x * x + y * y;
00210 
00211   float x3 = 2.0 * _distortion(3) * x;
00212   float y3 = 2.0 * _distortion(2) * y;
00213 
00214   float bx = r2 * (_distortion(0) + r2 * _distortion(1)) + x3 + y3;
00215   float by = bx + r2 * y1;
00216   bx += r2 * x1;
00217 
00218   float dx = rx + bx * du;
00219   float dy = ry + by * dv;
00220   return Pixel_Coord(dx,dy);
00221 }

void claraty::Tsai_Camera_Model::set_distortion_parameters ( const Vector< float > &  d  ) 

Definition at line 271 of file tsai_camera_model.cc.

References _distorted, and _distortion.

00272 {
00273   _distortion = d;
00274   _distorted = false;
00275   if (_distortion != 0) _distorted = true;
00276 }

void claraty::Tsai_Camera_Model::set_intrinsic_parameters ( const Matrix< float > &  p  ) 

Definition at line 282 of file tsai_camera_model.cc.

References _intrinsic.

00283 {
00284   _intrinsic = p;
00285 }

const Vector< float > & claraty::Tsai_Camera_Model::get_distortion_parameters (  )  const

Definition at line 291 of file tsai_camera_model.cc.

References _distortion.

00292 {
00293   return _distortion;
00294 }

const Matrix< float > & claraty::Tsai_Camera_Model::get_intrinsic_parameters (  )  const

Definition at line 300 of file tsai_camera_model.cc.

References _intrinsic.

00301 {
00302   return _intrinsic;
00303 }

void claraty::Tsai_Camera_Model::subsample ( int  subsampleFactor  )  [virtual]

Subsample the internal model so that the ray-to-pixel and pixel-to-ray functions work on images subsampled by the same amount. This way image algorithms can work with subsampled images and still have correct camera models to work with. The subsample_factor is a factor; images are sampled to 1/factor, so a factor of 3 means 1/3 the image height & width. Default behavior is to print a warning message and return.

Reimplemented from claraty::Camera_Model.

Definition at line 309 of file tsai_camera_model.cc.

References _distorted, _image_height, _image_width, _intrinsic, and AT_FUNCTION.

00310 {
00311   if (_distorted) {
00312     cerr << AT_FUNCTION << "unable to subsample camera models with non-linear"
00313          << " distortion" << endl;
00314     return;
00315   }
00316 
00317   _intrinsic    /= subsampleFactor;
00318   _image_width  /= subsampleFactor;
00319   _image_height /= subsampleFactor;
00320 }

std::string claraty::Tsai_Camera_Model::get_typename (  )  const [inline, virtual]

Implements claraty::Camera_Model.

Definition at line 112 of file tsai_camera_model.h.

00112 { return "Tsai_Camera_Model"; }

bool claraty::Tsai_Camera_Model::io ( FDM_Map  m  )  [virtual]

Serializes a camera model.

Parameters:
[in] m A map that holds the content of a serialized camera model

Reimplemented from claraty::Camera_Model.

Definition at line 344 of file tsai_camera_model.cc.

References _distorted, _distortion, _intrinsic, claraty::N_2D_Array< T >::begin(), claraty::FDM_Map::field(), claraty::Camera_Model::io(), claraty::FDM_Map::is_read(), and claraty::FDM_Map::peekfield().

00345 {
00346   bool ok = Camera_Model::io(m);
00347 
00348   const unsigned int latest_version = 2;
00349   unsigned int thisVersion = latest_version;
00350   if (m.is_read() && !m.peekfield("version", thisVersion)) {
00351     // legacy input. We don't write this format anymore, and we never wrote
00352     // it except for in ascii format, so we have to manually parse it here
00353     std::string distString, matrixString;
00354 
00355     ok &= m.field("distortion", distString);
00356     ok &= m.field("matrix", matrixString);
00357     
00358     std::istringstream dist(distString);
00359 
00360     for (int i = 0; i < 4; i++)
00361       dist >> _distortion(i);
00362 
00363     std::istringstream mat(matrixString);
00364     Matrix<float>::iterator it = _intrinsic.begin();
00365     for (int i = 0; i < 9; i++, ++it)
00366       mat >> *it;
00367 
00368     return ok;
00369   }
00370 
00371   ok &= m.field("version", thisVersion);
00372   ok &= m.field("distortion", _distortion);
00373   ok &= m.field("matrix", _intrinsic);
00374 
00375   if (m.is_read()) {
00376     _distorted = false;
00377     for (int i = 0; i < 4 && !_distorted; i++)
00378       if (_distortion(i) != 0)
00379         _distorted = true;
00380   }
00381   return ok;
00382 }

Here is the call graph for this function:

void claraty::Tsai_Camera_Model::read ( std::istream &  str  )  [virtual]

Reimplemented from claraty::Camera_Model.

void claraty::Tsai_Camera_Model::write ( std::ostream &  str  )  const [virtual]

Reimplemented from claraty::Camera_Model.

bool claraty::Tsai_Camera_Model::operator== ( const Tsai_Camera_Model rhs  )  const [inline]

Definition at line 119 of file tsai_camera_model.h.

References _distortion, _intrinsic, and claraty::operator==().

00119                                                       {
00120     return Camera_Model::operator==(rhs) &&
00121       _distortion == rhs._distortion &&
00122       _intrinsic  == rhs._intrinsic;
00123   }

Here is the call graph for this function:

bool claraty::Camera_Model::operator== ( const Camera_Model rhs  )  const [inherited]

Definition at line 74 of file camera_model.cc.

References claraty::Camera_Model::_mounting_frame, and claraty::Camera_Model::_name.

00075 {
00076   return _mounting_frame == rhs._mounting_frame && _name == rhs._name;
00077 }

void claraty::Camera_Model::set_frame ( Frame f  )  [inherited]

Assign frame to the camera model

Parameters:
[in] f The frame coordinate transformation that defines the mounting of the camera relative to other coordinate frames

Definition at line 99 of file camera_model.cc.

References claraty::Camera_Model::_mounting_frame.

00100 { 
00101   _mounting_frame = f; 
00102 }

void claraty::Camera_Model::set_name ( const std::string &  new_name  )  [inline, inherited]

Definition at line 94 of file camera_model.h.

References claraty::Camera_Model::_name.

00094 { _name = new_name; }

virtual const Frame& claraty::Camera_Model::get_frame (  )  const [inline, virtual, inherited]

Definition at line 96 of file camera_model.h.

References claraty::Camera_Model::_mounting_frame.

Referenced by claraty::Stereovision::compute_point_image().

00096 { return *_mounting_frame; }

const std::string& claraty::Camera_Model::get_name (  )  const [inline, inherited]

Definition at line 97 of file camera_model.h.

References claraty::Camera_Model::_name.

00097 { return _name; }

Camera_Model * claraty::Camera_Model::build_from_file ( const char *  filename  )  [static, inherited]

These are factory wrappers, which load a (subclass of) camera_model from disk. Subclasses have to implement hooks to tie into the factory at startup time.

Definition at line 251 of file camera_model.cc.

References AT_FUNCTION, and claraty::Camera_Model::build_from_stream().

00252 {
00253   ifstream stream(filename);
00254   if (!stream) {
00255     cerr << AT_FUNCTION << " : unable to open file " << filename 
00256          << " for reading camera model" << endl;
00257     return NULL;
00258   }
00259   return build_from_stream(stream);
00260 }

Here is the call graph for this function:

static Camera_Model* claraty::Camera_Model::build_from_stream ( std::istream &  stream  )  [static, inherited]

static Camera_Model* claraty::Camera_Model::build_from_typename ( const std::string  type_name  )  [inline, static, inherited]

Definition at line 137 of file camera_model.h.

References claraty::Camera_Model::factory.

Referenced by claraty::io_object().

00137                                                                        {
00138     return (*factory)(type_name); 
00139   }


Member Data Documentation

Definition at line 72 of file tsai_camera_model.h.

Referenced by subsample().

Definition at line 73 of file tsai_camera_model.h.

Referenced by subsample().

Factory< Camera_Model, string > * claraty::Camera_Model::factory [static, inherited]

Definition at line 80 of file camera_model.h.

Referenced by claraty::Camera_Model::build_from_typename().


The documentation for this class was generated from the following files: