contrib/gel/mrc/vpgl/vpgl_perspective_camera.h
Go to the documentation of this file.
00001 // This is gel/mrc/vpgl/vpgl_perspective_camera.h
00002 #ifndef vpgl_perspective_camera_h_
00003 #define vpgl_perspective_camera_h_
00004 //:
00005 // \file
00006 // \brief A class for the perspective camera model.
00007 // \author Thomas Pollard
00008 // \date Jan 28, 2005
00009 // \author Joseph Mundy, Matt Leotta, Vishal Jain
00010 //
00011 // \verbatim
00012 //  Modifications
00013 //   May 08, 2005  Ricardo Fabbri   Added binary I/O support
00014 //   May 08, 2005  Ricardo Fabbri   Added == operator
00015 //   Feb  8, 2007  Thomas Pollard   Added finite backproject method.
00016 //   Mar 16, 2007  Matt Leotta      Replaced vgl_h_matrix_3d with vgl_rotation_3d for rotation
00017 // \endverbatim
00018 
00019 #include <vnl/vnl_fwd.h>
00020 #include <vgl/vgl_fwd.h>
00021 #include <vgl/vgl_point_3d.h>
00022 #include <vgl/vgl_homg_point_3d.h>
00023 #include <vgl/algo/vgl_rotation_3d.h>
00024 #include <vcl_iosfwd.h>
00025 
00026 #include "vpgl_proj_camera.h"
00027 #include "vpgl_calibration_matrix.h"
00028 #include <vsl/vsl_binary_io.h>
00029 
00030 //: This class implements the perspective camera class as described in Hartley & Zisserman as a finite camera.
00031 //  This is the camera model based on three objects:
00032 //  the camera calibration matrix (see "vpgl_calibration_matrix.h"), the camera center,
00033 //  and the rotation of the camera from its canonical orientation staring down the
00034 //  positive z axis.
00035 //
00036 //  All rotation matrices entered will be checked that they are indeed rotations, i.e.
00037 //  that R.transpose()*R = Identity and in the form:
00038 //  \verbatim
00039 //   [ R 0 ]
00040 //   [ 0 1 ]
00041 //  \endverbatim
00042 //
00043 // \verbatim
00044 //  Modifications
00045 //   Feb 12, 2007  Thomas Pollard   Added finite backprojection method.
00046 // \endverbatim
00047 //
00048 //  For adding to this class:
00049 //
00050 //  Be sure to call recompute_matrix in your member functions any time you change any of the
00051 //  camera parameters.
00052 template <class T>
00053 class vpgl_perspective_camera : public vpgl_proj_camera<T>
00054 {
00055  public:
00056   //: Default constructor
00057   // Makes a camera at the origin with no rotation and default calibration matrix.
00058   vpgl_perspective_camera();
00059 
00060   //: Main constructor takes all of the camera parameters.
00061   vpgl_perspective_camera( const vpgl_calibration_matrix<T>& K,
00062                            const vgl_point_3d<T>& camera_center,
00063                            const vgl_rotation_3d<T>& R );
00064 
00065   //: Main constructor based on K[R|t]
00066   vpgl_perspective_camera( const vpgl_calibration_matrix<T>& K,
00067                            const vgl_rotation_3d<T>& R,
00068                            const vgl_vector_3d<T>& t);
00069 
00070 
00071   //: Copy constructor
00072   vpgl_perspective_camera( const vpgl_perspective_camera& cam );
00073 
00074   //: Destructor
00075   virtual ~vpgl_perspective_camera(){}
00076 
00077   virtual vcl_string type_name() const { return "vpgl_perspective_camera"; }
00078 
00079   //: Clone `this': creation of a new object and initialization
00080   //  See Prototype pattern
00081   virtual vpgl_proj_camera<T>* clone(void) const;
00082 
00083   //: Finite backprojection.
00084   vgl_line_3d_2_points<T> backproject( const vgl_point_2d<T>& image_point ) const;
00085 
00086   //: Compute the principal axis.
00087   // i.e. the vector perpendicular to the image plane pointing towards the front of the camera.
00088   vgl_vector_3d<T> principal_axis() const;
00089 
00090   //: Determine whether the given point lies in front of the principal plane.
00091   bool is_behind_camera( const vgl_homg_point_3d<T>& world_point ) const;
00092 
00093   //: Setters and getters.
00094   void set_calibration( const vpgl_calibration_matrix<T>& K );
00095   void set_camera_center( const vgl_point_3d<T>& camera_center );
00096   void set_translation(const vgl_vector_3d<T>& t);
00097   void set_rotation( const vgl_rotation_3d<T>& R );
00098   const vpgl_calibration_matrix<T>& get_calibration() const{ return K_; }
00099   const vgl_point_3d<T>& get_camera_center() const { return camera_center_; }
00100   vgl_vector_3d<T> get_translation() const;
00101   const vgl_rotation_3d<T>& get_rotation() const{ return R_; }
00102 
00103   //: Rotate the camera about its center such that it looks at the given point
00104   //  The camera should also be rotated about its principle axis such that
00105   //  the vertical image direction is closest to \p up in the world
00106   void look_at(const vgl_homg_point_3d<T>& point,
00107                const vgl_vector_3d<T>& up = vgl_vector_3d<T>(0,0,1));
00108 
00109   // Redefined virtual functions -------------------------------------------
00110 
00111   //: Return the known camera center instead of computing it in the base class
00112   virtual vgl_homg_point_3d<T> camera_center() const
00113   { return vgl_homg_point_3d<T>(camera_center_); }
00114 
00115   // static public functions -----------------------------------------------
00116 
00117   //: Post-multiply this perspective camera with a 3-d Euclidean transformation
00118   static  vpgl_perspective_camera<T>
00119    postmultiply( const vpgl_perspective_camera<T>& in_cam,
00120                  const vgl_h_matrix_3d<T>& euclid_trans);
00121 
00122   //: Equality test
00123   inline bool operator==(vpgl_perspective_camera<T> const &that) const
00124   { return this == &that ||
00125     (K_ == that.K_ && this->get_matrix()== that.get_matrix() &&
00126      camera_center_ == that.camera_center_ && this->R_.as_matrix() == that.R_.as_matrix()); }
00127 
00128   // I/O :---------------------
00129 
00130   //: Binary save self to stream.
00131   virtual void b_write(vsl_b_ostream &os) const;
00132 
00133   //: Binary load self from stream.
00134   virtual void b_read(vsl_b_istream &is);
00135 
00136   //: IO version number
00137   short version() const {return 2;}
00138 
00139   //: Print an ascii summary to the stream
00140   void print_summary(vcl_ostream &os) const { os << *this; }
00141 
00142   //: Return a platform independent string identifying the class.
00143   // This is used by e.g. polymorphic binary i/o
00144   virtual vcl_string is_a() const { return vcl_string("vpgl_perspective_camera"); }
00145 
00146   //: Return true if the argument matches the string identifying the class or any parent class
00147   virtual bool is_class(vcl_string const& cls) const
00148   { return cls==is_a() || vpgl_proj_camera<double>::is_class(cls); }
00149 
00150   //: Return `this' if `this' is a vpgl_perspective_camera, 0 otherwise
00151   // This is used by e.g. the storage class
00152   // \todo code for affine camera and other children
00153   virtual vpgl_perspective_camera<T> *cast_to_perspective_camera() {return this;}
00154   virtual const vpgl_perspective_camera<T> *cast_to_perspective_camera() const {return this;}
00155 
00156  protected:
00157   //: Recalculate the 3x4 camera matrix from the parameters.
00158   void recompute_matrix();
00159 
00160   vpgl_calibration_matrix<T> K_;
00161   vgl_point_3d<T> camera_center_;
00162   vgl_rotation_3d<T> R_;
00163 };
00164 
00165 // External Functions:-------------------------------------------------------------
00166 
00167 //: Write vpgl_perspective_camera to stream
00168 template <class Type>
00169 vcl_ostream&  operator<<(vcl_ostream& s, vpgl_perspective_camera<Type> const& p);
00170 
00171 //: Read vpgl_perspective_camera  from stream
00172 template <class Type>
00173 vcl_istream&  operator>>(vcl_istream& s, vpgl_perspective_camera<Type>& p);
00174 
00175 
00176 //: Decompose camera into parameter blocks.
00177 // Attempts to decompose a 3x4 camera matrix into the parameter blocks that describe
00178 // a perspective camera, but will only work if the supplied matrix has a left 3x3
00179 // submatrix with rank 3.
00180 template <class T>
00181 bool vpgl_perspective_decomposition( const vnl_matrix_fixed<T,3,4>& camera_matrix,
00182                                      vpgl_perspective_camera<T>& p_camera );
00183 
00184 //: Changes the coordinate system of camera p1 such that the same change would transform p0 to K[I|0].
00185 template <class T>
00186 vpgl_perspective_camera<T> vpgl_align_down( const vpgl_perspective_camera<T>& p0,
00187                                             const vpgl_perspective_camera<T>& p1 );
00188 
00189 //: Changes the coordinate system of camera p1 such that the same change would transform K[I|0] to p0.
00190 template <class T>
00191 vpgl_perspective_camera<T> vpgl_align_up( const vpgl_perspective_camera<T>& p0,
00192                                           const vpgl_perspective_camera<T>& p1 );
00193 
00194 template <class T>
00195 vpgl_perspective_camera<T>
00196 postmultiply( const vpgl_perspective_camera<T>& in_cam,
00197               const vgl_h_matrix_3d<T>& euclid_trans);
00198 
00199 //: Binary save
00200 template <class T>
00201 void vsl_b_write(vsl_b_ostream &os, const vpgl_perspective_camera<T>* p);
00202 
00203 
00204 //: Binary read
00205 template <class T>
00206 void vsl_b_read(vsl_b_istream &is, vpgl_perspective_camera<T>* &p);
00207 
00208 
00209 #endif // vpgl_perspective_camera_h_