contrib/oxl/mvl/TriTensor.h
Go to the documentation of this file.
00001 // This is oxl/mvl/TriTensor.h
00002 #ifndef TriTensor_h_
00003 #define TriTensor_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief The trifocal tensor
00010 //
00011 // A class to hold a Trifocal Tensor and perform common operations, such as
00012 // point and line transfer, coordinate-frame transformation and I/O.
00013 //
00014 // \author
00015 //             Paul Beardsley, 29.03.96
00016 //             Oxford University, UK
00017 //
00018 // \verbatim
00019 //  Modifications:
00020 //   AWF - Added composition, transformation, homography generation.
00021 //   Peter Vanroose - 11 Mar 97 - added operator==
00022 //   Peter Vanroose - 22 Jun 03 - added vgl interface
00023 // \endverbatim
00024 //
00025 //------------------------------------------------------------------------------
00026 
00027 #include <vcl_vector.h>
00028 #include <vcl_iosfwd.h>
00029 
00030 #include <vbl/vbl_array_3d.h>
00031 
00032 #include <vnl/vnl_matrix.h>
00033 #include <vnl/vnl_double_3.h>
00034 #include <vnl/vnl_double_3x3.h>
00035 
00036 #include <vgl/vgl_fwd.h>
00037 #include <vgl/algo/vgl_algo_fwd.h>
00038 #include <vgl/algo/vgl_p_matrix.h>
00039 
00040 #include <mvl/HomgLine2D.h>
00041 #include <mvl/HomgLineSeg2D.h>
00042 #include <mvl/HomgPoint2D.h>
00043 
00044 #include <mvl/PMatrix.h>
00045 class HMatrix2D;
00046 class FMatrix;
00047 class PMatrix;
00048 class FManifoldProject;
00049 
00050 class TriTensor
00051 {
00052   // Data Members------------------------------------------------------------
00053 
00054   vbl_array_3d<double> T;
00055 
00056   // Caches for various computed quantities
00057   mutable const HomgPoint2D* e12_;
00058   mutable const HomgPoint2D* e13_;
00059 
00060   mutable const FManifoldProject* fmp12_;
00061   mutable const FManifoldProject* fmp13_;
00062   mutable const FManifoldProject* fmp23_;
00063 
00064  public:
00065 
00066   // Constructors/Initializers/Destructors-----------------------------------
00067 
00068   TriTensor();
00069   TriTensor(const TriTensor&);
00070   // Construct from 27-element vector
00071   TriTensor(const double *tritensor_array);
00072   TriTensor(const PMatrix& P1, const PMatrix& P2, const PMatrix& P3);
00073   TriTensor(const PMatrix& P2, const PMatrix& P3);
00074   TriTensor(const vnl_matrix<double>& T1, const vnl_matrix<double>& P2, const vnl_matrix<double>& P3);
00075  ~TriTensor();
00076 
00077   // Data Access-------------------------------------------------------------
00078 
00079   TriTensor& operator=(const TriTensor&);
00080   bool operator==(TriTensor const& p) const {
00081     for (int i=0;i<3;++i) for (int j=0;j<3;++j) for (int k=0;k<3;++k) if (p(i,j,k)!=T(i,j,k)) return false;
00082     return true; }
00083   double& operator() (unsigned int i1, unsigned int i2, unsigned int i3) { return T(i1,i2,i3); }
00084   double operator() (unsigned int i1, unsigned int i2, unsigned int i3) const { return T(i1,i2,i3); }
00085 
00086   void set(unsigned int i1, unsigned int i2, unsigned int i3, double value);
00087 
00088   void set(const double* vec);
00089   void set(const vnl_matrix<double>& tvector); // 27x1 matrix
00090   void convert_to_vector(vnl_matrix<double>* tvector) const; // 27x1 matrix
00091 
00092   void set(const PMatrix& P1, const PMatrix& P2, const PMatrix& P3);
00093   void set(const PMatrix& P2, const PMatrix& P3);
00094   void set(const vnl_matrix<double>& T1, const vnl_matrix<double>& T2, const vnl_matrix<double>& T3);
00095 
00096   // Data Control------------------------------------------------------------
00097 
00098   vgl_homg_point_2d<double> image1_transfer(vgl_homg_point_2d<double> const& point2,
00099                                             vgl_homg_point_2d<double> const& point3,
00100                                             vgl_homg_point_2d<double> corrected[] = 0) const;
00101   vgl_homg_point_2d<double> image2_transfer(vgl_homg_point_2d<double> const& point1,
00102                                             vgl_homg_point_2d<double> const& point3,
00103                                             vgl_homg_point_2d<double> corrected[] = 0) const;
00104   vgl_homg_point_2d<double> image3_transfer(vgl_homg_point_2d<double> const& point1,
00105                                             vgl_homg_point_2d<double> const& point2,
00106                                             vgl_homg_point_2d<double> corrected[] = 0) const;
00107 
00108   HomgPoint2D image1_transfer(HomgPoint2D const& point2,
00109                               HomgPoint2D const& point3,
00110                               HomgPoint2D corrected[] = 0) const;
00111   HomgPoint2D image2_transfer(HomgPoint2D const& point1,
00112                               HomgPoint2D const& point3,
00113                               HomgPoint2D corrected[] = 0) const;
00114   HomgPoint2D image3_transfer(HomgPoint2D const& point1,
00115                               HomgPoint2D const& point2,
00116                               HomgPoint2D corrected[] = 0) const;
00117 
00118   vgl_homg_point_2d<double> image1_transfer_qd(vgl_homg_point_2d<double> const& point2,
00119                                                vgl_homg_point_2d<double> const& point3) const;
00120   vgl_homg_point_2d<double> image2_transfer_qd(vgl_homg_point_2d<double> const& point1,
00121                                                vgl_homg_point_2d<double> const& point3) const;
00122   vgl_homg_point_2d<double> image3_transfer_qd(vgl_homg_point_2d<double> const& point1,
00123                                                vgl_homg_point_2d<double> const& point2) const;
00124 
00125   HomgPoint2D image1_transfer_qd(const HomgPoint2D& point2, const HomgPoint2D& point3) const;
00126   HomgPoint2D image2_transfer_qd(const HomgPoint2D& point1, const HomgPoint2D& point3) const;
00127   HomgPoint2D image3_transfer_qd(const HomgPoint2D& point1, const HomgPoint2D& point2) const;
00128 
00129   vgl_homg_point_2d<double> image1_transfer(vgl_homg_point_2d<double> const& point1,
00130                                             vgl_homg_line_2d <double> const& line2) const;
00131   vgl_homg_point_2d<double> image2_transfer(vgl_homg_point_2d<double> const& point1,
00132                                             vgl_homg_line_2d <double> const& line3) const;
00133   vgl_homg_point_2d<double> image3_transfer(vgl_homg_point_2d<double> const& point2,
00134                                             vgl_homg_line_2d <double> const& line3) const;
00135 
00136   HomgPoint2D image1_transfer(HomgPoint2D const& point1,
00137                               HomgLine2D  const& line2) const;
00138   HomgPoint2D image2_transfer(HomgPoint2D const& point1,
00139                               HomgLine2D  const& line3) const;
00140   HomgPoint2D image3_transfer(HomgPoint2D const& point2,
00141                               HomgLine2D  const& line3) const;
00142 
00143   vgl_homg_line_2d<double> image1_transfer(vgl_homg_line_2d<double> const& line2,
00144                                            vgl_homg_line_2d<double> const& line3) const;
00145   vgl_homg_line_2d<double> image2_transfer(vgl_homg_line_2d<double> const& line2,
00146                                            vgl_homg_line_2d<double> const& line3) const;
00147   vgl_homg_line_2d<double> image3_transfer(vgl_homg_line_2d<double> const& line2,
00148                                            vgl_homg_line_2d<double> const& line3) const;
00149 
00150   HomgLine2D image1_transfer(const HomgLine2D& line2, const HomgLine2D& line3) const;
00151   HomgLine2D image2_transfer(const HomgLine2D& line2, const HomgLine2D& line3) const;
00152   HomgLine2D image3_transfer(const HomgLine2D& line2, const HomgLine2D& line3) const;
00153 
00154   vgl_h_matrix_2d<double> get_hmatrix_31(vgl_homg_line_2d<double> const& line2) const;
00155   vgl_h_matrix_2d<double> get_hmatrix_21(vgl_homg_line_2d<double> const& line3) const;
00156 
00157   HMatrix2D get_hmatrix_31(const HomgLine2D& line2) const;
00158   HMatrix2D get_hmatrix_21(const HomgLine2D& line3) const;
00159 
00160   bool get_epipoles(vgl_homg_point_2d<double>& e2, vgl_homg_point_2d<double>& e3) const;
00161   bool get_epipoles(HomgPoint2D* e2, HomgPoint2D* e3) const;
00162   bool compute_epipoles() const; // mutable const
00163 
00164   HomgPoint2D get_epipole_12() const;
00165   HomgPoint2D get_epipole_13() const;
00166 
00167   FMatrix get_fmatrix_13() const;
00168   FMatrix get_fmatrix_12() const;
00169 
00170   FMatrix compute_fmatrix_23() const;
00171 
00172   const FManifoldProject* get_fmp12() const;
00173   const FManifoldProject* get_fmp23() const;
00174   const FManifoldProject* get_fmp13() const;
00175 
00176   void compute_P_matrices(const vnl_double_3& x, double alpha, double beta, PMatrix* P2, PMatrix* P3) const;
00177   void compute_P_matrices(const vnl_double_3& x, double alpha, PMatrix* P2, PMatrix* P3) const {
00178     compute_P_matrices(x,alpha,alpha, P2, P3);
00179   }
00180   void compute_P_matrices(const vnl_double_3& x, PMatrix* P2, PMatrix* P3) const {
00181     compute_P_matrices(x, 1, 1, P2, P3);
00182   }
00183   void compute_P_matrices(PMatrix* P2, PMatrix* P3) const {
00184     compute_P_matrices(vnl_double_3(1,1,1), 1, 1, P2, P3);
00185   }
00186   void compute_P_matrices(vgl_p_matrix<double> &P2, vgl_p_matrix<double> &P3) const {
00187     PMatrix Ptemp2, Ptemp3;
00188     compute_P_matrices(vnl_double_3(1,1,1), 1, 1, &Ptemp2, &Ptemp3);
00189     P2.set(Ptemp2.get_matrix());
00190     P3.set(Ptemp3.get_matrix());
00191   }
00192   void compute_caches();
00193   void clear_caches();
00194 
00195   // Utility Methods---------------------------------------------------------
00196   void get_constraint_lines_image3(vgl_homg_point_2d<double> const& p1,
00197                                    vgl_homg_point_2d<double> const& p2,
00198                                    vcl_vector<vgl_homg_line_2d<double> >& lines) const;
00199   void get_constraint_lines_image2(vgl_homg_point_2d<double> const& p1,
00200                                    vgl_homg_point_2d<double> const& p3,
00201                                    vcl_vector<vgl_homg_line_2d<double> >& lines) const;
00202   void get_constraint_lines_image1(vgl_homg_point_2d<double> const& p2,
00203                                    vgl_homg_point_2d<double> const& p3,
00204                                    vcl_vector<vgl_homg_line_2d<double> >& lines) const;
00205 
00206   void get_constraint_lines_image3(HomgPoint2D const& p1,
00207                                    HomgPoint2D const& p2,
00208                                    vcl_vector<HomgLine2D>* lines) const;
00209   void get_constraint_lines_image2(HomgPoint2D const& p1,
00210                                    HomgPoint2D const& p3,
00211                                    vcl_vector<HomgLine2D>* lines) const;
00212   void get_constraint_lines_image1(HomgPoint2D const& p2,
00213                                    HomgPoint2D const& p3,
00214                                    vcl_vector<HomgLine2D>* lines) const;
00215 
00216   //: Contract Tensor axis tensor_axis with first component of Matrix M.
00217   // That is:
00218   // For tensor_axis = 1,  Compute T_ijk = T_pjk M_pi
00219   // For tensor_axis = 2,  Compute T_ijk = T_ipk M_pj
00220   // For tensor_axis = 3,  Compute T_ijk = T_ijp M_pk
00221   TriTensor postmultiply(unsigned tensor_axis, const vnl_matrix<double>& M) const;
00222 
00223   //: Contract Tensor axis tensor_axis with second component of Matrix M.
00224   // That is:
00225   // For tensor_axis = 1,  Compute T_ijk = M_ip T_pjk
00226   // For tensor_axis = 2,  Compute T_ijk = M_jp T_ipk
00227   // For tensor_axis = 3,  Compute T_ijk = M_kp T_ijp
00228   TriTensor premultiply(unsigned tensor_axis, const vnl_matrix<double>& M) const;
00229 
00230   TriTensor postmultiply1(const vnl_matrix<double>& M) const;
00231   TriTensor postmultiply2(const vnl_matrix<double>& M) const;
00232   TriTensor postmultiply3(const vnl_matrix<double>& M) const;
00233 
00234   TriTensor premultiply1(const vnl_matrix<double>& M) const;
00235   TriTensor premultiply2(const vnl_matrix<double>& M) const;
00236   TriTensor premultiply3(const vnl_matrix<double>& M) const;
00237 
00238   vnl_double_3x3 dot1(const vnl_double_3& v) const;
00239   vnl_double_3x3 dot2(const vnl_double_3& v) const;
00240   vnl_double_3x3 dot3(const vnl_double_3& v) const;
00241   vnl_double_3x3 dot1t(const vnl_double_3& v) const;
00242   vnl_double_3x3 dot2t(const vnl_double_3& v) const;
00243   vnl_double_3x3 dot3t(const vnl_double_3& v) const;
00244 
00245   bool check_equal_up_to_scale(const TriTensor& that) const;
00246 
00247   // INTERNALS---------------------------------------------------------------
00248 
00249   //: C123 are line conditioning matrices.
00250   // If C * l = lhat, and l1 = T l2 l3, then lhat1 = That lhat2 lhat3
00251   TriTensor condition(const vnl_matrix<double>& line_1_denorm,
00252                       const vnl_matrix<double>& line_2_norm,
00253                       const vnl_matrix<double>& line_3_norm) const;
00254 
00255   TriTensor decondition(const vnl_matrix<double>& line_1_norm,
00256                         const vnl_matrix<double>& line_2_denorm,
00257                         const vnl_matrix<double>& line_3_denorm) const;
00258  private:
00259   void delete_caches() const; // mutable const
00260 };
00261 
00262 vcl_ostream& operator << (vcl_ostream&, const TriTensor& T);
00263 vcl_istream& operator >> (vcl_istream&, TriTensor& T);
00264 
00265 #endif // TriTensor_h_