core/vpgl/vpgl_fundamental_matrix.h
Go to the documentation of this file.
00001 // This is core/vpgl/vpgl_fundamental_matrix.h
00002 #ifndef vpgl_fundamental_matrix_h_
00003 #define vpgl_fundamental_matrix_h_
00004 //:
00005 // \file
00006 // \brief A class for the fundamental matrix between two projective cameras.
00007 // \author Thomas Pollard
00008 // \date January 28, 2005
00009 // \author Joseph Mundy, Matt Leotta, Vishal Jain
00010 //
00011 //  A class which holds the fundamental matrix and performs basic computations with it.
00012 //  More advanced functions using the fundamental matrix can be found in
00013 //  "vpgl_fundamental_matrix_functions.h".
00014 //
00015 //  This implementation forces the rank of the fundamental matrix to be rank 2, and if
00016 //  the matrix is set with a rank 3 matrix, it will be reduced in rank using SVD
00017 //  decomposition.
00018 //
00019 //  The notation "left" and "right" refers to camera producing points used on
00020 //  the left side of the F matrix and vice versa.
00021 //
00022 // \verbatim
00023 //  Modifications
00024 //   May 06, 2009  Ricardo Fabbri   Overloaded {l,r}_epipolar_line to take line as input
00025 //   May 10, 2010 Andrew Hoelscher - Added a constructor based off two
00026 //      calibration matrices and an essential matrix.
00027 // \endverbatim
00028 
00029 #include <vnl/vnl_fwd.h>
00030 #include <vgl/vgl_fwd.h>
00031 #include <vcl_iosfwd.h>
00032 
00033 #include "vpgl_proj_camera.h"
00034 
00035 template <class T> class vpgl_essential_matrix;
00036 template <class T> class vpgl_calibration_matrix;
00037 
00038 template <class T>
00039 class vpgl_fundamental_matrix
00040 {
00041  public:
00042   // Constructors:----------------------
00043 
00044   //: Default constructor creates dummy rank 2 matrix.
00045   vpgl_fundamental_matrix();
00046 
00047   //: Main constructor takes two projective cameras.
00048   //  The RHS of the fundamental matrix will correspond to cr and the LHS to cl.
00049   vpgl_fundamental_matrix( const vpgl_proj_camera<T>& cr,
00050                            const vpgl_proj_camera<T>& cl ) : cached_svd_(NULL)
00051   { set_matrix( cr, cl ); }
00052 
00053   //: Construct from a fundamental matrix in vnl form.
00054   vpgl_fundamental_matrix( const vnl_matrix_fixed<T,3,3>& F ) : cached_svd_(NULL)
00055   { set_matrix( F ); }
00056 
00057   //: Copy Constructor
00058   vpgl_fundamental_matrix(const vpgl_fundamental_matrix<T>& other);
00059 
00060   //: Construct from an essential matrix and two calibration matrices.
00061   // Since E = Kl^T * F * Kr, then F = Kl^-T * E * Kr^-1.
00062   // WARNING! This constructor uses two 3x3 inverse calculations, so it is expensive.
00063   vpgl_fundamental_matrix(const vpgl_calibration_matrix<T> &kr,
00064                           const vpgl_calibration_matrix<T> &kl,
00065                           const vpgl_essential_matrix<T> &em);
00066   //: Assignment
00067   const vpgl_fundamental_matrix<T>& operator=( const vpgl_fundamental_matrix<T>& fm );
00068 
00069   //: Destructor
00070   virtual ~vpgl_fundamental_matrix();
00071 
00072   // Basic Operations:-------------------
00073 
00074   //: Put the coordinates of the epipoles in er, el.
00075   void get_epipoles( vgl_homg_point_2d<T>& er, vgl_homg_point_2d<T>& el ) const;
00076 
00077   //: Given a point in one image, find the corresponding epipolar line in the other image.
00078   vgl_homg_line_2d<T> r_epipolar_line( const vgl_homg_point_2d<T>& pl ) const;
00079   vgl_homg_line_2d<T> l_epipolar_line( const vgl_homg_point_2d<T>& pr ) const;
00080 
00081   //: Given an epipolar line in one image, find the corresponding epipolar line in the other image.
00082   // H&Z 2nd ed p. 247
00083   vgl_homg_line_2d<T> r_epipolar_line(const vgl_homg_line_2d<T> &epiline_l) const;
00084   vgl_homg_line_2d<T> l_epipolar_line(const vgl_homg_line_2d<T> &epiline_r) const;
00085 
00086   //: Gives the left camera matrix corresponding to the fundamental matrix
00087   // The right camera matrix is assumed to be identity.
00088   // The variables v, lambda are free parameters as described in H&Z 2nd ed p. 256.
00089   vpgl_proj_camera<T> extract_left_camera(
00090     const vnl_vector_fixed<T,3>& v, T lambda ) const;
00091 
00092   //: Alternative left camera extractor.
00093   // Takes corresponding lists of image points with their world locations
00094   // to determine the correct camera.  Must give at least 2 pairs of correspondences.
00095   // This is not a robust algorithm but this shouldn't be a problem
00096   // as these correspondences will usually be picked by hand.
00097   vpgl_proj_camera<T> extract_left_camera(
00098     const vcl_vector< vgl_point_3d<T> >& world_points,
00099     const vcl_vector< vgl_point_2d<T> >& image_points ) const;
00100 
00101   // Getters and Setters:----------------
00102 
00103   //: Get a copy of the FM in vnl form.
00104   const vnl_matrix_fixed<T,3,3>& get_matrix() const { return F_; }
00105 
00106   //: Get a copy of the svd of the fundamental matrix.
00107   // The svd is computed when the matrix is first set, so this just accesses a cached version.
00108   const vnl_svd<T>& svd() const{ return *cached_svd_; }
00109 
00110   void set_matrix( const vpgl_proj_camera<T>& cr,
00111                    const vpgl_proj_camera<T>& cl );
00112 
00113   void set_matrix( const vnl_matrix_fixed<T,3,3>& F );
00114 
00115  protected:
00116   //: Internal representation of the fundamental matrix.
00117   vnl_matrix_fixed<T,3,3> F_;
00118 
00119   //: Cached copy of the svd.
00120   mutable vnl_svd<T>* cached_svd_;
00121 };
00122 
00123 //: Write vpgl_fundamental_matrix to stream
00124 template <class T>
00125 vcl_ostream&  operator<<(vcl_ostream& s, vpgl_fundamental_matrix<T> const& p);
00126 
00127 //: Read vpgl_fundamental_matrix from stream
00128 template <class T>
00129 vcl_istream&  operator>>(vcl_istream& s, vpgl_fundamental_matrix<T>& p);
00130 
00131 #endif // vpgl_fundamental_matrix_h_