vpgl_fm_compute_2_point.cxx
Go to the documentation of this file.
1 // This is core/vpgl/algo/vpgl_fm_compute_2_point.cxx
2 #ifndef vpgl_fm_compute_2_point_cxx_
3 #define vpgl_fm_compute_2_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 2 points.
28  if ( pr.size() < 2 || pl.size() < 2 ) {
29  std::cerr << "vpgl_fm_compute_2_point: Need at least 2 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_2_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  double sl = 1.0, sr = 1.0, cxl=0.0, cyl = 0.0, cxr = 0.0, cyr = 0.0;
44  bool isotropic = true;
45  if ( precondition_ ) {
46  prnt.compute_from_points(pr, isotropic);
48  sr = mr[0][0]; cxr = -mr[0][2]/sr; cyr = -mr[1][2]/sr;
49  plnt.compute_from_points(pl, isotropic);
51  sl = ml[0][0]; cxl = -ml[0][2]/sl; cyl = -ml[1][2]/sl;
52  for ( unsigned int i = 0; i < pl.size(); i++ ) {
53  pr_norm.push_back( prnt*pr[i] );
54  pl_norm.push_back( plnt*pl[i] );
55  }
56  }
57  else{
58  for ( unsigned int i = 0; i < pl.size(); i++ ) {
59  pr_norm.push_back( pr[i] );
60  pl_norm.push_back( pl[i] );
61  }
62  }
63  // Solve!
64  vnl_matrix<double> S(static_cast<unsigned int>(pr_norm.size()), 3);
65  for ( unsigned int i = 0; i < pr_norm.size(); i++ )
66  {
67  double xl =pl_norm[i].x(), yl = pl_norm[i].y(), wl = pl_norm[i].w();
68  double xr =pr_norm[i].x(), yr = pr_norm[i].y(), wr = pr_norm[i].w();
69  if (!precondition_) {
70  S(i,0) = yl*wr - yr*wl;
71  S(i,1) = xr*wl - xl*wr;
72  S(i,2) = xl*yr - xr*yl;
73  }
74  else {
75  S(i,0) = (sl*sr*wl*wr*(cyl-cyr) + sr*wr*yl - sl*wl*yr);
76  S(i,1) = (sl*sr*wl*wr*(cxr-cxl) + sl*wl*xr - sr*wr*xl);
77  S(i,2) = (sl*sr*wl*wr*(cxl*cyr-cxr*cyl) + cyr*sr*wr*xl - cyl*sl*wl*xr
78  -cxr*sr*wr*yl + cxl*sl*wl*yr + xl*yr -xr*yl);
79  }
80  }
81  vnl_svd<double> svdS( S );
82  vnl_vector<double> solution = svdS.nullvector();
84  F_vnl(0,0) = 0; F_vnl(0,1) = solution(2); F_vnl(0,2) = -solution(1);
85  F_vnl(1,0) = -solution(2); F_vnl(1,1) = 0; F_vnl(1,2) = solution(0);
86  F_vnl(2,0) = solution(1); F_vnl(2,1) = -solution(0); F_vnl(2,2) = 0;
87  fm.set_matrix( F_vnl );
88  return true;
89 }
90 
91 
92 #endif //vpgl_fm_compute_2_point_cxx_
vnl_matrix_fixed< T, 3, 3 > const & get_matrix() const
vnl_vector< T > nullvector() const
A 2 point algorithm for computing the fundamental matrix for translation from point correspondences.
bool compute_from_points(std::vector< vgl_homg_point_2d< T > > const &points, bool isotropic=true)
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.
void set_matrix(const vpgl_proj_camera< T > &cr, const vpgl_proj_camera< T > &cl)