core/vgl/algo/vgl_h_matrix_1d.h
Go to the documentation of this file.
00001 // This is core/vgl/algo/vgl_h_matrix_1d.h
00002 #ifndef vgl_h_matrix_1d_h_
00003 #define vgl_h_matrix_1d_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief 2x2 line-to-line projectivity
00010 //
00011 // A class to hold a line-to-line projective transformation matrix
00012 // and to perform common operations using it e.g. transfer point.
00013 //
00014 // \verbatim
00015 //  Modifications
00016 //   22 Oct 2002 - Peter Vanroose - added vgl_homg_point_2d interface
00017 //   23 Oct 2002 - Peter Vanroose - using fixed 3x3 matrices throughout
00018 //   22 Mar 2003 - J.L. Mundy - preparing for upgrade to vgl
00019 //   13 Jun 2004 - Peter Vanroose - added set_identity() and projective_basis()
00020 //   31 Jul 2010 - Peter Vanroose - made more similar to 2d and 3d variants
00021 //   24 Oct 2010 - Peter Vanroose - mutators and setters now return *this
00022 //   27 Oct 2010 - Peter Vanroose - moved Doxygen docs from .txx to .h
00023 //   26 Jul 2011 - Peter Vanroose - added is_identity(),is_rotation(),is_euclidean(),
00024 //                                  correlation(),operator*(h_matrix),set(row,col,val),
00025 //                                  set_translation(),set_affine(), cf vgl_h_matrix_2d
00026 // \endverbatim
00027 
00028 #include <vnl/vnl_matrix_fixed.h>
00029 #include <vgl/vgl_homg_point_1d.h>
00030 #include <vcl_vector.h>
00031 #include <vcl_iosfwd.h>
00032 
00033 //:
00034 // A class to hold a line-to-line projective transformation matrix
00035 // and to perform common operations using it e.g. transfer point.
00036 template <class T>
00037 class vgl_h_matrix_1d
00038 {
00039   // Data Members--------------------------------------------------------------
00040  protected:
00041   vnl_matrix_fixed<T,2,2> t12_matrix_;
00042 
00043  public:
00044 
00045   // Constructors/Initializers/Destructors-------------------------------------
00046 
00047   vgl_h_matrix_1d() {}
00048  ~vgl_h_matrix_1d() {}
00049 
00050   //: Copy constructor
00051   vgl_h_matrix_1d(vgl_h_matrix_1d<T> const& M) : t12_matrix_(M.get_matrix()) {}
00052 
00053   //: Constructor from a 2x2 matrix, and implicit cast from vnl_matrix_fixed<T,2,2>
00054   vgl_h_matrix_1d(vnl_matrix_fixed<T,2,2> const& M) : t12_matrix_(M) {}
00055 
00056   //: Constructor from 2x2 C-array
00057   explicit vgl_h_matrix_1d(T const* M) : t12_matrix_(M) {}
00058   //: Constructor from istream
00059   explicit vgl_h_matrix_1d(vcl_istream& s);
00060   //: Constructor from file
00061   explicit vgl_h_matrix_1d(char const* filename);
00062   //: Constructor - calculate homography between two sets of 1D points (minimum 3)
00063   vgl_h_matrix_1d(vcl_vector<vgl_homg_point_1d<T> > const& points1,
00064                   vcl_vector<vgl_homg_point_1d<T> > const& points2);
00065 
00066   // Operations----------------------------------------------------------------
00067 
00068   //: Return the transformed point given by $q = {\tt H} p$
00069   vgl_homg_point_1d<T> operator()(vgl_homg_point_1d<T> const& p) const;
00070   //: Return the transformed point given by $q = {\tt H} p$
00071   vgl_homg_point_1d<T> operator*(vgl_homg_point_1d<T> const& p) const { return (*this)(p); }
00072   vgl_homg_point_1d<T> correlation(vgl_homg_point_1d<T> const& p) const { return (*this)(p); }
00073 
00074   //: Return the transformed point given by $p = {\tt H}^{-1} q$
00075   vgl_homg_point_1d<T> preimage(vgl_homg_point_1d<T> const& q) const;
00076 
00077   bool operator==(vgl_h_matrix_1d<T> const& M) const { return t12_matrix_ == M.get_matrix(); }
00078 
00079   //: product of two vgl_h_matrix_1ds
00080   vgl_h_matrix_1d<T> operator*(vgl_h_matrix_1d<T> const& H) const
00081   { return vgl_h_matrix_1d<T>(t12_matrix_ * H.t12_matrix_); }
00082 
00083   // Data Access---------------------------------------------------------------
00084 
00085   //: Return the 2x2 homography matrix
00086   vnl_matrix_fixed<T,2,2> const& get_matrix() const { return t12_matrix_; }
00087   //: Fill M with contents of the 2x2 homography matrix
00088   void get (vnl_matrix_fixed<T,2,2>* M) const;
00089   //:
00090   // \deprecated use the vnl_matrix_fixed variant instead
00091   void get (vnl_matrix<T>* M) const;
00092   //: Fill M with contents of the 2x2 homography matrix
00093   void get (T* M) const;
00094   //: Return an element from the 2x2 homography matrix
00095   T get (unsigned int row_index, unsigned int col_index) const;
00096   //: Return the inverse homography
00097   vgl_h_matrix_1d get_inverse() const;
00098 
00099   bool is_rotation() const;
00100   bool is_euclidean() const;
00101   bool is_identity() const;
00102 
00103   //: transformation to projective basis (canonical frame)
00104   // Compute the homography that takes the input set of points to the
00105   // canonical frame.  The points act as the projective basis for
00106   // the canonical coordinate system.  In the canonical frame the points
00107   // have coordinates:
00108   // \verbatim
00109   //   p[0]p[1]p[2]
00110   //     1   0   1
00111   //     0   1   1
00112   // \endverbatim
00113   bool projective_basis(vcl_vector<vgl_homg_point_1d<T> > const& three_points);
00114 
00115   //: initialize the transformation to identity
00116   vgl_h_matrix_1d& set_identity();
00117   //: Set to 2x2 row-stored matrix
00118   vgl_h_matrix_1d& set(T const* M);
00119   //: Set to given 2x2 matrix
00120   vgl_h_matrix_1d& set(vnl_matrix_fixed<T,2,2> const& M);
00121 
00122   //: Set an element of the 2x2 homography matrix
00123   vgl_h_matrix_1d& set (unsigned int row_index, unsigned int col_index, T value)
00124   { t12_matrix_[row_index][col_index]=value; return *this; }
00125 
00126   //: compose the current transform with a uniform scaling transformation, S.
00127   // $S = \left[ \begin{array}{cc}
00128   //                                s & 0 \\%
00129   //                                0 & 1
00130   // \end{array}\right]$                         , Ts = S*T.
00131   vgl_h_matrix_1d& set_scale(T scale);
00132 
00133   //: set H[0][1] = tx, other elements unaltered
00134   vgl_h_matrix_1d& set_translation(T tx);
00135 
00136   //: set the transform to a general affine transform matrix
00137   // $A = \left[ \begin{array}{ccc}
00138   //                           a00 & a01 \\%
00139   //                           0   & 1
00140   // \end{array}\right]$
00141   vgl_h_matrix_1d& set_affine(vnl_matrix_fixed<T,1,2> const& M12);
00142 
00143   //: Read H from file
00144   bool read(char const* filename);
00145   //: Read H from vcl_istream
00146   bool read(vcl_istream& s);
00147 };
00148 
00149 //: Print H on vcl_ostream
00150 template <class T> vcl_ostream& operator<<(vcl_ostream& s, vgl_h_matrix_1d<T> const& H);
00151 //: Read H from vcl_istream
00152 template <class T> vcl_istream& operator>>(vcl_istream& s, vgl_h_matrix_1d<T>&       H)
00153 { H.read(s); return s; }
00154 
00155 
00156 #define VGL_H_MATRIX_1D_INSTANTIATE(T) extern "please include vgl/algo/vgl_h_matrix_1d.txx first"
00157 
00158 #endif // vgl_h_matrix_1d_h_