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
00108 void NViewMatches::clear()
00109 {
00110 resize(0);
00111 }
00112
00113 bool NViewMatches::load(const char* filename)
00114 {
00115 vcl_ifstream s(filename);
00116 if (!s.good()) {
00117 vcl_cerr << "NViewMatches::load(" << filename << ") - bad filename\n";
00118 return false;
00119 }
00120 return load(s);
00121 }
00122
00123 bool NViewMatches::load(vcl_istream& s)
00124 {
00125 clear();
00126 for (vul_awk awk(s); awk; ++awk) {
00127
00128
00129 if (awk.NR() == 1)
00130 nviews_ = awk.NF();
00131 else
00132 if (awk.NF() != nviews_) {
00133 vcl_cerr << "NViewMatches::load() ERROR: only " << awk.NF() << " fields on line " << awk.NR() << '\n';
00134 return false;
00135 }
00136
00137
00138 NViewMatch v(nviews_);
00139 for (int j = 0; j < nviews_; ++j) {
00140 char const* cp = awk[j];
00141 if (cp[0] == '*')
00142 v[j] = NViewMatch::nomatch;
00143 else
00144 v[j] = atoi(cp);
00145 }
00146 push_back(v);
00147 }
00148
00149 return true;
00150 }
00151
00152 bool NViewMatches::save(vcl_ostream& s)
00153 {
00154 for (unsigned i = 0; i < size(); ++i)
00155 s << (*this)[i] << '\n';
00156 return s.good() != 0;
00157 }
00158
00159 bool NViewMatches::save(const char* filename)
00160 {
00161 vcl_ofstream o(filename);
00162 return save(o);
00163 }
00164
00165
00166 int NViewMatches::count_matches(const NViewMatch& match)
00167 {
00168 int nmatches = 0;
00169 for (unsigned i = 0; i < size(); ++i)
00170 if ((*this)[i].matches(match,min_overlap_))
00171 ++nmatches;
00172 return nmatches;
00173 }
00174
00175
00176 vcl_vector<int> NViewMatches::get_matches(const NViewMatch& match)
00177 {
00178 vcl_vector<int> ret;
00179 for (unsigned i = 0; i < size(); ++i)
00180 if (operator[](i).matches(match,min_overlap_))
00181 ret.push_back(i);
00182 return ret;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 int NViewMatches::incorporate(const NViewMatch& newtrack)
00200 {
00201 int nmatches = 0;
00202 iterator merged = end();
00203 vcl_abort();
00204 for (iterator i = begin(); i != end(); ++i) {
00205 if ((*i).matches(newtrack,min_overlap_)) {
00206 if (nmatches == 0) {
00207
00208 (*i).incorporate(newtrack);
00209 ++nmatches;
00210 merged = i;
00211 }
00212 else if ((*i).is_consistent(*merged)) {
00213 vcl_cerr << "Merge : " << (*i) << '\n'
00214 << " " << (*merged) << '\n';
00215
00216 (*merged).incorporate((*i));
00217 erase(i);
00218 --i;
00219 ++nmatches;
00220 }
00221 else {
00222
00223
00224 erase(i);
00225 erase(merged);
00226 return -1;
00227 }
00228 }
00229 }
00230 if (nmatches == 0) {
00231 push_back(newtrack);
00232 return size() - 1;
00233 }
00234
00235 #ifdef DEBUG
00236 if (nmatches > 1) {
00237 vcl_cerr << "NViewMatches::incorporate(): " << nmatches << " consistent matches merged\n";
00238 }
00239 #endif
00240 return merged - begin();
00241 }
00242
00243
00244 NViewMatch NViewMatches::make_triplet_match(int base_view, int c1, int c2, int c3)
00245 {
00246 assert(base_view+2 < nviews_);
00247 NViewMatch newtrack(nviews_);
00248 newtrack[base_view] = c1;
00249 newtrack[base_view+1] = c2;
00250 newtrack[base_view+2] = c3;
00251 return newtrack;
00252 }
00253
00254
00255 int NViewMatches::incorporate_triplet(int base_view, int c1, int c2, int c3)
00256 {
00257 assert(base_view+2 < nviews_);
00258 NViewMatch newtrack(nviews_);
00259 newtrack[base_view] = c1;
00260 newtrack[base_view+1] = c2;
00261 newtrack[base_view+2] = c3;
00262 return incorporate(newtrack);
00263 }
00264
00265
00266
00267 void NViewMatches::remove_inconsistencies()
00268 {
00269 }