Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006 #include "mvl_multi_view_matches.h"
00007
00008 #include <vcl_cassert.h>
00009 #include <vcl_cstdlib.h>
00010 #include <vcl_set.h>
00011 #include <vcl_functional.h>
00012 #include <vcl_fstream.h>
00013
00014 #include <vul/vul_awk.h>
00015
00016 mvl_multi_view_matches::mvl_multi_view_matches(char const* filename)
00017 {
00018 read(filename);
00019 }
00020
00021 mvl_multi_view_matches::mvl_multi_view_matches(vcl_vector<int> const& views)
00022 {
00023 set_views(views);
00024 }
00025
00026 mvl_multi_view_matches::mvl_multi_view_matches(int start, int end, int step)
00027 {
00028 set_views(start,end,step);
00029 }
00030
00031 mvl_multi_view_matches::mvl_multi_view_matches(int N)
00032 {
00033 set_views(N);
00034 }
00035
00036
00037 mvl_multi_view_matches::~mvl_multi_view_matches()
00038 {
00039 }
00040
00041 void mvl_multi_view_matches::set_views(vcl_vector<int> const& views)
00042 {
00043 views_ = views;
00044 init();
00045 }
00046
00047 void mvl_multi_view_matches::set_views(int start, int end, int step)
00048 {
00049 views_.clear();
00050 for (int i=start; i <= end; i+=step)
00051 views_.push_back(i);
00052 init();
00053 }
00054
00055 void mvl_multi_view_matches::set_views(int N)
00056 {
00057 views_.clear();
00058 for (int i=0; i < N; ++i)
00059 views_.push_back(i);
00060 init();
00061 }
00062
00063 void mvl_multi_view_matches::init()
00064 {
00065 view_to_internal_map_.clear();
00066 for (unsigned i=0; i < views_.size(); ++i)
00067 view_to_internal_map_[views_[i]] = i;
00068
00069 corner_to_track_maps_ = vcl_vector<Map> (views_.size());
00070 tracks_.clear();
00071 }
00072
00073 void mvl_multi_view_matches::add_pair(int view1, int corner1, int view2, int corner2)
00074 {
00075 vcl_vector<int> views(2);
00076 vcl_vector<int> corners(2);
00077 views[0] = view1;
00078 views[1] = view2;
00079 corners[0] = corner1;
00080 corners[1] = corner2;
00081 add_track(views, corners);
00082 }
00083
00084 void mvl_multi_view_matches::add_triplet(int view1, int corner1, int view2, int corner2, int view3, int corner3)
00085 {
00086 vcl_vector<int> views(3);
00087 vcl_vector<int> corners(3);
00088 views[0] = view1;
00089 views[1] = view2;
00090 views[2] = view3;
00091 corners[0] = corner1;
00092 corners[1] = corner2;
00093 corners[2] = corner3;
00094 add_track(views, corners);
00095 }
00096
00097 void mvl_multi_view_matches::add_track(vcl_vector<int> const& views, vcl_vector<int> const& corners)
00098 {
00099 assert(views.size() == corners.size());
00100
00101
00102
00103 typedef Map::iterator Map_iterator;
00104
00105 int track_length = views.size();
00106
00107 vcl_vector<int> internal_frames(track_length);
00108
00109
00110 for (int i=0; i < track_length; ++i) {
00111 Map_iterator m = view_to_internal_map_.find(views[i]);
00112 if (m == view_to_internal_map_.end()) {
00113 vcl_cerr << __FILE__ << " : view specified outside range!\n";
00114 vcl_abort();
00115 }
00116 internal_frames[i] = (*m).second;
00117 }
00118
00119
00120 Map new_track;
00121 for (int i=0; i < track_length; ++i) {
00122 new_track[internal_frames[i]] = corners[i];
00123 }
00124
00125 vcl_set<unsigned int, vcl_less<unsigned int> > friend_tracks;
00126 {
00127 for (int i=0; i < track_length; ++i) {
00128 Map_iterator m=corner_to_track_maps_[internal_frames[i]].find(corners[i]);
00129 if (m != corner_to_track_maps_[internal_frames[i]].end()) {
00130 if ((*m).second >= tracks_.size()) {
00131 vcl_cerr << __FILE__ << " : URK!" << internal_frames[i] << ' '
00132 << corners[i] << ' ' << (*m).second << ' ' << tracks_.size() << vcl_endl;
00133 vcl_abort();
00134 }
00135 friend_tracks.insert((*m).second);
00136 }
00137 }
00138 }
00139
00140 if (friend_tracks.empty()) {
00141
00142 tracks_.push_back(new_track);
00143 update_maps(tracks_.size() - 1);
00144 }
00145 else {
00146
00147
00148 bool consistency_okay = true;
00149 vcl_set<unsigned int, vcl_less<unsigned int> >::iterator t=friend_tracks.begin();
00150 for ( ; t != friend_tracks.end() && consistency_okay; ++t) {
00151 Map& friend_track = tracks_[(*t)];
00152
00153 for (Map_iterator i = new_track.begin(); i != new_track.end() && consistency_okay; ++i) {
00154 unsigned int frame = (*i).first;
00155 unsigned int corner = (*i).second;
00156 Map_iterator m = friend_track.find(frame);
00157 if (m != friend_track.end() && (*m).second != corner) consistency_okay = false;
00158 }
00159 if (consistency_okay) {
00160
00161 for (Map_iterator tp = friend_track.begin(); tp != friend_track.end(); ++tp)
00162 new_track.insert(*tp);
00163 }
00164 }
00165
00166 if (consistency_okay) {
00167
00168
00169
00170 int merged_track_index = *(friend_tracks.begin());
00171 friend_tracks.erase(merged_track_index);
00172 tracks_[merged_track_index] = new_track;
00173 update_maps(merged_track_index);
00174
00175 vcl_set<unsigned int, vcl_less<unsigned int> >::reverse_iterator track_iterator = friend_tracks.rbegin();
00176 for ( ; !(track_iterator == friend_tracks.rend()); ++track_iterator) {
00177 unsigned int dead_track_index = (*track_iterator);
00178 if (dead_track_index+1 != tracks_.size()) {
00179 tracks_[dead_track_index] = tracks_.back();
00180 update_maps(dead_track_index);
00181 }
00182 tracks_.pop_back();
00183 }
00184 }
00185 else {
00186
00187
00188 vcl_set<unsigned int, vcl_less<unsigned int> >::reverse_iterator track_iterator = friend_tracks.rbegin();
00189 for ( ; !(track_iterator == friend_tracks.rend()); ++track_iterator) {
00190 unsigned int dead_track_index = (*track_iterator);
00191 remove_maps(dead_track_index);
00192 if (dead_track_index+1 != tracks_.size()) {
00193 tracks_[dead_track_index] = tracks_.back();
00194 update_maps(dead_track_index);
00195 }
00196 tracks_.pop_back();
00197 }
00198 }
00199 }
00200 }
00201
00202 void mvl_multi_view_matches::add_matches(mvl_multi_view_matches const& )
00203 {
00204 vcl_cerr << __FILE__ ": mvl_multi_view_matches::add_matches() not implemented\n";
00205 vcl_abort();
00206 }
00207
00208 void mvl_multi_view_matches::update_maps(int track_index)
00209 {
00210 for (Map::iterator i = tracks_[track_index].begin(); i != tracks_[track_index].end(); ++i) {
00211 int internal_frame = (*i).first;
00212 int corner = (*i).second;
00213 corner_to_track_maps_[internal_frame][corner] = track_index;
00214 }
00215 }
00216
00217 void mvl_multi_view_matches::remove_maps(int track_index)
00218 {
00219 for (Map::iterator i = tracks_[track_index].begin(); i != tracks_[track_index].end(); ++i) {
00220 int internal_frame = (*i).first;
00221 int corner = (*i).second;
00222 corner_to_track_maps_[internal_frame].erase(corner);
00223 }
00224 }
00225
00226 vcl_ostream& mvl_multi_view_matches::print(vcl_ostream& s) const
00227 {
00228 for (unsigned int i=0; i < tracks_.size(); ++i) {
00229 s << "Track " << i << " : ";
00230 for (Map::const_iterator m = tracks_[i].begin(); m != tracks_[i].end(); ++m)
00231 s << '(' << views_[(*m).first] << ',' << (*m).second << ") ";
00232 s << vcl_endl;
00233 }
00234 return s;
00235 }
00236
00237 vcl_istream& mvl_multi_view_matches::read(vcl_istream& s)
00238 {
00239 if (!s.good()) return s;
00240
00241 views_.clear();
00242 vul_awk awk(s);
00243 for (int i=0; i < awk.NF(); ++i)
00244 views_.push_back(atoi(awk[i]));
00245 ++awk;
00246
00247 vcl_cerr << __FILE__ << " : reading views ( ";
00248 for (unsigned int i=0; i < views_.size(); ++i)
00249 vcl_cerr << views_[i] << ' ';
00250 vcl_cerr << ")\n";
00251
00252 init();
00253
00254 tracks_.resize(20000);
00255 int max_track = 0;
00256 for (; awk; ++awk) {
00257 if (awk.NF() != 3) vcl_abort();
00258 int track = atoi(awk[0]);
00259 int frame = atoi(awk[1]);
00260 int corner = atoi(awk[2]);
00261 tracks_[track][frame] = corner;
00262 if (track > max_track) max_track = track;
00263 }
00264 tracks_.resize(max_track);
00265
00266 for (unsigned int i=0; i < tracks_.size(); ++i)
00267 update_maps(i);
00268
00269 vcl_cerr << __FILE__ << " : read " << tracks_.size() << " tracks\n";
00270
00271 return s;
00272 }
00273
00274 vcl_ostream& mvl_multi_view_matches::write(vcl_ostream& s) const
00275 {
00276 if (!s.good()) return s;
00277
00278
00279 for (unsigned int i=0; i < views_.size(); ++i)
00280 s << i << ' ';
00281 s << vcl_endl;
00282
00283
00284 for (unsigned int i=0; i < tracks_.size(); ++i)
00285 for (Map::const_iterator m = tracks_[i].begin(); m != tracks_[i].end(); ++m)
00286 s << i << ' ' << (*m).first << ' ' << (*m).second << vcl_endl;
00287
00288 vcl_cerr << __FILE__ << " : wrote " << tracks_.size() << " tracks\n";
00289
00290 return s;
00291 }
00292
00293 void mvl_multi_view_matches::read(char const* filename)
00294 {
00295 vcl_ifstream fin(filename);
00296 read(fin);
00297 }
00298
00299 void mvl_multi_view_matches::write(char const* filename) const
00300 {
00301 vcl_ofstream fout(filename);
00302 write(fout);
00303 }