core/vgl/algo/vgl_h_matrix_2d.h
Go to the documentation of this file.
00001 // This is core/vgl/algo/vgl_h_matrix_2d.h
00002 #ifndef vgl_h_matrix_2d_h_
00003 #define vgl_h_matrix_2d_h_
00004 //:
00005 // \file
00006 // \brief 3x3 plane-to-plane projectivity
00007 //
00008 // A class to hold a plane-to-plane projective transformation matrix
00009 // and to perform common operations using it e.g. transfer point.
00010 //
00011 // \verbatim
00012 //  Modifications
00013 //   16 Aug 2010 - Gamze Tunali - added is_identity()
00014 //   22 Oct 2002 - Peter Vanroose - added vgl_homg_point_2d interface
00015 //   23 Oct 2002 - Peter Vanroose - using fixed 3x3 matrices throughout
00016 //   22 Mar 2003 - J.L. Mundy - preparing for upgrade to vgl
00017 //   24 Jun 2003 - Peter Vanroose - added projective_basis() from 4 lines
00018 //   31 Jul 2010 - Peter Vanroose - made more similar to 1d and 3d variants
00019 //   24 Oct 2010 - Peter Vanroose - mutators and setters now return *this
00020 //   27 Oct 2010 - Peter Vanroose - moved Doxygen docs from .txx to .h
00021 // \endverbatim
00022 
00023 #include <vnl/vnl_fwd.h> // for vnl_vector_fixed<T,2>
00024 #include <vnl/vnl_matrix_fixed.h>
00025 #include <vgl/vgl_homg_point_2d.h>
00026 #include <vgl/vgl_homg_line_2d.h>
00027 #include <vgl/vgl_conic.h>
00028 #include <vcl_vector.h>
00029 #include <vcl_iosfwd.h>
00030 
00031 //:
00032 // A class to hold a plane-to-plane projective transformation matrix
00033 // and to perform common operations using it e.g. transfer point.
00034 template <class T>
00035 class vgl_h_matrix_2d
00036 {
00037   // Data Members--------------------------------------------------------------
00038  protected:
00039   vnl_matrix_fixed<T,3,3> t12_matrix_;
00040 
00041  public:
00042 
00043   // Constructors/Initializers/Destructors-------------------------------------
00044 
00045   vgl_h_matrix_2d() {}
00046  ~vgl_h_matrix_2d() {}
00047   //: Copy constructor
00048   vgl_h_matrix_2d(vgl_h_matrix_2d<T> const& M) : t12_matrix_(M.get_matrix()) {}
00049   //: Constructor from a 3x3 matrix, and implicit cast from vnl_matrix_fixed<T,3,3>
00050   vgl_h_matrix_2d(vnl_matrix_fixed<T,3,3> const& M) : t12_matrix_(M) {}
00051   //: Construct an affine vgl_h_matrix_2d from 2x2 M and 2x1 m.
00052   vgl_h_matrix_2d(vnl_matrix_fixed<T,2,2> const& M,
00053                   vnl_vector_fixed<T,2> const& m);
00054   //: Constructor from 3x3 C-array
00055   explicit vgl_h_matrix_2d(T const* M) : t12_matrix_(M) {}
00056   //: Constructor from istream
00057   explicit vgl_h_matrix_2d(vcl_istream& s);
00058   //: Constructor from file
00059   explicit vgl_h_matrix_2d(char const* filename);
00060   //: Constructor - calculate homography between two sets of 2D points (minimum 4)
00061   vgl_h_matrix_2d(vcl_vector<vgl_homg_point_2d<T> > const& points1,
00062                   vcl_vector<vgl_homg_point_2d<T> > const& points2);
00063 
00064   // Operations----------------------------------------------------------------
00065 
00066   //: Return the transformed point given by $q = {\tt H} p$
00067   vgl_homg_point_2d<T> operator()(vgl_homg_point_2d<T> const& p) const;
00068   //: Return the transformed point given by $q = {\tt H} p$
00069   vgl_homg_point_2d<T> operator*(vgl_homg_point_2d<T> const& p) const { return (*this)(p);}
00070 
00071   bool operator==(vgl_h_matrix_2d<T> const& M) const { return t12_matrix_ == M.get_matrix(); }
00072 
00073   //: Return the transformed line given by $m = {\tt H} l$
00074   vgl_homg_line_2d<T> preimage(vgl_homg_line_2d<T> const& l) const;
00075   vgl_homg_line_2d<T> correlation(vgl_homg_point_2d<T> const& p) const;
00076   vgl_homg_point_2d<T> correlation(vgl_homg_line_2d<T> const& l) const;
00077 
00078   //: assumed to be a point conic
00079   vgl_conic<T> operator() (vgl_conic<T> const& C) const;
00080 
00081   // these operations require taking an inverse
00082 
00083   //: Return the transformed point given by $p = {\tt H}^{-1} q$
00084   vgl_homg_point_2d<T> preimage(vgl_homg_point_2d<T> const& q) const;
00085   //: Return the transformed line given by $m = {\tt H}^{-1} l$
00086   vgl_homg_line_2d<T> operator()(vgl_homg_line_2d<T> const& l) const;
00087   //: Return the transformed line given by $m = {\tt H}^{-1} l$
00088   vgl_homg_line_2d<T> operator*(vgl_homg_line_2d<T> const& l) const { return (*this)(l);}
00089   //: assumed to be a point conic
00090   vgl_conic<T> preimage(vgl_conic<T> const& C) const;
00091 
00092   //:composition (*this) * H
00093   vgl_h_matrix_2d<T> operator*(vgl_h_matrix_2d<T> const& H) const
00094   { return vgl_h_matrix_2d<T>(t12_matrix_ * H.t12_matrix_); }
00095 
00096   // Data Access---------------------------------------------------------------
00097 
00098   //: Return the 3x3 homography matrix
00099   vnl_matrix_fixed<T,3,3> const& get_matrix() const { return t12_matrix_; }
00100   //: Fill M with contents of the 3x3 homography matrix
00101   void get(vnl_matrix_fixed<T,3,3>* M) const;
00102   //:
00103   // \deprecated use the vnl_matrix_fixed variant instead
00104   void get(vnl_matrix<T>* M) const;
00105   //: Fill M with contents of the 3x3 homography matrix
00106   void get(T *M) const;
00107   //: Return an element from the 3x3 homography matrix
00108   T get(unsigned int row_index, unsigned int col_index) const;
00109   //: Return the inverse homography
00110   vgl_h_matrix_2d get_inverse() const;
00111 
00112   //: Set an element of the 3x3 homography matrix
00113   vgl_h_matrix_2d& set (unsigned int row_index, unsigned int col_index, T value)
00114   { t12_matrix_[row_index][col_index]=value; return *this; }
00115 
00116   //: Set to 3x3 row-stored matrix
00117   vgl_h_matrix_2d& set(T const* M);
00118   //: Set to given 3x3 matrix
00119   vgl_h_matrix_2d& set(vnl_matrix_fixed<T,3,3> const& M);
00120 
00121   // various affine transformations that set the corresponding parts of the matrix
00122 
00123   //: initialize the transformation to identity
00124   vgl_h_matrix_2d& set_identity();
00125 
00126   //: set H[0][2] = tx and H[1][2] = ty, other elements unaltered
00127   vgl_h_matrix_2d& set_translation(T tx, T ty);
00128 
00129   //: the upper 2x2 part of the matrix is replaced by a rotation matrix.
00130   //  rotation angle theta is in radians
00131   vgl_h_matrix_2d& set_rotation(T theta);
00132 
00133   //: compose the current transform with a uniform scaling transformation, S.
00134   // $S = \left[ \begin{array}{ccc}
00135   //                                s & 0 & 0 \\%
00136   //                                0 & s & 0 \\%
00137   //                                0 & 0 & 1
00138   // \end{array}\right]$                         , Ts = S*T.
00139   vgl_h_matrix_2d& set_scale(T scale);
00140 
00141   //: set the transform to a similarity mapping
00142   // Sim $ = \left[\begin{array}{ccc}
00143   //         \cos(\theta) & -\sin(\theta) & tx \\%
00144   //         \sin(\theta) &  \cos(\theta) & ty \\%
00145   //         0            &  0            & 1
00146   // \end{array}\right]$
00147   vgl_h_matrix_2d& set_similarity(T s, T theta, T tx, T ty);
00148 
00149   //: compose the transform with diagonal aspect ratio transform.
00150   // $A = \left[ \begin{array}{ccc}
00151   //                                 1 & 0 & 0 \\%
00152   //                                 0 & a & 0 \\%
00153   //                                 0 & 0 & 1
00154   // \end{array}\right]$                         , Ta = A*T.
00155   vgl_h_matrix_2d& set_aspect_ratio(T aspect_ratio);
00156 
00157 
00158   //: set the transform to a general affine transform matrix
00159   // $A = \left[ \begin{array}{ccc}
00160   //                           a00 & a01 & a02 \\%
00161   //                           a10 & a11 & a12 \\%
00162   //                           0   & 0   & 1
00163   // \end{array}\right]$
00164   vgl_h_matrix_2d& set_affine(vnl_matrix_fixed<T,2,3> const& M23);
00165   //:
00166   // \deprecated use the vnl_matrix_fixed variant instead
00167   vgl_h_matrix_2d& set_affine(vnl_matrix<T> const& M23);
00168 
00169   bool is_rotation() const;
00170   bool is_euclidean() const;
00171   bool is_identity() const;
00172 
00173   //: transformation to projective basis (canonical frame)
00174   // Compute the homography that takes the input set of points to the
00175   // canonical frame.  The points act as the projective basis for
00176   // the canonical coordinate system.  In the canonical frame the points
00177   // have coordinates:
00178   // $\begin{array}{cccc}
00179   //                 p[0] & p[1] & p[2] & p[3] \\%
00180   //                   1  &   0  &   0  &   1  \\%
00181   //                   0  &   1  &   0  &   1  \\%
00182   //                   0  &   0  &   1  &   1
00183   // \end{array}$
00184   bool projective_basis(vcl_vector<vgl_homg_point_2d<T> > const& four_points);
00185 
00186   //: transformation to projective basis (canonical frame)
00187   // Compute the homography that takes the input set of lines to the canonical
00188   // frame.  The lines act as the dual projective basis for the canonical
00189   // coordinate system.  In the canonical frame the lines have equations:
00190   // x=0; y=0; w=0; x+y+w=0.  (The third line is the line at infinity.)
00191   bool projective_basis(vcl_vector<vgl_homg_line_2d<T> > const& four_lines
00192 #ifdef VCL_VC_6
00193                        , int dummy=0 // parameter to help useless compiler disambiguate different functions
00194 #endif
00195                        );
00196 
00197   // ---------- extract components as transformations ----------
00198 
00199   //: corresponds to rotation for Euclidean transformations
00200   vgl_h_matrix_2d<T> get_upper_2x2() const;
00201   //: corresponds to rotation for Euclidean transformations
00202   vnl_matrix_fixed<T,2,2> get_upper_2x2_matrix() const;
00203 
00204   //: corresponds to translation for affine transformations
00205   vgl_homg_point_2d<T> get_translation() const;
00206   //: corresponds to translation for affine transformations
00207   vnl_vector_fixed<T,2> get_translation_vector() const;
00208 
00209   //: Read H from vcl_istream
00210   bool read(vcl_istream& s);
00211   //: Read H from file
00212   bool read(char const* filename);
00213 };
00214 
00215 //: Print H on vcl_ostream
00216 template <class T> vcl_ostream& operator<<(vcl_ostream& s, vgl_h_matrix_2d<T> const& H);
00217 //: Read H from vcl_istream
00218 template <class T> vcl_istream& operator>>(vcl_istream& s, vgl_h_matrix_2d<T>&       H)
00219 { H.read(s); return s; }
00220 
00221 #define VGL_H_MATRIX_2D_INSTANTIATE(T) extern "please include vgl/algo/vgl_h_matrix_2d.txx first"
00222 
00223 #endif // vgl_h_matrix_2d_h_