vpgl_fm_compute_8_point.cxx
Go to the documentation of this file.
1 // This is core/vpgl/algo/vpgl_fm_compute_8_point.cxx
2 #ifndef vpgl_fm_compute_8_point_cxx_
3 #define vpgl_fm_compute_8_point_cxx_
4 //:
5 // \file
6 
7 #include <iostream>
9 
10 #include <vnl/vnl_vector.h>
11 #include <vnl/vnl_matrix.h>
12 #include <vnl/vnl_matrix_fixed.h>
13 #include <vnl/algo/vnl_svd.h>
15 #ifdef _MSC_VER
16 # include <vcl_msvc_warnings.h>
17 #endif
18 
19 
20 //-------------------------------------------
21 bool
23  const std::vector< vgl_homg_point_2d<double> >& pr,
24  const std::vector< vgl_homg_point_2d<double> >& pl,
26 {
27  // Check that there are at least 8 points.
28  if ( pr.size() < 8 || pl.size() < 8 ) {
29  std::cerr << "vpgl_fm_compute_8_point: Need at least 8 point pairs.\n"
30  << "Number in each set: " << pr.size() << ", " << pl.size() << std::endl;
31  return false;
32  }
33 
34  // Check that the correspondence lists are the same size.
35  if ( pr.size() != pl.size() ) {
36  std::cerr << "vpgl_fm_compute_7_point: Need correspondence lists of same size.\n";
37  return false;
38  }
39 
40  // Condition if necessary.
41  std::vector< vgl_homg_point_2d<double> > pr_norm, pl_norm;
42  vgl_norm_trans_2d<double> prnt, plnt;
43  if ( precondition_ ) {
44  prnt.compute_from_points(pr);
45  plnt.compute_from_points(pl);
46  for ( unsigned int i = 0; i < pl.size(); i++ ) {
47  pr_norm.push_back( prnt*pr[i] );
48  pl_norm.push_back( plnt*pl[i] );
49  }
50  }
51  else{
52  for ( unsigned int i = 0; i < pl.size(); i++ ) {
53  pr_norm.push_back( pr[i] );
54  pl_norm.push_back( pl[i] );
55  }
56  }
57 
58  // Solve!
59  vnl_matrix<double> S(static_cast<unsigned int>(pr_norm.size()), 9);
60  for ( unsigned int i = 0; i < pr_norm.size(); i++ ) {
61  S(i,0) = pl_norm[i].x()*pr_norm[i].x();
62  S(i,1) = pl_norm[i].x()*pr_norm[i].y();
63  S(i,2) = pl_norm[i].x()*pr_norm[i].w();
64  S(i,3) = pl_norm[i].y()*pr_norm[i].x();
65  S(i,4) = pl_norm[i].y()*pr_norm[i].y();
66  S(i,5) = pl_norm[i].y()*pr_norm[i].w();
67  S(i,6) = pl_norm[i].w()*pr_norm[i].x();
68  S(i,7) = pl_norm[i].w()*pr_norm[i].y();
69  S(i,8) = pl_norm[i].w()*pr_norm[i].w();
70  }
71  vnl_svd<double> svdS( S );
72  vnl_vector<double> solution = svdS.nullvector();
74  F_vnl(0,0) = solution(0); F_vnl(0,1) = solution(1); F_vnl(0,2) = solution(2);
75  F_vnl(1,0) = solution(3); F_vnl(1,1) = solution(4); F_vnl(1,2) = solution(5);
76  F_vnl(2,0) = solution(6); F_vnl(2,1) = solution(7); F_vnl(2,2) = solution(8);
77  if ( precondition_ ) {
78  // As specified in Harley & Zisserman book 2nd ed p282: first rank-enforce *then* denormalize
79  fm.set_matrix( F_vnl ); // constructor enforces rank 2
80  vnl_matrix_fixed<double,3,3> F_vnl_trunc(fm.get_matrix());
81  fm.set_matrix( plnt.get_matrix().transpose()*F_vnl_trunc*prnt.get_matrix() );
82  }
83  else
84  fm.set_matrix( F_vnl );
85  return true;
86 };
87 
88 
89 #endif //vpgl_fm_compute_8_point_cxx_
vnl_matrix_fixed< T, 3, 3 > const & get_matrix() const
vnl_vector< T > nullvector() const
The 8 point algorithm for computing a fundamental matrix from point correspondences.
bool compute(const std::vector< vgl_homg_point_2d< double > > &pr, const std::vector< vgl_homg_point_2d< double > > &pl, vpgl_fundamental_matrix< double > &fm)
Compute from two sets of corresponding points.
vnl_matrix_fixed< T, num_cols, num_rows > transpose() const
bool compute_from_points(std::vector< vgl_homg_point_2d< T > > const &points, bool isotropic=true)
const vnl_matrix_fixed< T, 3, 3 > & get_matrix() const
Get a copy of the FM in vnl form.
void set_matrix(const vpgl_proj_camera< T > &cr, const vpgl_proj_camera< T > &cl)