core/vgl/algo/vgl_h_matrix_3d.h
Go to the documentation of this file.
00001 // This is core/vgl/algo/vgl_h_matrix_3d.h
00002 #ifndef vgl_h_matrix_3d_h_
00003 #define vgl_h_matrix_3d_h_
00004 //:
00005 // \file
00006 // \brief 4x4 3D-to-3D projectivity
00007 //
00008 // A class to hold a 3D projective transformation matrix
00009 // and to perform common operations using it e.g. transfer point.
00010 //
00011 // \verbatim
00012 //  Modifications
00013 //   22 Oct 2002 - Peter Vanroose - added vgl_homg_point_2d interface
00014 //   23 Oct 2002 - Peter Vanroose - using fixed 3x3 matrices throughout
00015 //   22 Mar 2003 - J. L. Mundy  - prep for moving to vgl
00016 //   31 Jul 2010 - Peter Vanroose - made more similar to 1d and 2d variants
00017 //   24 Oct 2010 - Peter Vanroose - mutators and setters now return *this
00018 //   27 Oct 2010 - Peter Vanroose - moved Doxygen docs from .txx to .h
00019 //   26 Jul 2011 - Peter Vanroose - added correlation(),set_affine(),is_identity()
00020 // \endverbatim
00021 
00022 #include <vnl/vnl_fwd.h> // for vnl_vector_fixed<T,3>
00023 #include <vnl/vnl_matrix_fixed.h>
00024 #include <vgl/vgl_homg_point_3d.h>
00025 #include <vgl/vgl_homg_plane_3d.h>
00026 #include <vcl_vector.h>
00027 #include <vcl_iosfwd.h>
00028 
00029 //:
00030 // A class to hold a 3-d projective transformation matrix
00031 // and to perform common operations using it e.g. transform point.
00032 template <class T>
00033 class vgl_h_matrix_3d
00034 {
00035  protected:
00036   vnl_matrix_fixed<T,4,4> t12_matrix_;
00037  public:
00038   vgl_h_matrix_3d() {}
00039  ~vgl_h_matrix_3d() {}
00040   //: Copy constructor
00041   vgl_h_matrix_3d(vgl_h_matrix_3d<T> const& M) : t12_matrix_(M.get_matrix()) {}
00042   //: Constructor from a 4x4 matrix, and implicit cast from vnl_matrix_fixed<T,4,4>
00043   vgl_h_matrix_3d(vnl_matrix_fixed<T,4,4> const& M) : t12_matrix_(M) {}
00044   //: Construct an affine vgl_h_matrix_3d from 3x3 M and 3x1 m.
00045   vgl_h_matrix_3d(vnl_matrix_fixed<T,3,3> const& M,
00046                   vnl_vector_fixed<T,3> const& m);
00047   //: Constructor from 4x4 row-storage C-array
00048   explicit vgl_h_matrix_3d(T const* M) : t12_matrix_(M) {}
00049   //: Load from ASCII vcl_istream.
00050   explicit vgl_h_matrix_3d(vcl_istream& s);
00051   //: Load from file
00052   explicit vgl_h_matrix_3d(char const* filename);
00053   //: Constructor - calculate homography between two sets of 3D points (minimum 5)
00054   vgl_h_matrix_3d(vcl_vector<vgl_homg_point_3d<T> > const& points1,
00055                   vcl_vector<vgl_homg_point_3d<T> > const& points2);
00056 
00057   // Operations----------------------------------------------------------------
00058 
00059   //: Return the transformed point given by $q = {\tt H} p$
00060   vgl_homg_point_3d<T> operator()(vgl_homg_point_3d<T> const& p) const;
00061   //: Return the transformed point given by $q = {\tt H} p$
00062   vgl_homg_point_3d<T> operator* (vgl_homg_point_3d<T> const& p) const {return (*this)(p);}
00063 
00064   bool operator==(vgl_h_matrix_3d<T> const& M) const { return t12_matrix_ == M.get_matrix(); }
00065 
00066   //: Return the preimage of a transformed plane: $m = {\tt H} l$
00067   vgl_homg_plane_3d<T> preimage(vgl_homg_plane_3d<T> const& l) const;
00068   vgl_homg_plane_3d<T> correlation(vgl_homg_point_3d<T> const& p) const;
00069   vgl_homg_point_3d<T> correlation(vgl_homg_plane_3d<T> const& l) const;
00070 
00071   //the following require computing the inverse homography
00072 
00073   //: Return the preimage of a transformed point: $p = {\tt H}^{-1} q$
00074   // (requires an inverse)
00075   vgl_homg_point_3d<T> preimage(vgl_homg_point_3d<T> const& q) const;
00076   //: Return the transformed plane given by $m = {\tt H}^{-1} l$
00077   // (requires an inverse)
00078   vgl_homg_plane_3d<T> operator()(vgl_homg_plane_3d<T> const& l) const;
00079   //: Return the transformed plane given by $m = {\tt H}^{-1} l$
00080   // (requires an inverse)
00081   vgl_homg_plane_3d<T> operator*(vgl_homg_plane_3d<T> const& l) const { return (*this)(l);}
00082 
00083   //:composition (*this) * H
00084   vgl_h_matrix_3d<T> operator * (vgl_h_matrix_3d<T> const& H) const
00085   { return vgl_h_matrix_3d<T>(t12_matrix_* H.t12_matrix_); }
00086 
00087   // Data Access---------------------------------------------------------------
00088 
00089   //: Return the 4x4 homography matrix
00090   vnl_matrix_fixed<T,4,4> const& get_matrix() const { return t12_matrix_; }
00091   //: Fill M with contents of the 4x4 homography matrix
00092   void get (vnl_matrix_fixed<T,4,4>* M) const;
00093   //:
00094   // \deprecated use the vnl_matrix_fixed variant instead
00095   void get (vnl_matrix<T>* M) const;
00096   //: Fill M with contents of the 4x4 homography matrix
00097   void get (T* M) const;
00098   //: Return an element from the 4x4 homography matrix
00099   T get (unsigned int row_index, unsigned int col_index) const;
00100   //: Return the inverse homography
00101   vgl_h_matrix_3d get_inverse() const;
00102 
00103   //: Set an element of the 4x4 homography matrix
00104   vgl_h_matrix_3d& set (unsigned int row_index, unsigned int col_index, T value)
00105   { t12_matrix_[row_index][col_index]=value; return *this; }
00106 
00107   //: Set to 4x4 row-stored matrix
00108   vgl_h_matrix_3d& set(T const* M);
00109   //: Set to given 4x4 matrix
00110   vgl_h_matrix_3d& set(vnl_matrix_fixed<T,4,4> const& M);
00111 
00112   // various affine transformations that set the corresponding parts of the matrix
00113 
00114   //: initialize the transformation to identity
00115   vgl_h_matrix_3d& set_identity();
00116   //: set H[0][3] = tx, H[1][3] = ty, and H[2][3] = tz, other elements unaltered
00117   vgl_h_matrix_3d& set_translation(T tx, T ty, T tz);
00118   //: compose the current transform with a uniform scaling transformation, S.
00119   // $S = \left[ \begin{array}{cccc}
00120   //                           s & 0 & 0 & 0 \\%
00121   //                           0 & s & 0 & 0 \\%
00122   //                           0 & 0 & s & 0 \\%
00123   //                           0 & 0 & 0 & 1
00124   // \end{array}\right]$                         , Ts = S*T.
00125   vgl_h_matrix_3d& set_scale(T scale);
00126 
00127   //: set the transform to a general affine transform matrix
00128   // $A = \left[ \begin{array}{ccc}
00129   //                           a00 & a01 & a02 & a03 \\%
00130   //                           a10 & a11 & a12 & a13 \\%
00131   //                           a20 & a21 & a22 & a23 \\%
00132   //                           0   & 0   & 0   & 1
00133   // \end{array}\right]$
00134   vgl_h_matrix_3d& set_affine(vnl_matrix_fixed<T,3,4> const& M34);
00135 
00136   //: Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
00137   vgl_h_matrix_3d& set_rotation_matrix(vnl_matrix_fixed<T,3,3> const& R);
00138   //: Set to rotation about an axis
00139   //  Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
00140   //  rotation angle theta is in radians
00141   vgl_h_matrix_3d& set_rotation_about_axis(vnl_vector_fixed<T,3> const& axis, T theta);
00142   //: Set to roll, pitch and yaw specified rotation.
00143   // - roll is rotation about z
00144   // - pitch is rotation about y
00145   // - yaw is rotation about x
00146   //  Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
00147   vgl_h_matrix_3d& set_rotation_roll_pitch_yaw(T yaw, T pitch, T roll);
00148   //: Set to rotation specified by Euler angles
00149   //  Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
00150   vgl_h_matrix_3d& set_rotation_euler(T rz1, T ry, T rz2);
00151 
00152   //: set the transformation to a reflection about a plane
00153   void set_reflection_plane(vgl_plane_3d<double> const& p);
00154 
00155   bool is_rotation() const;
00156   bool is_identity() const;
00157   bool is_euclidean() const;
00158 
00159   //: Compute transform to projective basis given five points, no 4 of which coplanar
00160   // Transformation to projective basis (canonical frame)
00161   // Compute the homography that takes the input set of points to the
00162   // canonical frame.  The points act as the projective basis for
00163   // the canonical coordinate system.  In the canonical frame the points
00164   // have coordinates:
00165   // $\begin{array}{cccc}
00166   //   p[0] & p[1] & p[2]  & p[3] & p[4] \\%
00167   //     1  &   0  &   0   &   0  &   1  \\%
00168   //     0  &   1  &   0   &   0  &   1  \\%
00169   //     0  &   0  &   1   &   0  &   1  \\%
00170   //     0  &   0  &   0   &   1  &   1
00171   // \end{array}$
00172   bool projective_basis(vcl_vector<vgl_homg_point_3d<T> > const& five_points);
00173 
00174   //: transformation to projective basis (canonical frame)
00175   // Compute the homography that takes the input set of planes to the canonical
00176   // frame.  The planes act as the dual projective basis for the canonical
00177   // coordinate system.  In the canonical frame the planes have equations:
00178   // x=0; y=0; z=0; w=0; x+y+z+w=0. (The latter plane is the plane at infinity.)
00179   bool projective_basis(vcl_vector<vgl_homg_plane_3d<T> > const& five_planes);
00180 
00181   // ---------- extract components as transformations ----------
00182 
00183   //: corresponds to rotation for Euclidean transformations
00184   vgl_h_matrix_3d<T> get_upper_3x3() const;
00185   vnl_matrix_fixed<T,3,3> get_upper_3x3_matrix() const;
00186 
00187   //: corresponds to translation for affine transformations
00188   vgl_homg_point_3d<T> get_translation() const;
00189   vnl_vector_fixed<T,3> get_translation_vector() const;
00190 
00191   //: Load H from ASCII file.
00192   bool read(vcl_istream& s);
00193   //: Read H from file
00194   bool read(char const* filename);
00195 };
00196 
00197 //: Print H on vcl_ostream
00198 template <class T> vcl_ostream& operator<<(vcl_ostream& s, vgl_h_matrix_3d<T> const& H);
00199 //: Load H from ASCII file.
00200 template <class T> vcl_istream& operator>>(vcl_istream& s, vgl_h_matrix_3d<T>&       H)
00201 { H.read(s); return s; }
00202 
00203 #define VGL_H_MATRIX_3D_INSTANTIATE(T) extern "please include vgl/algo/vgl_h_matrix_3d.txx first"
00204 
00205 #endif // vgl_h_matrix_3d_h_