Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "PairMatchSet.h"
00009
00010 #include <vcl_cstdlib.h>
00011 #include <vcl_cassert.h>
00012 #include <vcl_iostream.h>
00013 #include <vcl_vector.h>
00014
00015 #include <mvl/MatchSet.h>
00016
00017 PairMatchSet::iterator PairMatchSet::iterator::operator++ (int )
00018 {
00019 vcl_abort();
00020 return *this;
00021 }
00022
00023
00024 PairMatchSet::PairMatchSet(unsigned size):
00025 matches_(size)
00026 {
00027 clear();
00028 }
00029
00030
00031 PairMatchSet::~PairMatchSet()
00032 {
00033 }
00034
00035
00036
00037 PairMatchSet::PairMatchSet(const PairMatchSet& that):
00038 MatchSet(),
00039 matches_(that.matches_),
00040 match_count_(that.match_count_)
00041 {
00042 }
00043
00044 PairMatchSet& PairMatchSet::operator=(const PairMatchSet& that)
00045 {
00046 matches_ = that.matches_;
00047 match_count_ = that.match_count_;
00048 return *this;
00049 }
00050
00051 void PairMatchSet::update_feature_match_data()
00052 {
00053 assert(false);
00054 }
00055
00056
00057
00058 bool PairMatchSet::add_match(int i1, int i2)
00059 {
00060 if ((unsigned)i1 >= matches_.size()) {
00061 vcl_cerr << "PairMatchSet: add_match(" << i1 << ") greater than size " << matches_.size() << vcl_endl;
00062 vcl_abort();
00063 return false;
00064 }
00065 bool had_nomatch = (matches_[i1] == NoMatch);
00066 bool new_nomatch = (i2 == NoMatch);
00067 matches_[i1] = i2;
00068 if (had_nomatch && !new_nomatch)
00069 ++match_count_;
00070 return true;
00071 }
00072
00073
00074
00075 void PairMatchSet::clear_match_1(int i1)
00076 {
00077 if ((unsigned)i1 >= matches_.size()) {
00078 vcl_cerr << "PairMatchSet: clear squawwk\n";
00079 return;
00080 }
00081 int& i2 = matches_[i1];
00082 if (i2 != MatchSet::NoMatch) {
00083 assert(match_count_ > 0);
00084 --match_count_;
00085 }
00086
00087 i2 = MatchSet::NoMatch;
00088 }
00089
00090
00091
00092 int PairMatchSet::get_match_12(int i1) const
00093 {
00094 if (i1 == MatchSet::NoMatch)
00095 return MatchSet::NoMatch;
00096
00097 if ((unsigned)i1 >= matches_.size()) {
00098 vcl_cerr << "PairMatchSet::get_match_12() -- i1 = " << i1 << " >= matches_.size() = " << matches_.size() << vcl_endl;
00099 vcl_abort();
00100 return -1;
00101 }
00102
00103 return matches_[i1];
00104 }
00105
00106
00107
00108
00109
00110 int PairMatchSet::get_match_21(int i2) const
00111 {
00112 for (unsigned i = 0; i < matches_.size(); ++i)
00113 if (matches_[i] == i2)
00114 return i;
00115 return MatchSet::NoMatch;
00116 }
00117
00118
00119 bool PairMatchSet::get_match(int c, int* i1, int* i2) const
00120 {
00121 if (c >= size())
00122 return false;
00123
00124 *i1 = c;
00125 *i2 = get_match_12(*i1);
00126
00127 return true;
00128 }
00129
00130
00131 void PairMatchSet::clear()
00132 {
00133 for (unsigned i = 0; i < matches_.size(); ++i)
00134 matches_[i] = MatchSet::NoMatch;
00135 match_count_ = 0;
00136 }
00137
00138
00139 void PairMatchSet::set_identity()
00140 {
00141 for (unsigned i = 0; i < matches_.size(); ++i)
00142 matches_[i] = i;
00143 match_count_ = matches_.size();
00144 }
00145
00146
00147 int PairMatchSet::compute_match_count()
00148 {
00149 match_count_ = 0;
00150 for (unsigned i = 0; i < matches_.size(); ++i)
00151 if (matches_[i] != MatchSet::NoMatch)
00152 ++match_count_;
00153
00154 return match_count_;
00155 }
00156
00157
00158 int PairMatchSet::size() const
00159 {
00160 return matches_.size();
00161 }
00162
00163
00164 void PairMatchSet::set_size(unsigned newsize)
00165 {
00166 if (newsize != matches_.size())
00167 matches_ = vcl_vector<int>(newsize, NoMatch);
00168 }
00169
00170 void PairMatchSet::update(const vcl_vector<bool>& inliers)
00171 {
00172 if (inliers.size() != count()) {
00173 vcl_cerr << "PairMatchSet::update() -- This matchset is not the same length as the inliers\n";
00174 vcl_abort();
00175 }
00176
00177 int n = 0;
00178 for (PairMatchSet::iterator match (*this); match; match.next(), ++n)
00179 if (!inliers[n])
00180 clear_match_1(match.get_i1());
00181 }
00182
00183
00184
00185
00186
00187
00188 void PairMatchSet::write_ascii(vcl_ostream& s) const
00189 {
00190 for (unsigned i = 0; i < matches_.size(); ++i) {
00191 int to_index = matches_[i];
00192 if (to_index != NoMatch)
00193 s << i << ' ' << to_index << vcl_endl;
00194 }
00195 }
00196
00197 vcl_ostream& operator<<(vcl_ostream& s, const PairMatchSet& cc)
00198 {
00199 cc.write_ascii(s);
00200 return s;
00201 }
00202
00203 bool PairMatchSet::read_ascii(vcl_istream& s)
00204 {
00205 clear();
00206 for (;;) {
00207
00208 int i1, i2;
00209 s >> i1 >> i2;
00210
00211 if (!s.good())
00212 break;
00213
00214 s >> vcl_ws;
00215
00216
00217 if (i1 < 0 || i2 < 0 || i1 >= (int)matches_.size()) {
00218 vcl_cerr << "PairMatchSet::read_ascii -- Pair " << i1 << '-' << i2 << " is outside the valid range.\n";
00219 clear();
00220 return false;
00221 }
00222
00223
00224 if (matches_[i1] != NoMatch) {
00225 vcl_cerr << "PairMatchSet::read_ascii() -- Warning:\n"
00226 << "Duplicate matches for " << i1 << ": " << matches_[i1] << " and " << i2 << vcl_endl;
00227 return false;
00228 }
00229
00230 matches_[i1] = i2;
00231 }
00232
00233 return compute_match_count() > 0;
00234 }
00235
00236 vcl_istream& operator>>(vcl_istream& s, PairMatchSet& cc)
00237 {
00238 cc.read_ascii(s);
00239 return s;
00240 }
00241
00242
00243 void PairMatchSet::print_brief(vcl_ostream& s) const
00244 {
00245 s << "PairMatchSet: ";
00246 for (unsigned i = 0; i < matches_.size(); i++)
00247 s << matches_[i] << ' ';
00248 s << vcl_endl;
00249 }
00250
00251
00252 void PairMatchSet::print_brief() const
00253 {
00254 unsigned n = matches_.size();
00255 char const *c = "";
00256 if (n > 30) {
00257 n = 30;
00258 c = "...";
00259 }
00260
00261 for (unsigned i = 0; i < n; ++i)
00262 if (matches_[i] != NoMatch)
00263 vcl_cout << ' ' << matches_[i];
00264 vcl_cout << c << vcl_endl;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274 PairMatchSet::iterator::iterator(bool full_only):
00275 c_(0),
00276 match_index_(0),
00277 full_only_(full_only)
00278 {
00279 }
00280
00281
00282 PairMatchSet::iterator::iterator(const PairMatchSet& cc, bool full_only):
00283 c_(&cc),
00284 match_index_(0),
00285 full_only_(full_only)
00286 {
00287 match_index_ = -1;
00288 next();
00289 }
00290
00291
00292 PairMatchSet::iterator& PairMatchSet::iterator::operator =(const PairMatchSet& cc)
00293 {
00294 c_ = &cc;
00295 match_index_ = -1;
00296 next();
00297 return *this;
00298 }
00299
00300
00301 bool PairMatchSet::iterator::next()
00302 {
00303 if (full_only_) {
00304 while (c_->get_match(++match_index_, &i1, &i2))
00305 if (isfull())
00306 return true;
00307 return false;
00308 }
00309 return c_->get_match(++match_index_, &i1, &i2);
00310 }
00311
00312 #if 0 // insert these here for documentation purposes
00313
00314 int PairMatchSet::iterator::get_i1() const
00315 {
00316 return i1;
00317 }
00318
00319
00320 int PairMatchSet::iterator::get_i2() const
00321 {
00322 return i2;
00323 }
00324 #endif
00325
00326
00327
00328 bool PairMatchSet::iterator::isfull() const
00329 {
00330 return i1 != NoMatch && i2 != NoMatch;
00331 }