contrib/oxl/mvl/FMatrixComputeLinear.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/FMatrixComputeLinear.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 
00006 //-----------------------------------------------------------------------------
00007 //
00008 // .NAME FMatrixComputeLinear
00009 // Author: Andrew W. Fitzgibbon, Oxford RRG
00010 // Created: 23 Jul 96
00011 //
00012 //-----------------------------------------------------------------------------
00013 
00014 #include "FMatrixComputeLinear.h"
00015 
00016 #include <vcl_vector.h>
00017 #include <vcl_iostream.h>
00018 
00019 #include <vnl/algo/vnl_svd.h>
00020 #include <vgl/vgl_homg_point_2d.h>
00021 
00022 #include <mvl/HomgMetric.h>
00023 #include <mvl/PairMatchSetCorner.h>
00024 #include <mvl/FDesignMatrix.h>
00025 #include <mvl/HomgNorm2D.h>
00026 
00027 FMatrixComputeLinear::FMatrixComputeLinear(bool precondition, bool rank2_truncate):
00028   precondition_(precondition),
00029   rank2_truncate_(rank2_truncate)
00030 {
00031 }
00032 
00033 //-----------------------------------------------------------------------------
00034 //
00035 // - Compute a fundamental matrix for a set of point matches.
00036 //
00037 // Return false if the calculation fails or there are fewer than eight point
00038 // matches in the list.
00039 //
00040 
00041 bool FMatrixComputeLinear::compute (PairMatchSetCorner& matches, FMatrix *F)
00042 {
00043   // Copy matching points from matchset.
00044   vcl_vector<HomgPoint2D> points1(matches.count());
00045   vcl_vector<HomgPoint2D> points2(matches.count());
00046   matches.extract_matches(points1, points2);
00047   return compute(points1, points2, F);
00048 }
00049 
00050 //-----------------------------------------------------------------------------
00051 bool FMatrixComputeLinear::compute (vcl_vector<vgl_homg_point_2d<double> >& points1,
00052                                     vcl_vector<vgl_homg_point_2d<double> >& points2, FMatrix& F)
00053 {
00054   if (points1.size() < 8 || points2.size() < 8) {
00055     vcl_cerr << "FMatrixComputeLinear: Need at least 8 point pairs.\n"
00056              << "Number in each set: " << points1.size() << ", " << points2.size() << vcl_endl;
00057     return false;
00058   }
00059 
00060   if (precondition_) {
00061     // Condition points
00062     HomgNorm2D conditioned1(points1);
00063     HomgNorm2D conditioned2(points2);
00064 
00065     // Compute F with preconditioned points
00066     compute_preconditioned(conditioned1.get_normalized_points(),
00067                            conditioned2.get_normalized_points(),
00068                            &F);
00069 
00070     // De-condition F
00071     F = HomgMetric::homg_to_image_F(F, &conditioned1, &conditioned2);
00072   } else
00073     compute_preconditioned(points1, points2, F);
00074 
00075   return true;
00076 }
00077 
00078 //-----------------------------------------------------------------------------
00079 bool FMatrixComputeLinear::compute (vcl_vector<HomgPoint2D>& points1,
00080                                     vcl_vector<HomgPoint2D>& points2, FMatrix *F)
00081 {
00082   if (points1.size() < 8 || points2.size() < 8) {
00083     vcl_cerr << "FMatrixComputeLinear: Need at least 8 point pairs.\n"
00084              << "Number in each set: " << points1.size() << ", " << points2.size() << vcl_endl;
00085     return false;
00086   }
00087 
00088   if (precondition_) {
00089     // Condition points
00090     HomgNorm2D conditioned1(points1);
00091     HomgNorm2D conditioned2(points2);
00092 
00093     // Compute F with preconditioned points
00094     compute_preconditioned(conditioned1.get_normalized_points(),
00095                            conditioned2.get_normalized_points(),
00096                            F);
00097 
00098     // De-condition F
00099     *F = HomgMetric::homg_to_image_F(*F, &conditioned1, &conditioned2);
00100   } else
00101     compute_preconditioned(points1, points2, F);
00102 
00103   return true;
00104 }
00105 
00106 //-----------------------------------------------------------------------------
00107 bool FMatrixComputeLinear::compute_preconditioned (vcl_vector<vgl_homg_point_2d<double> >& points1,
00108                                                    vcl_vector<vgl_homg_point_2d<double> >& points2,
00109                                                    FMatrix& F)
00110 {
00111   // Create design matrix from conditioned points.
00112   FDesignMatrix design(points1, points2);
00113 
00114   // Normalize rows for better conditioning
00115   design.normalize_rows();
00116 
00117   // Extract vnl_svd<double> of design matrix
00118   vnl_svd<double> svd(design);
00119 
00120   // Reshape nullvector to 3x3
00121   F.set(vnl_double_3x3(svd.nullvector().data_block()));
00122 
00123   // Rank-truncate F
00124   if (rank2_truncate_)
00125     F.set_rank2_using_svd();
00126 
00127   return true;
00128 }
00129 
00130 //-----------------------------------------------------------------------------
00131 bool FMatrixComputeLinear::compute_preconditioned (vcl_vector<HomgPoint2D>& points1,
00132                                                    vcl_vector<HomgPoint2D>& points2,
00133                                                    FMatrix *F)
00134 {
00135   // Create design matrix from conditioned points.
00136   FDesignMatrix design(points1, points2);
00137 
00138   // Normalize rows for better conditioning
00139   design.normalize_rows();
00140 
00141   // Extract vnl_svd<double> of design matrix
00142   vnl_svd<double> svd (design);
00143 
00144   // Reshape nullvector to 3x3
00145   F->set(vnl_double_3x3(svd.nullvector().data_block()));
00146 
00147   // Rank-truncate F
00148   if (rank2_truncate_)
00149     F->set_rank2_using_svd();
00150 
00151   return true;
00152 }