contrib/oxl/mvl/PairMatchSetCorner.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/PairMatchSetCorner.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 
00008 #include "PairMatchSetCorner.h"
00009 
00010 #include <vcl_cassert.h>
00011 #include <vcl_cstdlib.h>
00012 #include <vcl_vector.h>
00013 #include <vcl_iostream.h>
00014 #include <mvl/HomgInterestPointSet.h>
00015 
00016 //: Constructor
00017 PairMatchSetCorner::PairMatchSetCorner() : corners1_(0) , corners2_(0)
00018 {
00019 }
00020 
00021 //: Construct a PairMatchSetCorner that will contain matches between the given HomgInterestPointSets.
00022 // These objects are held by reference in the MatchSet and must therefore
00023 // live longer than the PairMatchSetCorner (for example in an MViewDatabase).
00024 PairMatchSetCorner::PairMatchSetCorner(HomgInterestPointSet const* corners1,
00025                                        HomgInterestPointSet const* corners2)
00026   : corners1_(0) , corners2_(0)
00027 {
00028   set(corners1, corners2);
00029 }
00030 
00031 //: Copy a PairMatchSetCorner
00032 PairMatchSetCorner::PairMatchSetCorner(const PairMatchSetCorner& that):
00033   PairMatchSet(that) , corners1_(0) , corners2_(0)
00034 {
00035   set(that.corners1_, that.corners2_);
00036 }
00037 
00038 PairMatchSetCorner& PairMatchSetCorner::operator=(const PairMatchSetCorner&that)
00039 {
00040   set(that.corners1_, that.corners2_);
00041   PairMatchSet::operator= (that);
00042   return *this;
00043 }
00044 
00045 //: Destructor
00046 PairMatchSetCorner::~PairMatchSetCorner()
00047 {
00048 }
00049 
00050 // Data Control--------------------------------------------------------------
00051 
00052 //: Set the pair of HomgInterestPointSets to which matches refer.
00053 // See the constructor for constraints.
00054 void PairMatchSetCorner::set(HomgInterestPointSet const* corners1,
00055                              HomgInterestPointSet const* corners2)
00056 {
00057   corners1_ = corners1;
00058   corners2_ = corners2;
00059   if (corners1_)
00060     set_size(corners1_->size());
00061   else
00062     set_size(0);
00063 }
00064 
00065 //: Extract the point vectors for only the valid matches.
00066 // For example, given a set of matches between corner features,
00067 // this function copies the inliers to a pair of arrays which
00068 // can then be fed to a non-robust matcher.
00069 void PairMatchSetCorner::extract_matches(vcl_vector<HomgPoint2D>& points1,
00070                                          vcl_vector<HomgPoint2D>& points2) const
00071 {
00072   int n = count();
00073   points1.resize(n);
00074   points2.resize(n);
00075   int i = 0;
00076   for (PairMatchSet::iterator match = *this; match; ++match) {
00077     points1[i] = corners1_->get_homg(match.get_i1());
00078     points2[i] = corners2_->get_homg(match.get_i2());
00079     ++i;
00080     if (i > n) {
00081       vcl_cerr << "ERRRRRK!";
00082       vcl_abort();
00083     }
00084   }
00085   assert(i == n);
00086 }
00087 
00088 //: Extract the point vectors for only the valid matches.
00089 // In addition, return the corresponding point indices in corner_index_[12].
00090 // Thus, points1[0] = corner_set_1()[corner_index_1[0]].
00091 // This is useful with procedures such as RANSAC.
00092 void PairMatchSetCorner::extract_matches(vcl_vector<HomgPoint2D>& points1,
00093                                          vcl_vector<int>& corner_index_1,
00094                                          vcl_vector<HomgPoint2D>& points2,
00095                                          vcl_vector<int>& corner_index_2) const
00096 {
00097   unsigned n = count();
00098   points1.resize(n);
00099   points2.resize(n);
00100   corner_index_1.resize(n);
00101   corner_index_2.resize(n);
00102   int i = 0;
00103   for (PairMatchSet::iterator match = *this; match; match.next()) {
00104     corner_index_1[i] = match.get_i1();
00105     corner_index_2[i] = match.get_i2();
00106     points1[i] = corners1_->get_homg(match.get_i1());
00107     points2[i] = corners2_->get_homg(match.get_i2());
00108     ++i;
00109   }
00110 }
00111 
00112 //: Clear all matches and then set only those for which the corresponding inliers flag is set.
00113 //  For example, if inliers[5] == true, then the match
00114 // (corner_index_1[5], corner_index_2[5]) is added to the set.
00115 void PairMatchSetCorner::set(const vcl_vector<bool>& inliers,
00116                              const vcl_vector<int>&  corner_index_1,
00117                              const vcl_vector<int>&  corner_index_2)
00118 {
00119   clear();
00120   unsigned n = inliers.size();
00121   for (unsigned i = 0; i < n; ++i)
00122     if (inliers[i])
00123       add_match(corner_index_1[i], corner_index_2[i]);
00124 }