00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "TripleMatchSet.h"
00009
00010 #include <vcl_cstdlib.h>
00011 #include <vcl_iostream.h>
00012 #include <vnl/vnl_matrix.h>
00013 #include <mvl/PairMatchSet.h>
00014
00015
00016
00017
00018 TripleMatchSet::TripleMatchSet(PairMatchSet* match12, PairMatchSet* match23)
00019 {
00020 match12_ = match12;
00021 match23_ = match23;
00022 }
00023
00024
00025
00026
00027 TripleMatchSet::TripleMatchSet(int i1_max, int i2_max, int)
00028 {
00029 match12_ = new PairMatchSet(i1_max);
00030 match23_ = new PairMatchSet(i2_max);
00031 }
00032
00033
00034 TripleMatchSet::~TripleMatchSet()
00035 {
00036 delete match12_;
00037 delete match23_;
00038 }
00039
00040
00041 void TripleMatchSet::set(PairMatchSet* match12, PairMatchSet* match23)
00042 {
00043 delete match12_;
00044 delete match23_;
00045 match12_ = match12;
00046 match23_ = match23;
00047 }
00048
00049
00050
00051
00052
00053
00054 void TripleMatchSet::set_from_pairwise_matches(const PairMatchSet& matches12,
00055 const PairMatchSet& matches23)
00056 {
00057 clear_matches();
00058 for (PairMatchSet::iterator p12 = matches12; p12; p12.next()) {
00059 int i3 = matches23.get_match_12(p12.get_i2());
00060 if (matchp(i3))
00061 add_match(p12.get_i1(), p12.get_i2(), i3);
00062 }
00063 vcl_cerr << "TripleMatchSet: " << count() << " triplet matches.\n";
00064 }
00065
00066
00067 void TripleMatchSet::write_ascii(vcl_ostream & s) const
00068 {
00069 for (iterator match = begin(); match; ++match) {
00070 s << match.get_i1() << '\t'
00071 << match.get_i2() << '\t'
00072 << match.get_i3() << '\n';
00073 }
00074 }
00075
00076
00077 bool TripleMatchSet::read_ascii(vcl_istream& s)
00078 {
00079 vnl_matrix<double> m;
00080 s >> m;
00081 if (!s.good() && !s.eof())
00082 return false;
00083
00084 if (m.columns() != 3) {
00085 vcl_cerr << "TripleMatchSet::read_ascii(): cols = " << m.columns() << ", not 3\n";
00086 return false;
00087 }
00088
00089 int n = m.rows();
00090
00091 int i1_max = 0;
00092 int i2_max = 0;
00093 for (int i = 0; i < n; ++i) {
00094 if (m(i,0) > i1_max) i1_max = (int)m(i,0);
00095 if (m(i,1) > i2_max) i2_max = (int)m(i,2);
00096 }
00097
00098 clear_matches();
00099
00100
00101 {
00102 for (int i = 0; i < n; ++i)
00103 add_match(int(m(i,0)), int(m(i,1)), int(m(i,2)));
00104 }
00105
00106 return true;
00107 }
00108
00109
00110 vcl_ostream& operator << (vcl_ostream& s, const TripleMatchSet& matches)
00111 {
00112 s << "# TripleMatchSet: " << matches.count() << " triplet matches.\n";
00113 matches.write_ascii(s);
00114 return s;
00115 }
00116
00117 vcl_istream& operator >> (vcl_istream& s, TripleMatchSet& matches)
00118 {
00119 matches.read_ascii(s);
00120 return s;
00121 }
00122
00123
00124
00125
00126
00127 bool TripleMatchSet::add_match(int i1, int i2, int i3)
00128 {
00129 if (get_match_23(i2) != MatchSet::NoMatch) {
00130 vcl_cerr << "TripleMatchSet::add_match(" <<i1<< ", "<<i2<<", "<<i3<<")\n";
00131 int old_i1 = get_match_21(i2);
00132 int old_i3 = get_match_23(i2);
00133 vcl_cerr<<"*** i2 is already in a match ("<<old_i1<<'/'<<i2<<'/'<<old_i3<<")\n";
00134 }
00135
00136 if (get_match_12(i1) != MatchSet::NoMatch) {
00137 vcl_cerr<<"TripleMatchSet::add_match("<<i1<<", "<<i2<<", "<<i3<<")\n";
00138 int old_i2 = get_match_12(i1);
00139 int old_i3 = get_match_23(old_i2);
00140 vcl_cerr<<"*** i1 is already in a match ("<<i1<<'/'<<old_i2<<'/'<<old_i3<<")\n";
00141 }
00142
00143 return match12_->add_match(i1, i2) && match23_->add_match(i2, i3);
00144 }
00145
00146
00147 int TripleMatchSet::count() const
00148 {
00149 int c = 0;
00150 for (iterator match = begin(); match; match.next())
00151 ++c;
00152 return c;
00153 }
00154
00155
00156 void TripleMatchSet::clear_matches()
00157 {
00158 match12_->clear();
00159 match23_->clear();
00160 }
00161
00162
00163
00164
00165 int TripleMatchSet::get_match_12(int i1) const
00166 {
00167 return match12_->get_match_12(i1);
00168 }
00169
00170
00171
00172 int TripleMatchSet::get_match_13(int i1) const
00173 {
00174 return get_match_23(get_match_12(i1));
00175 }
00176
00177
00178 int TripleMatchSet::get_match_23(int i2) const
00179 {
00180 return match23_->get_match_12(i2);
00181 }
00182
00183
00184 int TripleMatchSet::get_match_21(int i2) const
00185 {
00186 return match12_->get_match_21(i2);
00187 }
00188
00189
00190 int TripleMatchSet::get_match_31(int i3) const
00191 {
00192 return get_match_21(get_match_32(i3));
00193 }
00194
00195
00196 int TripleMatchSet::get_match_32(int i3) const
00197 {
00198 return match23_->get_match_21(i3);
00199 }
00200
00201
00202
00203 int TripleMatchSet::get_match_123(int i1, int i2) const
00204 {
00205 int ii = match12_->get_match_12(i1);
00206 if (ii != i2)
00207 return MatchSet::NoMatch;
00208 else
00209 return get_match_23(i2);
00210 }
00211
00212
00213
00214 bool TripleMatchSet::get_1(int c, int* i1, int* i2, int* i3) const
00215 {
00216 if (c >= match12_->size())
00217 return false;
00218
00219 *i1 = c;
00220 *i2 = match12_->get_match_12(*i1);
00221 *i3 = match23_->get_match_12(*i2);
00222
00223 return true;
00224 }
00225
00226
00227 bool TripleMatchSet::get_2(int c, int* i1, int* i2, int* i3) const
00228 {
00229 return get_1(get_match_21(c), i1, i2, i3);
00230 }
00231
00232
00233 bool TripleMatchSet::get_3(int c, int* i1, int* i2, int* i3) const
00234 {
00235 return get_1(get_match_31(c), i1, i2, i3);
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245 void TripleMatchSet::clear_nontriplets()
00246 {
00247
00248 vcl_vector<bool> accept(match23_->size());
00249 for (vcl_vector<bool>::iterator i=accept.begin(); i!=accept.end(); ++i)
00250 *i = false;
00251
00252 int cleared_count = 0;
00253 for (int i1 = 0; i1 < match12_->size(); i1++) {
00254 int i2 = match12_->get_match_12(i1);
00255 if (i2 != NoMatch) {
00256 int i3 = NoMatch;
00257 if (i2 >= match23_->size() || i2 < 0)
00258 vcl_cerr << "TripleMatchSet::clear_nontriplets() -- bad i2 = " << i2 << vcl_endl;
00259 else
00260 i3 = match23_->get_match_12(i2);
00261
00262 if (i3 == NoMatch) {
00263 match12_->add_match(i1, NoMatch);
00264 ++cleared_count;
00265 }
00266 else
00267 accept[i2] = true;
00268 }
00269 }
00270 vcl_cerr << "TripleMatchSet::clear_nontriplets() -- Cleared i2 " << cleared_count << vcl_endl;
00271
00272 for (int i2 = 0; i2 < match23_->size(); i2++)
00273 if (!accept[i2]) {
00274 match23_->add_match(i2, NoMatch);
00275 ++cleared_count;
00276 }
00277
00278 vcl_cerr << "TripleMatchSet::clear_nontriplets() -- Cleared i3 " << cleared_count << vcl_endl;
00279 }
00280
00281 bool TripleMatchSet::delete_match(int i1, int i2, int i3)
00282 {
00283 int old_12 = match12_->get_match_12(i1);
00284 if (old_12 != i2) {
00285 vcl_cerr << "TripleMatchSet::delete_match - old/new i2 = " << old_12 << '/' << i2 << vcl_endl;
00286 match23_->clear_match_1(old_12);
00287 }
00288 int old_23 = match23_->get_match_12(i2);
00289 if (old_23 != i3) {
00290 vcl_cerr << "TripleMatchSet::delete_match - old/new i3 = " << old_23 << '/' << i3 << vcl_endl;
00291 }
00292
00293 match12_->clear_match_1(i1);
00294 match23_->clear_match_1(i2);
00295
00296 return true;
00297 }
00298
00299
00300 int TripleMatchSet::size() const
00301 {
00302 return match12_->size();
00303 }
00304
00305
00306 void TripleMatchSet::update_feature_match_data()
00307 {
00308 match12_->update_feature_match_data();
00309 match23_->update_feature_match_data();
00310 }
00311
00312
00313
00314
00315 #if 0
00316 TripleMatchSet::iterator::iterator(bool)
00317 {
00318 vcl_abort();
00319 }
00320 #endif
00321
00322
00323
00324 TripleMatchSet::iterator::iterator(const TripleMatchSet& ccc, bool full_only):
00325 c_(&ccc),
00326 match_index_(0),
00327 full_only_(full_only)
00328 {
00329 match_index_ = -1;
00330 next();
00331 }
00332
00333
00334 bool TripleMatchSet::iterator::next()
00335 {
00336 if (full_only_) {
00337 while (c_->get_match(++match_index_, &i1, &i2, &i3))
00338 if (isfull())
00339 return true;
00340 return false;
00341 }
00342 return c_->get_match(++match_index_, &i1, &i2, &i3);
00343 }
00344
00345
00346 TripleMatchSet::iterator::operator bool () const
00347 {
00348 return match_index_ < c_->size();
00349 }
00350
00351
00352
00353 bool TripleMatchSet::iterator::isfull() const
00354 {
00355 return i1 != NoMatch && i2 != NoMatch && i3 != NoMatch;
00356 }
00357
00358
00359 #if 0
00360 MA_MATCH_TABLE_STR* TripleMatchSet::make_matchtable()
00361 {
00362 return mt_3image_affinity_to_match (match12_->get_table(), match23_->get_table());
00363 }
00364
00365 MA_MATCH_TABLE_STR* TripleMatchSet::make_matchtable_12()
00366 {
00367
00368
00369 return mt_3image_affinity_to_match (match12_->get_table(), match23_->get_table());
00370 }
00371
00372 MA_MATCH_TABLE_STR* TripleMatchSet::make_matchtable_23()
00373 {
00374 return mt_3image_affinity123_to_match23 (match12_->get_table(), match23_->get_table());
00375 }
00376
00377 void TripleMatchSet::update_from(MA_MATCH_TABLE_STR* matchtable)
00378 {
00379 mt_3image_match_to_affinity (matchtable, match12_->get_table(), match23_->get_table());
00380 }
00381 #endif
00382