Go to the documentation of this file.00001
00002
00003
00004
00005
00006
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
00031
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;
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
00185
00186 if (anchor_.empty())
00187 return *getAtoms().begin();
00188
00189 return anchor_;
00190 }
00191
00192
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
00217
00218 if (atoms_.count(pivot))
00219 {
00220 atoms_.erase(pivot);
00221 }
00222
00223
00224 atoms_.insert(molecule.atoms_.begin(), molecule.atoms_.end());
00225
00226
00227 pairs_.reserve(pairs_.size() + molecule.pairs_.size());
00228
00229
00230
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
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
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 }