contrib/oxl/mvl/PMatrix.h
Go to the documentation of this file.
00001 // This is oxl/mvl/PMatrix.h
00002 #ifndef PMatrix_h_
00003 #define PMatrix_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief General 3x4 perspective projection matrix
00010 //
00011 // A class to hold a perspective projection matrix and use it to
00012 // perform common operations e.g. projecting point in 3d space to
00013 // its image on the image plane
00014 //
00015 // \verbatim
00016 //  Modifications
00017 //     010796 AWF Implemented get_focal_point() - awf, july 96
00018 //     011096 AWF Added caching vnl_svd<double>
00019 //     260297 AWF Converted to use vnl_double_3x4
00020 //     110397 PVr Added operator==
00021 //     221002 Peter Vanroose - added vgl_homg_point_2d interface
00022 //     231002 Peter Vanroose - using fixed 3x4 matrices throughout
00023 // \endverbatim
00024 
00025 #include <vcl_iosfwd.h>
00026 
00027 #include <vnl/algo/vnl_algo_fwd.h> // for vnl_svd
00028 #include <vnl/vnl_matrix.h>
00029 #include <vnl/vnl_vector.h>
00030 #include <vnl/vnl_double_3x3.h>
00031 #include <vnl/vnl_double_3x4.h>
00032 #include <vnl/vnl_double_4x4.h>
00033 #include <vnl/vnl_double_3.h>
00034 #include <vgl/vgl_homg_point_2d.h>
00035 #include <vgl/vgl_homg_point_3d.h>
00036 #include <vgl/vgl_homg_line_2d.h>
00037 #include <vgl/vgl_homg_line_3d_2_points.h>
00038 #include <vgl/vgl_homg_plane_3d.h>
00039 #include <vgl/vgl_line_segment_2d.h>
00040 #include <vgl/vgl_line_segment_3d.h>
00041 #include <vgl/algo/vgl_homg_operators_3d.h> // for p_matrix_ * vgl_homg_point_3d
00042 #include <vbl/vbl_ref_count.h>
00043 
00044 class HomgPoint2D;
00045 class HomgLine2D;
00046 class HomgLineSeg2D;
00047 
00048 class HomgPoint3D;
00049 class HomgPlane3D;
00050 class HomgLine3D;
00051 class HomgLineSeg3D;
00052 class HMatrix3D;
00053 class HMatrix2D;
00054 
00055 class PMatrix : public vbl_ref_count
00056 {
00057  public:
00058 
00059   // Constructors/Initializers/Destructors-------------------------------------
00060 
00061   PMatrix();
00062   PMatrix(vcl_istream&);
00063   PMatrix(const double *c_matrix);
00064   explicit PMatrix(vnl_double_3x4 const&);
00065   PMatrix(const vnl_matrix<double>& A, const vnl_vector<double>& a);
00066   PMatrix(const PMatrix&);
00067  ~PMatrix();
00068 
00069   static PMatrix read(const char* filename);
00070   static PMatrix read(vcl_istream&);
00071 
00072   // Operations----------------------------------------------------------------
00073 
00074   HomgPoint2D   project(const HomgPoint3D& X) const;
00075   HomgLine2D    project(const HomgLine3D& L) const;
00076   HomgLineSeg2D project(const HomgLineSeg3D& L) const;
00077 
00078   HomgPoint3D backproject_pseudoinverse(const HomgPoint2D& x) const;
00079   HomgLine3D  backproject(const HomgPoint2D& x) const;
00080   HomgPlane3D backproject(const HomgLine2D& l) const;
00081 
00082   //: Return the image point which is the projection of the specified 3D point X
00083   vgl_homg_point_2d<double>   project(vgl_homg_point_3d<double> const& X) const { return p_matrix_ * X; }
00084   //: Return the image line which is the projection of the specified 3D line L
00085   vgl_homg_line_2d<double>    project(vgl_homg_line_3d_2_points<double> const& L) const;
00086   //: Return the image linesegment which is the projection of the specified 3D linesegment L
00087   vgl_line_segment_2d<double> project(vgl_line_segment_3d<double> const& L) const;
00088 
00089   //: Return the 3D point $\vec X$ which is $\vec X = P^+ \vec x$.
00090   vgl_homg_point_3d<double> backproject_pseudoinverse(vgl_homg_point_2d<double> const& x) const;
00091   //: Return the 3D line which is the backprojection of the specified image point, x.
00092   vgl_homg_line_3d_2_points<double>  backproject(vgl_homg_point_2d<double> const& x) const;
00093   //: Return the 3D plane which is the backprojection of the specified line l in the image
00094   vgl_homg_plane_3d<double> backproject(vgl_homg_line_2d<double> const& l) const;
00095 
00096   //: post-multiply this projection matrix with a HMatrix3D
00097   PMatrix postmultiply(vnl_double_4x4 const& H) const;
00098 
00099   //: pre-multiply this projection matrix with a HMatrix2D
00100   PMatrix premultiply(vnl_double_3x3 const& H) const;
00101 
00102   vnl_svd<double>* svd() const; // mutable const
00103   void clear_svd() const;
00104   HomgPoint3D get_focal_point() const;
00105   vgl_homg_point_3d<double> get_focal() const;
00106   HMatrix3D get_canonical_H() const;
00107   bool is_canonical(double tol = 0) const;
00108 
00109   bool is_behind_camera(const HomgPoint3D&);
00110   bool is_behind_camera(vgl_homg_point_3d<double> const&);
00111   void flip_sign();
00112   bool looks_conditioned();
00113   void fix_cheirality();
00114 
00115   // Data Access---------------------------------------------------------------
00116 
00117   PMatrix& operator=(const PMatrix&);
00118 
00119   bool operator==(PMatrix const& p) const { return p_matrix_ == p.get_matrix(); }
00120 
00121   void get(vnl_matrix<double>* A, vnl_vector<double>* a) const;
00122   void get(vnl_double_3x3* A, vnl_double_3* a) const;
00123   void set(const vnl_matrix<double>& A, const vnl_vector<double>& a);
00124 
00125   void get_rows(vnl_vector<double>*, vnl_vector<double>*, vnl_vector<double>*) const;
00126   void get_rows(vnl_vector_fixed<double, 4>*, vnl_vector_fixed<double, 4>*, vnl_vector_fixed<double, 4>*) const;
00127   void set_rows(const vnl_vector<double>&, const vnl_vector<double>&, const vnl_vector<double>&);
00128 
00129   double get(unsigned int row_index, unsigned int col_index) const;
00130   void get(double *c_matrix) const;
00131   void get(vnl_matrix<double>* p_matrix) const;
00132   void get(vnl_double_3x4* p_matrix) const;
00133 
00134   void set(const double* p_matrix);
00135   void set(const double p_matrix [3][4]);
00136   void set(const vnl_matrix<double>& p_matrix);
00137   void set(vnl_double_3x4 const& p_matrix);
00138 
00139   const vnl_double_3x4& get_matrix() const { return p_matrix_; }
00140 
00141   // Utility Methods-----------------------------------------------------------
00142   bool read_ascii(vcl_istream& f);
00143 
00144   // Data Members--------------------------------------------------------------
00145  protected:
00146   vnl_double_3x4 p_matrix_;
00147   mutable vnl_svd<double>* svd_;
00148 };
00149 
00150 vcl_ostream& operator<<(vcl_ostream& s, const PMatrix& p);
00151 vcl_istream& operator>>(vcl_istream& i, PMatrix& p);
00152 
00153 inline
00154 PMatrix operator*(vnl_double_3x3 const& C, const PMatrix& P)
00155 {
00156   return PMatrix(C * P.get_matrix());
00157 }
00158 
00159 #endif // PMatrix_h_