core/vpgl/algo/vpgl_em_compute_5_point.h
Go to the documentation of this file.
00001 // This is core/vpgl/algo/vpgl_em_compute_5_point.h
00002 #ifndef vpgl_em_compute_5_point_h_
00003 #define vpgl_em_compute_5_point_h_
00004 //:
00005 // \file
00006 // \brief The 5 point algorithm as described by David Nister for computing an essential matrix from point correspondences.
00007 // \author Noah Snavely, ported to VXL by Andrew Hoelscher
00008 // \date April 24, 2011
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //      August 31, 2011  Andrew Hoelscher   Added a ransac routine
00013 // \endverbatim
00014 
00015 #include <vcl_vector.h>
00016 
00017 #include <vnl/vnl_matrix.h>
00018 #include <vnl/vnl_vector_fixed.h>
00019 #include <vnl/vnl_real_npolynomial.h>
00020 
00021 #include <vgl/vgl_point_2d.h>
00022 
00023 #include <vpgl/vpgl_essential_matrix.h>
00024 #include <vpgl/vpgl_calibration_matrix.h>
00025 
00026 
00027 template <class T>
00028 class vpgl_em_compute_5_point
00029 {
00030   public:
00031 
00032     vpgl_em_compute_5_point(): verbose(false), tolerance(0.0001) { }
00033     vpgl_em_compute_5_point(bool v): verbose(v), tolerance(0.0001) { }
00034     vpgl_em_compute_5_point(bool v, double t): verbose(v), tolerance(t) { }
00035 
00036     //: Compute from two sets of corresponding points.
00037     // Puts the resulting matrix into em, returns true if successful.
00038     // Each of right_points and left_points must contain exactly 5 points!
00039     // This function returns a set of potential solutions, generally 10.
00040     // Each of these solutions is appropriate to use as RANSAC hypthosis.
00041     //
00042     // The points must be normalized!! Use the function below to avoid
00043     // normalizing the points yourself.
00044     bool compute( const vcl_vector<vgl_point_2d<T> > &normed_right_points,
00045                   const vcl_vector<vgl_point_2d<T> > &normed_left_points,
00046                   vcl_vector<vpgl_essential_matrix<T> > &ems) const;
00047 
00048     //Same as above, but performs the normalization using the two
00049     // calibration matrices.
00050     bool compute( const vcl_vector<vgl_point_2d<T> > &right_points,
00051                   const vpgl_calibration_matrix<T> &k_right,
00052                   const vcl_vector<vgl_point_2d<T> > &left_points,
00053                   const vpgl_calibration_matrix<T> &k_left,
00054                   vcl_vector<vpgl_essential_matrix<T> > &ems) const;
00055 
00056   protected:
00057     const bool verbose;
00058     const double tolerance;
00059 
00060     void normalize(
00061         const vcl_vector<vgl_point_2d<T> > &points,
00062         const vpgl_calibration_matrix<T> &k,
00063         vcl_vector<vgl_point_2d<T> > &normed_points) const;
00064 
00065     void compute_nullspace_basis(
00066         const vcl_vector<vgl_point_2d<T> > &right_points,
00067         const vcl_vector<vgl_point_2d<T> > &left_points,
00068         vcl_vector<vnl_vector_fixed<T, 9> > &basis) const;
00069 
00070     void compute_constraint_polynomials(
00071         const vcl_vector<vnl_vector_fixed<T,9> > &basis,
00072         vcl_vector<vnl_real_npolynomial> &constraints) const;
00073 
00074     void compute_groebner_basis(
00075         const vcl_vector<vnl_real_npolynomial> &constraints,
00076         vnl_matrix<double> &groebner_basis) const;
00077 
00078     void compute_action_matrix(
00079         const vnl_matrix<double> &groebner_basis,
00080         vnl_matrix<double> &action_matrix) const;
00081 
00082     void compute_e_matrices(
00083         const vcl_vector<vnl_vector_fixed<T, 9> > &basis,
00084         const vnl_matrix<double> &action_matrix,
00085         vcl_vector<vpgl_essential_matrix<T> > &ems) const;
00086 
00087     double get_coeff(
00088         const vnl_real_npolynomial &p,
00089         unsigned int x_p, unsigned int y_p, unsigned int z_p) const;
00090 };
00091 
00092 
00093 template <class T>
00094 class vpgl_em_compute_5_point_ransac
00095 {
00096     public:
00097         vpgl_em_compute_5_point_ransac() :
00098             num_rounds(512u), inlier_threshold(2.25), verbose(false) { }
00099 
00100         vpgl_em_compute_5_point_ransac(unsigned nr, double trsh, bool v) :
00101             num_rounds(nr), inlier_threshold(trsh), verbose(v) { }
00102 
00103     bool compute(
00104         vcl_vector<vgl_point_2d<T> > const& right_points,
00105         vpgl_calibration_matrix<T> const& right_k,
00106         vcl_vector<vgl_point_2d<T> > const& left_points,
00107         vpgl_calibration_matrix<T> const& left_k,
00108 
00109         vpgl_essential_matrix<T> &best_em) const;
00110 
00111 
00112     private:
00113         const unsigned num_rounds;
00114         const double inlier_threshold;
00115         const bool verbose;
00116 };
00117 
00118 #endif // vpgl_em_compute_5_point_h_