1 // This file is part of OpenMVG, an Open Multiple View Geometry C++ library.
2 
3 // Copyright (c) 2012, 2013 Pierre MOULON.
4 
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #ifndef OPENMVG_MATCHING_IND_MATCH_HPP
10 #define OPENMVG_MATCHING_IND_MATCH_HPP
11 
12 #include <iostream>
13 #include <map>
14 #include <set>
15 #include <utility>
16 #include <vector>
17 
18 #include "openMVG/types.hpp"
19 
20 namespace openMVG {
21 namespace matching {
22 
23 /// Structure in order to save pairwise indexed references.
24 /// A sort operator exist in order to remove duplicates of IndMatch series.
25 struct IndMatch
26 {
IndMatchopenMVG::matching::IndMatch27   IndMatch(const IndexT i = 0, const IndexT j = 0) : i_(i), j_(j)  {}
28 
29   /// Remove duplicates ((i_, j_) that appears multiple times)
getDeduplicatedopenMVG::matching::IndMatch30   static bool getDeduplicated(std::vector<IndMatch> & vec_match)  {
31 
32     const size_t sizeBefore = vec_match.size();
33     const std::set<IndMatch> set_deduplicated( vec_match.cbegin(), vec_match.cend());
34     vec_match.assign(set_deduplicated.cbegin(), set_deduplicated.cend());
35     return sizeBefore != vec_match.size();
36   }
37 
38   // Serialization
39   template <class Archive>
40   void serialize( Archive & ar );
41 
42   IndexT i_, j_;  // Left, right index
43 };
44 
operator ==(const IndMatch & m1,const IndMatch & m2)45 inline bool operator==(const IndMatch& m1, const IndMatch& m2)  {
46   return (m1.i_ == m2.i_ && m1.j_ == m2.j_);
47 }
48 
operator !=(const IndMatch & m1,const IndMatch & m2)49 inline bool operator!=(const IndMatch& m1, const IndMatch& m2)  {
50   return !(m1 == m2);
51 }
52 
53 // Lexicographical ordering of matches. Used to remove duplicates
operator <(const IndMatch & m1,const IndMatch & m2)54 inline bool operator<(const IndMatch& m1, const IndMatch& m2)  {
55   return (m1.i_ < m2.i_ || (m1.i_ == m2.i_ && m1.j_ < m2.j_));
56 }
57 
operator <<(std::ostream & out,const IndMatch & obj)58 inline std::ostream& operator<<(std::ostream & out, const IndMatch & obj) {
59   return out << obj.i_ << " " << obj.j_;
60 }
61 
operator >>(std::istream & in,IndMatch & obj)62 inline std::istream& operator>>(std::istream & in, IndMatch & obj) {
63   return in >> obj.i_ >> obj.j_;
64 }
65 
66 using IndMatches = std::vector<matching::IndMatch>;
67 
68 /// Pairwise matches (indexed matches for a pair <I,J>)
69 /// The interface used to store corresponding point indexes per images pairs
70 class PairWiseMatchesContainer
71 {
72 public:
73   virtual ~PairWiseMatchesContainer() = default;
74   virtual void insert(std::pair<Pair, IndMatches>&& pairWiseMatches) = 0;
75 };
76 
77 //--
78 /// Pairwise matches (indexed matches for a pair <I,J>)
79 /// A structure used to store corresponding point indexes per images pairs
80 struct PairWiseMatches :
81   public PairWiseMatchesContainer,
82   public std::map<Pair, IndMatches>
83 {
insertopenMVG::matching::PairWiseMatches84   void insert(std::pair<Pair, IndMatches> && pairWiseMatches)override
85   {
86     std::map<Pair, IndMatches>::insert(
87       std::forward<std::pair<Pair, IndMatches>>(pairWiseMatches));
88   }
89 
90   // Serialization
91   template <class Archive>
serializeopenMVG::matching::PairWiseMatches92   void serialize( Archive & ar )  {
93     ar(static_cast<std::map<Pair, IndMatches>&>(*this));
94   }
95 };
96 
getPairs(const PairWiseMatches & matches)97 inline Pair_Set getPairs(const PairWiseMatches & matches)
98 {
99   Pair_Set pairs;
100   for ( const auto & cur_pair : matches )
101     pairs.insert(cur_pair.first);
102   return pairs;
103 }
104 
105 /**
106  * @brief Get the subset of the matches that corresponds to the given pairs
107  *
108  * @param matches     Initial matches
109  * @param pairs       The only pairs to keep
110  * @return PairWiseMatches The matches that are inside the pairset
111  */
getPairs(const PairWiseMatches & matches,const Pair_Set & pairs)112 inline PairWiseMatches getPairs( const PairWiseMatches & matches, const Pair_Set & pairs )
113 {
114   PairWiseMatches res;
115   for( auto it_pair : pairs )
116   {
117     if( matches.count( it_pair ) )
118     {
119       res.insert( std::make_pair( it_pair , matches.at( it_pair ) ) );
120     }
121   }
122   return res;
123 }
124 
125 }  // namespace matching
126 }  // namespace openMVG
127 
128 
129 #endif // OPENMVG_MATCHING_IND_MATCH_HPP
130