Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "NViewMatches.h"
00009
00010 #include <vcl_cassert.h>
00011 #include <vcl_cstdlib.h>
00012 #include <vcl_fstream.h>
00013 #include <vul/vul_awk.h>
00014 #include <vul/vul_printf.h>
00015
00016
00017
00018 vcl_ostream& operator<<(vcl_ostream& s, const NViewMatch& c)
00019 {
00020 for (unsigned i = 0; i < c.size(); ++i)
00021 vul_printf(s, "%-4d ", c[i]);
00022
00023 return s;
00024 }
00025
00026
00027
00028
00029
00030 bool NViewMatch::matches(const NViewMatch& b, int min_overlap) const
00031 {
00032 unsigned l = size();
00033
00034 if (l != b.size()) {
00035 vcl_cerr << "NViewMatch::matches(B): matching vectors of different lengths\n";
00036 return false;
00037 }
00038
00039 int overlap = 0;
00040 for (unsigned i = 0; i < l; ++i)
00041 if ((*this)[i] != NViewMatch::nomatch && b[i] != NViewMatch::nomatch) {
00042 if ((*this)[i] != b[i])
00043 return false;
00044 ++overlap;
00045 }
00046 return overlap >= min_overlap;
00047 }
00048
00049
00050 void NViewMatch::incorporate(const NViewMatch& b)
00051 {
00052 unsigned l = size();
00053 for (unsigned i = 0; i < l; ++i)
00054 if ((*this)[i] == NViewMatch::nomatch)
00055 (*this)[i] = b[i];
00056 }
00057
00058
00059 bool NViewMatch::is_consistent(const NViewMatch& b) const
00060 {
00061 unsigned l = size();
00062 for (unsigned i = 0; i < l; ++i)
00063 if ((*this)[i] != NViewMatch::nomatch && b[i] != NViewMatch::nomatch)
00064 if ((*this)[i] != b[i])
00065 return false;
00066 return true;
00067 }
00068
00069
00070 int NViewMatch::count_observations() const
00071 {
00072 unsigned l = size();
00073 int c = 0;
00074 for (unsigned i = 0; i < l; ++i)
00075 if ((*this)[i] != NViewMatch::nomatch)
00076 ++c;
00077 return c;
00078 }
00079
00080
00081
00082
00083 NViewMatches::NViewMatches():
00084 _min_overlap(2)
00085 {
00086 }
00087
00088 NViewMatches::NViewMatches(vcl_istream& s)
00089 {
00090 load(s);
00091 }
00092
00093 NViewMatches::NViewMatches(const char* filename)
00094 {
00095 load(filename);
00096 }
00097
00098 NViewMatches::NViewMatches(int nviews, int min_overlap):
00099 _nviews(nviews), _min_overlap(min_overlap)
00100 {
00101 }
00102
00103 NViewMatches::~NViewMatches() {
00104
00105 }
00106
00107 void NViewMatches::clear()
00108 {
00109 resize(0);
00110 }
00111
00112 bool NViewMatches::load(const char* filename)
00113 {
00114 vcl_ifstream s(filename);
00115 if (!s.good()) {
00116 vcl_cerr << "NViewMatches::load(" << filename << ") - bad filename\n";
00117 return false;
00118 }
00119 return load(s);
00120 }
00121
00122 bool NViewMatches::load(vcl_istream& s)
00123 {
00124 clear();
00125 for (vul_awk awk(s); awk; ++awk) {
00126
00127
00128 if (awk.NR() == 1)
00129 _nviews = awk.NF();
00130 else
00131 if (awk.NF() != _nviews) {
00132 vcl_cerr << "NViewMatches::load() ERROR: only " << awk.NF() << " fields on line " << awk.NR() << vcl_endl;
00133 return false;
00134 }
00135
00136
00137 NViewMatch v(_nviews);
00138 for (int j = 0; j < _nviews; ++j) {
00139 char const* cp = awk[j];
00140 if (cp[0] == '*')
00141 v[j] = NViewMatch::nomatch;
00142 else
00143 v[j] = atoi(cp);
00144 }
00145 push_back(v);
00146 }
00147
00148 return true;
00149 }
00150
00151 bool NViewMatches::save(vcl_ostream& s)
00152 {
00153 for (unsigned i = 0; i < size(); ++i)
00154 s << (*this)[i] << "\n";
00155 return s.good() != 0;
00156 }
00157
00158 bool NViewMatches::save(const char* filename)
00159 {
00160 vcl_ofstream o(filename);
00161 return save(o);
00162 }
00163
00164
00165 int NViewMatches::count_matches(const NViewMatch& match)
00166 {
00167 int nmatches = 0;
00168 for (unsigned i = 0; i < size(); ++i)
00169 if ((*this)[i].matches(match,_min_overlap))
00170 ++nmatches;
00171 return nmatches;
00172 }
00173
00174
00175 vcl_vector<int> NViewMatches::get_matches(const NViewMatch& match)
00176 {
00177 vcl_vector<int> ret;
00178 for (unsigned i = 0; i < size(); ++i)
00179 if (operator[](i).matches(match,_min_overlap))
00180 ret.push_back(i);
00181 return ret;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 int NViewMatches::incorporate(const NViewMatch& newtrack)
00199 {
00200 int nmatches = 0;
00201 iterator merged = end();
00202 vcl_abort();
00203 for (iterator i = begin(); i != end(); ++i) {
00204 if ((*i).matches(newtrack,_min_overlap)) {
00205 if (nmatches == 0) {
00206
00207 (*i).incorporate(newtrack);
00208 ++nmatches;
00209 merged = i;
00210 } else {
00211 if ((*i).is_consistent(*merged)) {
00212 vcl_cerr << "Merge : " << (*i) << vcl_endl;
00213 vcl_cerr << " " << (*merged) << vcl_endl;
00214
00215 (*merged).incorporate((*i));
00216 erase(i);
00217 --i;
00218 ++nmatches;
00219 } else {
00220
00221
00222 erase(i);
00223 erase(merged);
00224 return -1;
00225 }
00226 }
00227 }
00228 }
00229 if (nmatches == 0) {
00230 push_back(newtrack);
00231 return size() - 1;
00232 }
00233
00234
00235
00236
00237
00238 return merged - begin();
00239 }
00240
00241
00242 NViewMatch NViewMatches::make_triplet_match(int base_view, int c1, int c2, int c3)
00243 {
00244 assert(base_view+2 < _nviews);
00245 NViewMatch newtrack(_nviews);
00246 newtrack[base_view] = c1;
00247 newtrack[base_view+1] = c2;
00248 newtrack[base_view+2] = c3;
00249 return newtrack;
00250 }
00251
00252
00253 int NViewMatches::incorporate_triplet(int base_view, int c1, int c2, int c3)
00254 {
00255 assert(base_view+2 < _nviews);
00256 NViewMatch newtrack(_nviews);
00257 newtrack[base_view] = c1;
00258 newtrack[base_view+1] = c2;
00259 newtrack[base_view+2] = c3;
00260 return incorporate(newtrack);
00261 }
00262
00263
00264
00265 void NViewMatches::remove_inconsistencies() {
00266 }