ImageMolecule.cpp
Go to the documentation of this file.
00001 /*
00002 
00003  * ImageMolecule.cpp
00004  *
00005  *  Created on: Oct 20, 2010
00006  *      Author: erublee
00007 
00008  */
00009 #include "pano_core/ImageMolecule.h"
00010 #include "pano_core/ModelFitter.h"
00011 
00012 #include <algorithm>
00013 #include <utility>
00014 #include <vector>
00015 #include <string>
00016 #include <algorithm>
00017 #include <functional>
00018 #include <set>
00019 #include <stdexcept>
00020 #include <exception>
00021 
00022 using namespace cv;
00023 using namespace std;
00024 
00025 namespace pano
00026 {
00027 
00028 namespace
00029 {
00030 //    * Helper functor for iterating over pairs
00031 //      * and inserting them into a molecule
00032 
00033 struct IAPairInserter
00034 {
00035   IAPairInserter(ImageMolecule*mol) :
00036     mol(mol)
00037   {
00038   }
00039   ImageMolecule* mol;
00040   void operator()(const AtomPair& pair)
00041   {
00042     mol->insertPair(pair);
00043   }
00044 
00045 };
00046 
00047 struct IAInserter
00048 {
00049   IAInserter(ImageMolecule*mol) :
00050     mol(mol)
00051   {
00052   }
00053   ImageMolecule* mol;
00054   void operator()(const Ptr<ImageAtom>& atom)
00055   {
00056     mol->insertAtom(atom);
00057   }
00058 };
00059 }
00060 
00061 ImageMolecule::ImageMolecule()
00062 {
00063 
00064 }
00065 
00066 ImageMolecule::ImageMolecule(const ImageMolecule& rhs) :
00067   pairmap_(rhs.pairmap_), atoms_(rhs.atoms_), pairs_(rhs.pairs_), anchor_(rhs.anchor_)
00068 {
00069 
00070 }
00071 
00072 ImageMolecule::ImageMolecule(const std::list<AtomPair> & l_pairs)
00073 {
00074   if (l_pairs.size())
00075     setAnchor(l_pairs.front().atom1());
00076   insertPairs(l_pairs);
00077 }
00078 
00079 ImageMolecule::ImageMolecule(const std::vector<AtomPair> & pairs)
00080 {
00081   if (pairs.size())
00082     setAnchor(pairs.front().atom1());
00083   insertPairs(pairs);
00084 }
00085 
00086 void ImageMolecule::insertAtom(const Ptr<ImageAtom>& atom) throw ()
00087 {
00088   if (!hasAtom(atom))
00089     atoms_.insert(atom);
00090   if (anchor_.empty())
00091     setAnchor(atom);
00092 }
00093 
00094 void ImageMolecule::insertPair(const AtomPair& pair) throw ()
00095 {
00096   insertAtom(pair.atom1());
00097   insertAtom(pair.atom2());
00098   pairs_.push_back(pair);
00099   size_t idx = pairs_.size() - 1;
00100   pairmap_[pair.atom1()].push_back(idx);
00101   pairmap_[pair.atom2()].push_back(idx);
00102 }
00103 
00104 void ImageMolecule::peelAtoms(int flag)
00105 {
00106   set<Ptr<ImageAtom> >::iterator aitr = this->atoms_.begin();
00107   for (; aitr != atoms_.end(); ++aitr)
00108   {
00109     Ptr<ImageAtom> atom = *aitr;//)->flush();
00110     atom->flush();
00111   }
00112 }
00113 
00114 namespace
00115 {
00116 bool badpairpredicate(const AtomPair& pair)
00117 {
00118   return !pair.result().empty() && pair.result().success();
00119 }
00120 
00121 }
00122 
00123 bool ImageMolecule::removePair(const AtomPair& pair) throw ()
00124 {
00125   vector<AtomPair>::iterator it = std::find(pairs_.begin(), pairs_.end(), pair);
00126   if (it != pairs_.end())
00127   {
00128     pairs_.erase(it);
00129     pairmap_.clear();
00130     std::vector<AtomPair> tpairs = pairs_;
00131     pairs_.clear();
00132     insertPairs(tpairs);
00133     return true;
00134   }
00135   return false;
00136 }
00137 
00138 void ImageMolecule::removeBadPairs()
00139 {
00140   std::remove_if(pairs_.begin(), pairs_.end(), badpairpredicate);
00141   pairmap_.clear();
00142   std::vector<AtomPair> tpairs = pairs_;
00143   pairs_.clear();
00144   insertPairs(tpairs);
00145 }
00146 
00147 void ImageMolecule::insertPairs(const vector<AtomPair>& pairs) throw ()
00148 {
00149   for_each(pairs.begin(), pairs.end(), IAPairInserter(this));
00150 }
00151 
00152 void ImageMolecule::insertPairs(const list<AtomPair>& pairs) throw ()
00153 {
00154   for_each(pairs.begin(), pairs.end(), IAPairInserter(this));
00155 }
00156 
00157 void ImageMolecule::insertAtoms(const std::set<cv::Ptr<ImageAtom> > & atoms)
00158 {
00159   for_each(atoms.begin(), atoms.end(), IAInserter(this));
00160 }
00161 
00162 void ImageMolecule::setAnchor(const Ptr<ImageAtom>& atom) throw ()
00163 {
00164   anchor_ = atom;
00165 }
00166 
00167 vector<AtomPair>& ImageMolecule::getPairs() throw ()
00168 {
00169   return pairs_;
00170 }
00171 
00172 const vector<AtomPair>& ImageMolecule::getPairs() const throw ()
00173 {
00174   return pairs_;
00175 }
00176 const Ptr<ImageAtom>& ImageMolecule::getAnchor() const throw (std::logic_error)
00177 {
00178 
00179   if (atoms_.empty())
00180   {
00181     throw logic_error("The molecule is empty!");
00182   }
00183 
00184   //if the anchor has not been set then just return the begining of
00185   //atoms
00186   if (anchor_.empty())
00187     return *getAtoms().begin();
00188 
00189   return anchor_;
00190 }
00191 
00192 // TODO: Get list<int>* of atom pointers by UID Query
00193 
00194 const list<int>* ImageMolecule::getPairIndices(const Ptr<ImageAtom>& atom) const
00195 {
00196   map<Ptr<ImageAtom> , list<int> >::const_iterator it = pairmap_.find(atom);
00197   if (it == pairmap_.end())
00198   {
00199     cerr << "ERROR: requested atom is not in the molecule! " << endl;
00200     return NULL;
00201   }
00202   return &it->second;
00203 }
00204 
00205 const AtomPair* ImageMolecule::getPairByIndex(size_t idx) const
00206 {
00207   if (idx >= pairs_.size()) {
00208     cerr << "ERROR: requested atom index is bogus! " << endl;
00209     return NULL;
00210   }
00211   return &pairs_[idx];
00212 }
00213 
00214 void ImageMolecule::merge(Ptr<ImageAtom> pivot, const ImageMolecule& molecule)
00215 {
00216   //erase the pivot atom - if they are shared between the two
00217   //molecules
00218   if (atoms_.count(pivot))
00219   {
00220     atoms_.erase(pivot);
00221   }
00222 
00223   //first insert all the atoms
00224   atoms_.insert(molecule.atoms_.begin(), molecule.atoms_.end());
00225 
00226   //now insert the atom pair bonds
00227   pairs_.reserve(pairs_.size() + molecule.pairs_.size());
00228 
00229   //uses helper function object IAPairInserter
00230   //for stl for_each functionality
00231   for_each(molecule.pairs_.begin(), molecule.pairs_.end(), IAPairInserter(this));
00232 }
00233 
00234 set<Ptr<ImageAtom> >& ImageMolecule::getAtoms() throw ()
00235 {
00236   return atoms_;
00237 }
00238 
00239 const set<Ptr<ImageAtom> >& ImageMolecule::getAtoms() const throw ()
00240 {
00241   return atoms_;
00242 }
00243 
00244 bool ImageMolecule::hasAtom(const Ptr<ImageAtom>& atom) const throw ()
00245 {
00246   return atoms_.count(atom);
00247 }
00248 
00249 void ImageMolecule::hasAtomThrow(const Ptr<ImageAtom>& atom) const throw (std::logic_error)
00250 {
00251   if (!hasAtom(atom))
00252     throw logic_error("Atom not in the Molecule!");
00253 }
00254 
00255 namespace
00256 {
00257 
00258 typedef std::pair<int, Ptr<ImageAtom> > node_pair;
00259 bool node_sorter(const node_pair& lhs, const node_pair& rhs)
00260 {
00261   return lhs.first > rhs.first;
00262 }
00263 }
00264 
00265 Ptr<ImageAtom> ImageMolecule::getMaximallyConnectedAtom(int node_offset) const
00266 {
00267   std::vector<std::pair<int, Ptr<ImageAtom> > > node_connections;
00268   node_connections.reserve(atoms_.size());
00269 
00270   set<Ptr<ImageAtom> >::const_iterator it = atoms_.begin();
00271 
00272   while (it != atoms_.end())
00273   {
00274     const std::list<int>* indices = getPairIndices(*it);
00275     if (indices)
00276       node_connections.push_back(make_pair(indices->size(), *it));
00277     ++it;
00278   }
00279 
00280   sort(node_connections.begin(), node_connections.end(), node_sorter);
00281 
00282   if (node_connections.size())
00283   {
00284     if (node_offset < 0 || node_offset >= (int)node_connections.size())
00285     {
00286       std::cerr << "bogus value of node offset! " << std::endl;
00287       node_offset = 0;
00288     }
00289     return (node_connections[node_offset]).second;
00290   }
00291   else
00292     return NULL;
00293 
00294 }
00295 
00296 void ImageMolecule::serialize(cv::FileStorage& fs) const
00297 {
00298   fs << "{";
00299   fs << "atoms";
00300   {
00301     std::set<Ptr<ImageAtom> >::const_iterator atom = atoms_.begin();
00302     fs << "[";
00303     while (atom != atoms_.end())
00304     {
00305       (*atom)->serialize(fs);
00306       atom++;
00307     }
00308     fs << "]";
00309   }
00310   fs << "pairs";
00311 
00312   {
00313     std::vector<AtomPair>::const_iterator pit;
00314     fs << "[";
00315     for (pit = pairs_.begin(); pit != pairs_.end(); ++pit)
00316     {
00317       pit->serialize(fs);
00318     }
00319     fs << "]";
00320   }
00321   fs << "}";
00322 }
00323 void ImageMolecule::deserialize(const cv::FileNode& fn)
00324 {
00325   FileNode atoms = fn["atoms"];
00326   CV_Assert(atoms.type() == FileNode::SEQ);
00327 
00328   std::map<int, Ptr<ImageAtom> > a_map;
00329   for (size_t i = 0; i < atoms.size(); i++)
00330   {
00331     Ptr<ImageAtom> atom(new ImageAtom);
00332     atom->deserialize(atoms[i]);
00333     a_map[atom->uid()] = atom;
00334     //we will insert from pairs...
00335     insertAtom(atom);
00336   }
00337 
00338   FileNode pairs = fn["pairs"];
00339   CV_Assert(pairs.type() == FileNode::SEQ);
00340   vector<AtomPair> pairs_temp;
00341   pairs_temp.resize(pairs.size());
00342   for (size_t i = 0; i < pairs.size(); i++)
00343   {
00344     pairs_temp[i].deserialize(pairs[i]);
00345 
00346     pairs_temp[i].setAtom1(a_map[pairs_temp[i].atom1()->uid()]);
00347     pairs_temp[i].setAtom2(a_map[pairs_temp[i].atom2()->uid()]);
00348 
00349   }
00350 
00351   insertPairs(pairs_temp);
00352 
00353 }
00354 
00355 //void ImageMolecule::serialize(std::ostream& out, int  flags)const{
00356 //
00357 //    std::set<Ptr<ImageAtom> >::const_iterator atom = imageatoms.begin();
00358 //    out << "[" << imageatoms.size() << "]";
00359 //    while(atom != imageatoms.end()){
00360 //        (*atom)->serialize(out,ImageAtom::SERIALIZE_ATOM);
00361 //        atom++;
00362 //    }
00363 //    out << "[" << atom_pair_bonds.size() << "]";
00364 //
00365 //    std::vector<AtomPair>::const_iterator pit;
00366 //
00367 //    for (pit = atom_pair_bonds.begin(); pit != atom_pair_bonds.end(); ++pit) {
00368 //        pit->serialize(out);
00369 //    }
00370 //
00371 //}
00372 
00373 
00374 //void ImageMolecule::deserialize(std::istream& in, int  flags){
00375 //
00376 //    Atoms().resetPool();
00377 //
00378 //    int atoms_size;
00379 //    eatchar(in, '[');
00380 //    in >> atoms_size;
00381 //    eatchar(in, ']');
00382 //
00383 //    for(int i = 0; i < atoms_size; i++){
00384 //        cv::Ptr<ImageAtom> atom = new ImageAtom();
00385 //
00386 //        atom->deserialize(in,ImageAtom::DESERIALIZE_ATOM);
00387 //
00388 //        //add the atom to the atom pool to alleviate redundant
00389 //        //atoms
00390 //        atom = Atoms().getAtom(*atom);
00391 //        insertAtom(atom);
00392 //    }
00393 //
00394 //    int pairs_size;
00395 //    eatchar(in, '[');
00396 //    in >> pairs_size;
00397 //    eatchar(in, ']');
00398 //
00399 //    for(int i = 0; i < pairs_size; i++){
00400 //       AtomPair pair;
00401 //       pair.deserialize(in);
00402 //       insertPair(pair);
00403 //    }
00404 //
00405 //}
00406 
00407 
00408 }


pano_core
Author(s): Ethan Rublee
autogenerated on Wed Aug 26 2015 16:34:01