00001
00002
00003 #ifndef SAMS_MODEL_HPP
00004 #define SAMS_MODEL_HPP
00005
00006 #include <utility>
00007 #include <algorithm>
00008 #include <iostream>
00009 #include "boost/utility.hpp"
00010 #include "boost/archive/binary_iarchive.hpp"
00011 #include "boost/archive/binary_oarchive.hpp"
00012 #include "boost/serialization/split_member.hpp"
00013 #include "boost/serialization/map.hpp"
00014 #include "boost/serialization/string.hpp"
00015
00016 #define USE_JMATH_SERIALIZATION 1
00017
00018 #include "jmath/gaussianVector.hpp"
00019 #include "sams/frame.hpp"
00020 #include "sams/tools.hpp"
00021
00022 namespace jafar {
00023 namespace sams {
00024
00025 class Match;
00026 class Hypothesis;
00027 class ViewPartLink;
00028
00029 class ModelPart {
00030 public:
00031 ModelPart(int id_=0, double confidence_ = 1.0) : m_id(id_), m_confidence(confidence_) {
00032 m_trCount = 0;
00033 };
00034
00036 int id() const { return m_id; };
00037 double confidence() const { return m_confidence; };
00038 jblas::vec const & app() const { return m_desc.x; };
00039 jblas::sym_mat const & cov() const { return m_desc.P; };
00040 ViewPartLink const * view(int id_) const {
00041 std::map<int, ViewPartLink *>::const_iterator it = m_views.find(id_);
00042 return ( it != m_views.end() ? it->second : NULL);
00043 };
00044 std::map<int, ViewPartLink*> const & views() const { return m_views; };
00045
00046 double probabilityDensity(jblas::vec const & v) const {
00047 return m_desc.probabilityDensity(v);
00048 };
00049
00050
00051 bool operator== (ModelPart const & p_) const {
00052 return ( m_id == p_.m_id);
00053 };
00054
00055 private:
00057 int m_id;
00059 double m_confidence;
00061 jafar::jmath::GaussianVector m_desc;
00063 std::map<int, ViewPartLink *> m_views;
00064
00065 int m_trCount;
00066
00067 void update(jblas::vec const & v_);
00068
00069 friend class Model;
00070
00071
00072 friend class boost::serialization::access;
00073 template<class Archive>
00074 void serialize(Archive & ar, const unsigned int version)
00075 {
00076
00077 ar & BOOST_SERIALIZATION_NVP(m_id);
00078 ar & BOOST_SERIALIZATION_NVP(m_confidence);
00079 ar & BOOST_SERIALIZATION_NVP(m_trCount);
00080 ar & BOOST_SERIALIZATION_NVP(m_desc.x);
00081 ar & BOOST_SERIALIZATION_NVP(m_desc.P);
00082 ar & BOOST_SERIALIZATION_NVP(m_views);
00083 }
00084
00085
00086 };
00087
00088
00089 class ModelView {
00090 public:
00091 ModelView(int id_=0) : m_id(id_), m_img() {};
00092
00094 int centerX;
00095 int centerY;
00096
00098 int id() const { return m_id; };
00099
00100 jafar::image::Image const & img() const { return m_img; };
00101
00102 int nbParts() const {
00103 return m_parts.size();
00104 };
00105
00106 ViewPartLink const * getPart(int id_) const {
00107 std::map<int, ViewPartLink *>::const_iterator it = m_parts.find(id_);
00108 return ( it != m_parts.end() ? it->second : NULL);
00109 };
00110
00111 std::map<int, ViewPartLink*> const & parts() const { return m_parts; };
00112
00114 bool operator== (ModelView const & v_) const {
00115 return ( m_id == v_.m_id );
00116 };
00117
00118
00119
00120 ViewPartLink const * first() {
00121 m_it = m_parts.begin();
00122 return m_it->second;
00123 };
00124
00125 bool hasNext() const {
00126 std::map<int, ViewPartLink *>::const_iterator tmp = m_it;
00127 return ( ++tmp != m_parts.end() );
00128 };
00129
00130 bool hasPrevious() const {
00131 return ( m_it != m_parts.begin());
00132 }
00133
00134 ViewPartLink const * next() {
00135 return (++m_it)->second;
00136 };
00137
00138 ViewPartLink const * previous() {
00139 return (--m_it)->second;
00140 };
00141
00142 private:
00144 int m_id;
00146 jafar::image::Image m_img;
00148 std::map<int, ViewPartLink *> m_parts;
00149 mutable std::map<int, ViewPartLink *>::const_iterator m_it;
00150
00151
00152 friend class boost::serialization::access;
00153 template<class Archive>
00154 void serialize(Archive & ar, const unsigned int version)
00155 {
00156
00157 ar & BOOST_SERIALIZATION_NVP(m_id);
00158 ar & BOOST_SERIALIZATION_NVP(m_img);
00159 ar & BOOST_SERIALIZATION_NVP(m_parts);
00160 }
00161
00162 friend class Model;
00163
00164 };
00165
00166
00167 class ViewPartLink {
00168 public:
00169 ViewPartLink(double x_, double y_, double o_, double s_,
00170 ModelPart * part_,
00171 ModelView * view_) : m_pos(4), m_part(part_), m_view(view_), m_trCount(1) {
00172 m_pos.x(0) = x_; m_pos.x(1) = y_;
00173 m_pos.x(2) = o_; m_pos.x(3) = s_;
00174 m_pos.P = jblas::identity_mat(4,4);
00175 };
00176 ViewPartLink(jafar::jmath::GaussianVector const & gv_,
00177 ModelPart * part_,
00178 ModelView * view_) : m_pos(gv_), m_part(part_), m_view(view_), m_trCount(1) {
00179 };
00180
00181 double x() const { return m_pos.x(0); };
00182 double y() const { return m_pos.x(1); };
00183 double o() const { return m_pos.x(2); };
00184 double s() const { return m_pos.x(3); };
00185 jblas::vec const & pos() const { return m_pos.x; };
00186 jblas::sym_mat const & cov() const { return m_pos.P; };
00187 ModelPart const * part() const { return m_part; };
00188 ModelView const * view() const { return m_view; };
00189 double probabilityDensity(jblas::vec const & v) const {
00190 return m_pos.probabilityDensity(v);
00191 };
00192
00193 jblas::vec transform (jblas::mat const & t) const;
00194
00195
00196
00197 private:
00198 jafar::jmath::GaussianVector m_pos;
00199 ModelPart * m_part;
00200 ModelView * m_view;
00201 int m_trCount;
00202
00203 ViewPartLink() {};
00204
00205 void update(jblas::vec const & v_);
00206
00207
00208 friend class boost::serialization::access;
00209
00210 template<class Archive>
00211 void serialize(Archive & ar, const unsigned int version)
00212 {
00213
00214 ar & BOOST_SERIALIZATION_NVP(m_trCount);
00215 ar & BOOST_SERIALIZATION_NVP(m_pos.x);
00216 ar & BOOST_SERIALIZATION_NVP(m_pos.P);
00217 ar & BOOST_SERIALIZATION_NVP(m_part);
00218 ar & BOOST_SERIALIZATION_NVP(m_view);
00219 }
00220
00221 friend class Model;
00222 };
00223
00224 class Model {
00225 public:
00226
00227 Model() : pidcount(0), vidcount(0), m_trFr(0), m_label(), currentView(-1) {
00228 };
00229
00230 Model(std::string const & label,jafar::sams::Frame const & f_);
00231
00232 ~Model() {
00233 clear();
00234 };
00235
00236
00237
00238 std::string label() const { return m_label; };
00239
00240 typedef std::map<int, ModelPart *>::const_iterator const_parts_iterator;
00241 typedef std::map<int, ModelPart *>::iterator parts_iterator;
00242 const_parts_iterator parts_begin() const { return m_parts.begin(); };
00243 parts_iterator parts_begin() { return m_parts.begin(); };
00244 const_parts_iterator parts_end() const { return m_parts.end(); };
00245 parts_iterator parts_end() { return m_parts.end(); };
00246 typedef std::map<int, ModelView *>::const_iterator const_views_iterator;
00247 typedef std::map<int, ModelView *>::iterator views_iterator;
00248 const_views_iterator views_begin() const { return m_views.begin(); };
00249 views_iterator views_begin() { return m_views.begin(); };
00250 const_views_iterator views_end() const { return m_views.end(); };
00251 views_iterator views_end() { return m_views.end(); };
00252
00253 ModelView const * view(int id_, bool setCurrent_=false) const {
00254 const_views_iterator it = m_views.find(id_);
00255 if ( it != views_end() ) {
00256 if (setCurrent_) currentView = id_;
00257 return it->second;
00258 } else
00259 return NULL;
00260 };
00261
00262 ModelPart const * part(int id_) const {
00263 const_parts_iterator it = m_parts.find(id_);
00264 return ( it != parts_end() ? it->second : NULL);
00265 };
00266
00267
00268 ModelView const * first() {
00269 JFR_PRECOND(isInitialized(), "Model::first: model not initialized");
00270 currentView = 0;
00271 return views_begin()->second;
00272 };
00273
00274 ModelView const * current() const {
00275 JFR_PRECOND(isInitialized(), "Model::current: model not initialized");
00276 return m_views.find(currentView)->second;
00277 }
00278
00279 bool hasNext() const {
00280 JFR_PRECOND(isInitialized(), "Model::hasNext: model not initialized");
00281 const_views_iterator tmp = m_views.find(currentView);
00282 return ( ++tmp != views_end() );
00283 };
00284
00285 bool hasPrevious() const {
00286 JFR_PRECOND(isInitialized(), "Model::hasPrevious: model not initialized");
00287 return ( m_views.find(currentView) != views_begin());
00288 }
00289
00290 ModelView const * next() {
00291 JFR_PRECOND(isInitialized(), "Model::next: model not initialized");
00292 const_views_iterator tmp = m_views.find(currentView);
00293 currentView = (++tmp)->first;
00294 return tmp->second;
00295 };
00296
00297 ModelView const * previous() {
00298 JFR_PRECOND(isInitialized(), "Model::previous: model not initialized");
00299 const_views_iterator tmp = m_views.find(currentView);
00300 currentView = (--tmp)->first;
00301 return tmp->second;
00302 };
00303
00304
00305 inline int parts_size() const {
00306 return m_parts.size();
00307 };
00308
00309 inline int views_size() const {
00310 return m_views.size();
00311 };
00312
00313 void initialize(jafar::sams::Frame const & f_);
00314
00316 void addFrame(jafar::sams::Frame const & f_);
00317
00319 void addView(jafar::sams::Frame const & f_, jafar::sams::Hypothesis const & hyp_);
00320
00322 void updateView(jafar::sams::Frame const & f_, jafar::sams::Hypothesis const & hyp_);
00323
00324
00325 private:
00326 int pidcount;
00327 int vidcount;
00328 int m_trFr;
00329 std::string m_label;
00330 std::map<int, ModelPart *> m_parts;
00331 std::map<int, ModelView *> m_views;
00332
00333
00334 friend class boost::serialization::access;
00335 template<class Archive>
00336 void serialize(Archive & ar, const unsigned int version)
00337 {
00338
00339 ar & BOOST_SERIALIZATION_NVP(pidcount);
00340 ar & BOOST_SERIALIZATION_NVP(vidcount);
00341 ar & BOOST_SERIALIZATION_NVP(m_trFr);
00342 ar & BOOST_SERIALIZATION_NVP(m_label);
00343 ar & BOOST_SERIALIZATION_NVP(m_parts);
00344 ar & BOOST_SERIALIZATION_NVP(m_views);
00345 }
00346
00347 mutable int currentView;
00348
00349 inline bool isInitialized() const {
00350 return (m_parts.size() != 0);
00351 };
00352
00353
00354 inline ModelView * new_view(jafar::image::Image const & img_) {
00355 ModelView * view = new ModelView(vidcount++);
00356 m_views[view->m_id]=view;
00357 view->m_img = img_.clone();
00358 view->centerX = img_.width()/2;
00359 view->centerY = img_.height()/2;
00360 return view;
00361 };
00362
00363 inline ModelPart * new_part() {
00364 ModelPart * part = new ModelPart(pidcount++);
00365 m_parts[part->m_id]=part;
00366 return part;
00367 }
00368
00369 inline void delete_part(ModelPart * p_) {
00370 std::map<int, ViewPartLink *>::iterator it = p_->m_views.begin();
00371 for(; it != p_->m_views.end(); it++) {
00372 (it->second)->m_view->m_parts.erase(p_->m_id);
00373 delete it->second;
00374 }
00375 m_parts.erase(p_->m_id);
00376 delete p_;
00377 };
00378
00379 inline void delete_view(ModelView * v_) {
00380 std::map<int, ViewPartLink *>::iterator it = v_->m_parts.begin();
00381 for(; it != v_->m_parts.end(); it++) {
00382 (it->second)->m_part->m_views.erase(v_->m_id);
00383 delete it->second;
00384 }
00385 m_views.erase(v_->m_id);
00386 delete v_;
00387 };
00388
00389 inline void clear() {
00390 parts_iterator it = parts_begin();
00391
00392 for(; it != parts_end(); it++)
00393 tools::map_delete(it->second->m_views.begin(),it->second->m_views.end());
00394 tools::map_delete(parts_begin(),parts_end());
00395 tools::map_delete(views_begin(),views_end());
00396 m_parts.clear();
00397 m_views.clear();
00398 };
00399
00400 };
00401
00402 class ModelDB {
00403 public:
00404
00405 typedef std::map<std::string,Model *>::iterator iterator;
00406 typedef std::map<std::string,Model *>::const_iterator const_iterator;
00407
00408
00409 ModelDB() {};
00410 ModelDB(std::string const & path_) {
00411 loadDB(path_);
00412 };
00413
00414
00415 iterator begin() {
00416 return db.begin();
00417 };
00418 const_iterator begin() const {
00419 return db.begin();
00420 };
00421 iterator end() {
00422 return db.end();
00423 };
00424 const_iterator end() const {
00425 return db.end();
00426 };
00427
00428
00429
00430 Model const * operator[] (std::string const & name_) const {
00431 const_iterator it = db.find(name_);
00432 return ( it == db.end() ? 0 : it->second );
00433 };
00434
00435 Model * operator[] (std::string const & name_) {
00436 const_iterator it = db.find(name_);
00437 return ( it == db.end() ? 0 : it->second );
00438 };
00439
00440 void insert (std::string const & name_, const Model * model_) {
00441 JFR_PRECOND( db.find(name_) == db.end(), "ModelDB::insert: already used label");
00442 db.insert(value_type(name_, const_cast<Model *>(model_)));
00443 }
00444
00445 void remove(std::string const & name_) {
00446 iterator it = db.find(name_);
00447 if ( it != db.end() ) {
00448 delete it->second;
00449 db.erase(it);
00450 }
00451 };
00452
00453 int size() const {
00454 return db.size();
00455 };
00456
00457 int nbParts() const {
00458 int acc=0;
00459 const_iterator it = db.begin();
00460 for(; it != db.end(); it++)
00461 acc += it->second->parts_size();
00462 return acc;
00463 };
00464
00465 static void loadModel(Model & model, std::string const & path);
00466 static void saveModel(Model & model, std::string const & path);
00467
00468 void load(std::string const & path_);
00469 void loadDB(std::string const & path_);
00470 void save(std::string const & name_, std::string const & path_=".") const;
00471 void saveDB(std::string const & path_=".") const ;
00472
00473 private:
00474 typedef std::map<std::string, Model *>::value_type value_type;
00475 std::map<std::string, Model *> db;
00476 };
00477
00478
00479 }
00480 }
00481
00482 #endif // SAMS_MODEL_HPP