00001 #ifndef GFM_ALL_TIME_TRACKER
00002 #define GFM_ALL_TIME_TRACKER
00003
00004 #include "gfm/EngineTracking.hpp"
00005 #include <set>
00006
00007 namespace jafar {
00008 namespace gfm_v2 {
00009
00020 template<typename DESCRIPTOR>
00021 class AllTimeTracker : public gfm_v2::EngineTracking<DESCRIPTOR> {
00022
00023 public:
00024 typedef fdetect_v2::InterestFeature<DESCRIPTOR> Feature;
00025 typedef fdetect_v2::DetectionResult<DESCRIPTOR> DR;
00026 typedef gfm_v2::MatchingResult<DESCRIPTOR> MR;
00027
00028 private:
00033 struct features_comp {
00034 bool operator() (const Feature* lhf, const Feature* rhf) const
00035 {
00036 return lhf->index() < rhf->index();
00037 }
00038 };
00040 std::map<unsigned int, std::set< Feature*, features_comp > > unmatched;
00041 typedef typename std::map<unsigned int, typename std::set< Feature*, features_comp > >::iterator unmatched_iterator;
00043 unsigned int global_id;
00045 unsigned int initial_id;
00047 unsigned int second_id;
00049 DR previous_points;
00051 MR current_match;
00053 DR current_unmatched;
00055 void matchWithOthers ( DR& local_unmatched )
00056 {
00057 using namespace std;
00058 MatchSourceInfo<DESCRIPTOR>* match_info = this->m_matcher->initMatchSourceInfo(local_unmatched);
00059 MatchSourceInfo<DESCRIPTOR>* source_info;
00060
00061 for(unmatched_iterator uit = unmatched.begin();
00062 uit != unmatched.end();
00063 ++uit) {
00064 DR source;
00065 source.insert(uit->second.begin(), uit->second.end());
00066 source.id = uit->first;
00067 source_info = this->m_matcher->initMatchSourceInfo(source);
00068 MR mr = this->m_matcher->computeMatch(source_info, match_info);
00069 JFR_DEBUG("Found " << mr.size() << " matches");
00070 if (mr.size() != 0) {
00071 mr.propagateId(global_id);
00072 for (typename MR::const_iterator mit = mr.begin(); mit != mr.end(); ++mit) {
00073 if(mit->point_ref->id() != geom::InterestPoint::NO_ID) {
00074 unmatched_iterator finder = unmatched.find(mit->point_ref->parent_id);
00075 JFR_ASSERT(finder != unmatched.end(),
00076 "no DR with id "<<mit->point_ref->parent_id<<" found!")
00077 finder->second.erase(mit->point_ref);
00078 current_match.push_back(mit->point_ref, mit->point_match);
00079 }
00080 }
00081 }
00082 }
00083 }
00084
00085 public:
00086
00093 AllTimeTracker(jafar::fdetect_v2::Detector<DESCRIPTOR>* detector,
00094 jafar::gfm_v2::Matcher<DESCRIPTOR>* matcher,
00095 unsigned int start = 0,
00096 jafar::fdetect_v2::DescriptorFactory<DESCRIPTOR>* descriptor = 0) :
00097 gfm_v2::EngineTracking<DESCRIPTOR>(detector, matcher, descriptor),
00098 global_id(start), initial_id(-1), second_id(-1) { }
00099
00104 void initTracking(jafar::image::Image const& image_ref,
00105 unsigned int id)
00106 {
00107 this->initTracking(image_ref, jafar::image::Image(), id);
00108 }
00109
00114 void initTracking(jafar::image::Image const& image_ref,
00115 jafar::image::Image const& mask_ref,
00116 unsigned int id)
00117 {
00118 JFR_PRECOND(id != -1,
00119 "id must be different from -1")
00120 initial_id = id;
00121 EngineTracking<DESCRIPTOR>::initTracking(image_ref, mask_ref, id);
00122 }
00123
00129 void initTracking(fdetect_v2::DetectionResult<DESCRIPTOR> &points_ref,
00130 unsigned int id)
00131 {
00132 JFR_PRECOND(id != -1,
00133 "id must be different from -1")
00134 initial_id = id;
00135 EngineTracking<DESCRIPTOR>::initTracking(points_ref, id);
00136 }
00137
00144 MR nextImage(jafar::image::Image const& image_next, unsigned int id)
00145 {
00146 return this->nextImage(image_next, jafar::image::Image(), id);
00147 }
00148
00156 MR nextImage(jafar::image::Image const& image_next,
00157 jafar::image::Image const& mask_next,
00158 unsigned int id)
00159 {
00160 using namespace std;
00161 JFR_PRECOND(initial_id != -1,
00162 "call initTracking() first!")
00163 JFR_PRECOND(id != -1,
00164 "id must be different from -1!")
00165 using namespace fdetect_v2;
00166
00167 previous_points = this->currentPoints();
00168 DR points_match = this->m_detector->detectIn(image_next);
00169 points_match.id = id;
00170 for ( typename DR::iterator it = points_match.begin();
00171 it != points_match.end();
00172 ++it)
00173 (*it)->parent_id = id;
00174 if(this->m_descriptorFactory)
00175 {
00176 this->m_descriptorFactory->createDescriptor(points_match, image_next);
00177 }
00178 MatchSourceInfo<DESCRIPTOR>* infomatch = this->m_matcher->initMatchSourceInfo(points_match);
00179 this->m_sourceInfoRef->reinit();
00180 current_match = this->m_matcher->computeMatch(this->m_sourceInfoRef, infomatch);
00181 JFR_DEBUG("Found " << current_match.size() << " matches");
00182 delete this->m_sourceInfoRef;
00183 current_match.propagateId(global_id);
00184
00185 if(second_id == -1) {
00186
00187 for(typename DR::iterator fit = previous_points.begin();
00188 fit != previous_points.end();
00189 ++fit) {
00190 if((*fit)->id() == geom::InterestPoint::NO_ID)
00191 unmatched[initial_id].insert(*fit);
00192 }
00193 second_id = id;
00194 } else {
00195 current_unmatched.clear();
00196
00197 for(typename DR::const_iterator fit = points_match.begin();
00198 fit != points_match.end();
00199 ++fit) {
00200 if((*fit)->id() == geom::InterestPoint::NO_ID) {
00201 current_unmatched.push_back(*fit);
00202 }
00203 }
00204 matchWithOthers(current_unmatched);
00205 JFR_DEBUG("After others matching, found " << current_match.size() << " matches")
00206
00207 typename DR::iterator fit = previous_points.begin();
00208 unsigned int prev_id = (*fit)->parent_id;
00209 for(; fit != previous_points.end(); ++fit) {
00210 if((*fit)->id() == geom::InterestPoint::NO_ID)
00211 unmatched[prev_id].insert(*fit);
00212 }
00213 }
00214
00215 this->m_sourceInfoRef = this->m_matcher->initMatchSourceInfo(points_match);
00216 return current_match;
00217 }
00218
00226 MR nextImage(DR &points_next,
00227 unsigned int id = geom::InterestPoint::NO_ID)
00228 {
00229 using namespace std;
00230 JFR_PRECOND(initial_id != -1,
00231 "call initTracking() first!")
00232 JFR_PRECOND(id != -1,
00233 "id must be different from -1!")
00234 using namespace fdetect_v2;
00235
00236 previous_points = this->currentPoints();
00237 points_next.id = id;
00238 for(typename DR::iterator it = points_next.begin();
00239 it != points_next.end();
00240 ++it)
00241 (*it)->parent_id = id;
00242
00243 MatchSourceInfo<DESCRIPTOR>* infomatch = this->m_matcher->initMatchSourceInfo(points_next);
00244 this->m_sourceInfoRef->reinit();
00245 current_match = this->m_matcher->computeMatch(this->m_sourceInfoRef, infomatch);
00246 JFR_DEBUG("Found " << current_match.size() << " matches");
00247 delete this->m_sourceInfoRef;
00248 current_match.propagateId(global_id);
00249
00250 if(second_id == -1) {
00251
00252 for(typename DR::iterator fit = previous_points.begin();
00253 fit != previous_points.end();
00254 ++fit) {
00255 if((*fit)->id() == geom::InterestPoint::NO_ID)
00256 unmatched[initial_id].insert(*fit);
00257 }
00258 second_id = id;
00259 } else {
00260 current_unmatched.clear();
00261
00262 for(typename DR::const_iterator fit = points_next.begin();
00263 fit != points_next.end();
00264 ++fit) {
00265 if((*fit)->id() == geom::InterestPoint::NO_ID) {
00266 current_unmatched.push_back(*fit);
00267 }
00268 }
00269 matchWithOthers(current_unmatched);
00270 JFR_DEBUG("After others matching, found " << current_match.size() << " matches")
00271
00272 typename DR::iterator fit = previous_points.begin();
00273 unsigned int prev_id = (*fit)->parent_id;
00274 for(; fit != previous_points.end(); ++fit) {
00275 if((*fit)->id() == geom::InterestPoint::NO_ID)
00276 unmatched[prev_id].insert(*fit);
00277 }
00278 }
00279
00280 this->m_sourceInfoRef = this->m_matcher->initMatchSourceInfo(points_next);
00281 return current_match;
00282 }
00283
00284 };
00285
00286 }
00287
00288 }
00289
00290 #endif