core/vpgl/algo/vpgl_fm_compute_2_point.cxx
Go to the documentation of this file.
00001 // This is core/vpgl/algo/vpgl_fm_compute_2_point.cxx
00002 #ifndef vpgl_fm_compute_2_point_cxx_
00003 #define vpgl_fm_compute_2_point_cxx_
00004 //:
00005 // \file
00006 
00007 #include "vpgl_fm_compute_2_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_2_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 2 points.
00025   if ( pr.size() < 2 || pl.size() < 2 ) {
00026     vcl_cerr << "vpgl_fm_compute_2_point: Need at least 2 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_2_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   double sl = 1.0, sr = 1.0, cxl=0.0, cyl = 0.0, cxr = 0.0, cyr = 0.0;
00041   bool isotropic = true;
00042   if ( precondition_ ) {
00043     prnt.compute_from_points(pr, isotropic);
00044     vnl_matrix_fixed<double, 3, 3> mr = prnt.get_matrix();
00045     sr = mr[0][0]; cxr = -mr[0][2]/sr; cyr = -mr[1][2]/sr;
00046     plnt.compute_from_points(pl, isotropic);
00047     vnl_matrix_fixed<double, 3, 3> ml = plnt.get_matrix();
00048     sl = ml[0][0]; cxl = -ml[0][2]/sl; cyl = -ml[1][2]/sl;
00049     for ( unsigned int i = 0; i < pl.size(); i++ ) {
00050       pr_norm.push_back( prnt*pr[i] );
00051       pl_norm.push_back( plnt*pl[i] );
00052     }
00053   }
00054   else{
00055     for ( unsigned int i = 0; i < pl.size(); i++ ) {
00056       pr_norm.push_back( pr[i] );
00057       pl_norm.push_back( pl[i] );
00058     }
00059   }
00060   // Solve!
00061   vnl_matrix<double> S(pr_norm.size(),3);
00062   for ( unsigned int i = 0; i < pr_norm.size(); i++ )
00063   {
00064     double xl =pl_norm[i].x(), yl = pl_norm[i].y(), wl = pl_norm[i].w();
00065     double xr =pr_norm[i].x(), yr = pr_norm[i].y(), wr = pr_norm[i].w();
00066     if (!precondition_) {
00067       S(i,0) = yl*wr - yr*wl;
00068       S(i,1) = xr*wl - xl*wr;
00069       S(i,2) = xl*yr - xr*yl;
00070     }
00071     else {
00072       S(i,0) = (sl*sr*wl*wr*(cyl-cyr) + sr*wr*yl - sl*wl*yr);
00073       S(i,1) = (sl*sr*wl*wr*(cxr-cxl) + sl*wl*xr - sr*wr*xl);
00074       S(i,2) = (sl*sr*wl*wr*(cxl*cyr-cxr*cyl) + cyr*sr*wr*xl - cyl*sl*wl*xr
00075                 -cxr*sr*wr*yl + cxl*sl*wl*yr + xl*yr -xr*yl);
00076     }
00077   }
00078   vnl_svd<double> svdS( S );
00079   vnl_vector<double> solution = svdS.nullvector();
00080   vnl_matrix_fixed<double,3,3> F_vnl;
00081   F_vnl(0,0) = 0; F_vnl(0,1) = solution(2); F_vnl(0,2) = -solution(1);
00082   F_vnl(1,0) = -solution(2); F_vnl(1,1) = 0; F_vnl(1,2) = solution(0);
00083   F_vnl(2,0) = solution(1); F_vnl(2,1) = -solution(0); F_vnl(2,2) = 0;
00084   fm.set_matrix( F_vnl );
00085   return true;
00086 }
00087 
00088 
00089 #endif //vpgl_fm_compute_2_point_cxx_