core/vpgl/algo/vpgl_fm_compute_8_point.cxx
Go to the documentation of this file.
00001 // This is core/vpgl/algo/vpgl_fm_compute_8_point.cxx
00002 #ifndef vpgl_fm_compute_8_point_cxx_
00003 #define vpgl_fm_compute_8_point_cxx_
00004 //:
00005 // \file
00006 
00007 #include "vpgl_fm_compute_8_point.h"
00008 
00009 #include <vnl/vnl_vector.h>
00010 #include <vnl/vnl_matrix.h>
00011 #include <vnl/vnl_matrix_fixed.h>
00012 #include <vnl/algo/vnl_svd.h>
00013 #include <vgl/algo/vgl_norm_trans_2d.h>
00014 #include <vcl_iostream.h>
00015 
00016 
00017 //-------------------------------------------
00018 bool
00019 vpgl_fm_compute_8_point::compute(
00020   const vcl_vector< vgl_homg_point_2d<double> >& pr,
00021   const vcl_vector< vgl_homg_point_2d<double> >& pl,
00022   vpgl_fundamental_matrix<double>& fm )
00023 {
00024   // Check that there are at least 8 points.
00025   if ( pr.size() < 8 || pl.size() < 8 ) {
00026     vcl_cerr << "vpgl_fm_compute_8_point: Need at least 8 point pairs.\n"
00027              << "Number in each set: " << pr.size() << ", " << pl.size() << vcl_endl;
00028     return false;
00029   }
00030 
00031   // Check that the correspondence lists are the same size.
00032   if ( pr.size() != pl.size() ) {
00033     vcl_cerr << "vpgl_fm_compute_7_point: Need correspondence lists of same size.\n";
00034     return false;
00035   }
00036 
00037   // Condition if necessary.
00038   vcl_vector< vgl_homg_point_2d<double> > pr_norm, pl_norm;
00039   vgl_norm_trans_2d<double> prnt, plnt;
00040   if ( precondition_ ) {
00041     prnt.compute_from_points(pr);
00042     plnt.compute_from_points(pl);
00043     for ( unsigned int i = 0; i < pl.size(); i++ ) {
00044       pr_norm.push_back( prnt*pr[i] );
00045       pl_norm.push_back( plnt*pl[i] );
00046     }
00047   }
00048   else{
00049     for ( unsigned int i = 0; i < pl.size(); i++ ) {
00050       pr_norm.push_back( pr[i] );
00051       pl_norm.push_back( pl[i] );
00052     }
00053   }
00054 
00055   // Solve!
00056   vnl_matrix<double> S(pr_norm.size(),9);
00057   for ( unsigned int i = 0; i < pr_norm.size(); i++ ) {
00058     S(i,0) = pl_norm[i].x()*pr_norm[i].x();
00059     S(i,1) = pl_norm[i].x()*pr_norm[i].y();
00060     S(i,2) = pl_norm[i].x()*pr_norm[i].w();
00061     S(i,3) = pl_norm[i].y()*pr_norm[i].x();
00062     S(i,4) = pl_norm[i].y()*pr_norm[i].y();
00063     S(i,5) = pl_norm[i].y()*pr_norm[i].w();
00064     S(i,6) = pl_norm[i].w()*pr_norm[i].x();
00065     S(i,7) = pl_norm[i].w()*pr_norm[i].y();
00066     S(i,8) = pl_norm[i].w()*pr_norm[i].w();
00067   }
00068   vnl_svd<double> svdS( S );
00069   vnl_vector<double> solution = svdS.nullvector();
00070   vnl_matrix_fixed<double,3,3> F_vnl;
00071   F_vnl(0,0) = solution(0); F_vnl(0,1) = solution(1); F_vnl(0,2) = solution(2);
00072   F_vnl(1,0) = solution(3); F_vnl(1,1) = solution(4); F_vnl(1,2) = solution(5);
00073   F_vnl(2,0) = solution(6); F_vnl(2,1) = solution(7); F_vnl(2,2) = solution(8);
00074   if ( precondition_ ) {
00075     // As specified in Harley & Zisserman book 2nd ed p282: first rank-enforce *then* denormalize
00076     fm.set_matrix( F_vnl ); // constructor enforces rank 2
00077     vnl_matrix_fixed<double,3,3> F_vnl_trunc(fm.get_matrix());
00078     fm.set_matrix( plnt.get_matrix().transpose()*F_vnl_trunc*prnt.get_matrix() );
00079   }
00080   else
00081     fm.set_matrix( F_vnl );
00082   return true;
00083 };
00084 
00085 
00086 #endif //vpgl_fm_compute_8_point_cxx_