FunctorBrute4pcs.h
Go to the documentation of this file.
1 
2 #ifndef BRUTE4PCS_FUNCTOR4PCS_H
3 #define BRUTE4PCS_FUNCTOR4PCS_H
4 
5 #include <vector>
6 #include "gr/utils/shared.h"
7 #include "gr/algorithms/match4pcsBase.h"
8 
9 
10 namespace gr {
11  /// Processing functor for the computation of the 4PCS algorithm
12  /// \see Match4pcsBase
13  /// \tparam PairFilterFunctor filters pairs of points during the exploration.
14  /// Must implement PairFilterConcept
15  template <typename PointType, typename PairFilterFunctor, typename Options>
17  public :
18  using BaseCoordinates = typename Traits4pcs<PointType>::Coordinates;
19  using Scalar = typename PointType::Scalar;
20  using PairsVector = std::vector< std::pair<int, int> >;
21  using VectorType = typename PointType::VectorType;
22  using OptionType = Options;
23 
24 
25  private :
26  OptionType myOptions_;
27  std::vector<PointType>& mySampled_Q_3D_;
28  BaseCoordinates &myBase_3D_;
29 
30 
31  public :
32  inline FunctorBrute4PCS(std::vector<PointType> &sampled_Q_3D_,
33  BaseCoordinates& base_3D_,
34  const OptionType &options)
36  ,myBase_3D_(base_3D_)
37  ,myOptions_ (options) {}
38 
39  /// Initializes the data structures and needed values before the match
40  /// computation.
41  inline void Initialize() {}
42 
43  /// Finds congruent candidates in the set Q, given the invariants and threshold distances.
44  /// Returns true if a non empty set can be found, false otherwise.
45  /// @param invariant1 [in] The first invariant corresponding to the set P_pairs
46  /// of pairs, previously extracted from Q.
47  /// @param invariant2 [in] The second invariant corresponding to the set
48  /// Q_pairs of pairs, previously extracted from Q.
49  /// @param [in] distance_threshold1 The distance for verification.
50  /// @param [in] distance_threshold2 The distance for matching middle points due
51  /// to the invariants (See the paper for e1, e2).
52  /// @param [in] First_pairs The first set of pairs found in Q.
53  /// @param [in] Second_pairs The second set of pairs found in Q.
54  /// @param [out] quadrilaterals The set of congruent quadrilateral. In fact,
55  /// it's a super set from which we extract the real congruent set.
57  Scalar invariant1,
58  Scalar invariant2,
59  Scalar /*distance_threshold1*/,
60  Scalar distance_threshold2,
61  const std::vector <std::pair<int, int>> &First_pairs,
62  const std::vector <std::pair<int, int>> &Second_pairs,
63  typename Traits4pcs<PointType>::Set* quadrilaterals) const {
64  using VectorType = typename PointType::VectorType;
65 
66  if (quadrilaterals == nullptr) return false;
67 
68  size_t number_of_points = 2 * First_pairs.size();
69 
70  // We need a temporary kdtree to store the new points corresponding to
71  // invariants in the First_pairs and then query them (for range search) for all
72  // the new points corresponding to the invariants in Second_pairs.
73  quadrilaterals->clear();
74 
75  std::vector<VectorType> invariant1Set;
76  invariant1Set.reserve(number_of_points);
77 
78  // build invariants for the first pair set
79  for (size_t i = 0; i < First_pairs.size(); ++i) {
80  const VectorType &p1 = mySampled_Q_3D_[First_pairs[i].first].pos();
81  const VectorType &p2 = mySampled_Q_3D_[First_pairs[i].second].pos();
82  invariant1Set.push_back(p1 + invariant1 * (p2 - p1));
83  }
84 
85  VectorType query;
86  for (size_t i = 0; i < Second_pairs.size(); ++i) {
87  const VectorType &p1 = mySampled_Q_3D_[Second_pairs[i].first].pos();
88  const VectorType &p2 = mySampled_Q_3D_[Second_pairs[i].second].pos();
89 
90  query = p1 + invariant2 * (p2 - p1);
91  for (size_t j = 0; j < invariant1Set.size(); ++j) {
92  const auto&other = invariant1Set[j];
93  if ( (query - other).squaredNorm() < distance_threshold2 )
94  quadrilaterals->push_back(
95  { First_pairs[j].first,
96  First_pairs[j].second,
97  Second_pairs[i].first,
98  Second_pairs[i].second });
99  }
100  }
101 
102  return quadrilaterals->size() != 0;
103  }
104 
105  /// Constructs pairs of points in Q, corresponding to a single pair in the
106  /// in basein P.
107  /// @param [in] pair_distance The distance between the pairs in P that we have
108  /// to match in the pairs we select from Q.
109  /// @param [in] pair_normal_distance The angle between the normals of the pair
110  /// in P.
111  /// @param [in] pair_distance_epsilon Tolerance on the pair distance. We allow
112  /// candidate pair in Q to have distance of
113  /// pair_distance+-pair_distance_epsilon.
114  /// @param [in] base_point1 The index of the first point in P.
115  /// @param [in] base_point2 The index of the second point in P.
116  /// @param [out] pairs A set of pairs in Q that match the pair in P with
117  /// respect to distance and normals, up to the given tolerance.
118  inline void ExtractPairs(Scalar pair_distance,
119  Scalar pair_normals_angle,
120  Scalar pair_distance_epsilon,
121  int base_point1,
122  int base_point2,
123  PairsVector* pairs) const {
124  if (pairs == nullptr) return;
125 
126  pairs->clear();
127  pairs->reserve(2 * mySampled_Q_3D_.size());
128 
129  PairFilterFunctor fun;
130 
131  // Go over all ordered pairs in Q.
132  for (size_t j = 0; j < mySampled_Q_3D_.size(); ++j) {
133  const PointType& p = mySampled_Q_3D_[j];
134  for (size_t i = j + 1; i < mySampled_Q_3D_.size(); ++i) {
135  const PointType& q = mySampled_Q_3D_[i];
136 #ifndef MULTISCALE
137  // Compute the distance and two normal angles to ensure working with
138  // wrong orientation. We want to verify that the angle between the
139  // normals is close to the angle between normals in the base. This can be
140  // checked independent of the full rotation angles which are not yet
141  // defined by segment matching alone..
142  const Scalar distance = (q.pos() - p.pos()).norm();
143  if (std::abs(distance - pair_distance) > pair_distance_epsilon) continue;
144 #endif
145 
146  std::pair<bool,bool> res = fun(p,q, pair_normals_angle, *myBase_3D_[base_point1],*myBase_3D_[base_point2], myOptions_);
147  if (res.first)
148  pairs->emplace_back(i, j);
149  if (res.second)
150  pairs->emplace_back(j, i);
151  }
152  }
153  }
154 
155  };
156 }
157 
158 
159 #endif //BRUTE4PCS_FUNCTOR4PCS_H
Processing functor for the computation of the 4PCS algorithm.
Definition: FunctorBrute4pcs.h:16
bool FindCongruentQuadrilaterals(Scalar invariant1, Scalar invariant2, Scalar, Scalar distance_threshold2, const std::vector< std::pair< int, int >> &First_pairs, const std::vector< std::pair< int, int >> &Second_pairs, typename Traits4pcs< PointType >::Set *quadrilaterals) const
Finds congruent candidates in the set Q, given the invariants and threshold distances. Returns true if a non empty set can be found, false otherwise.
Definition: FunctorBrute4pcs.h:56
static constexpr int size()
Definition: match4pcsBase.h:27
void Initialize()
Initializes the data structures and needed values before the match computation.
Definition: FunctorBrute4pcs.h:41
CongruentSetExplorationBase< Traits, PointType, TransformVisitor, PairFilteringFunctor, OptExts... >::Scalar ComputeTransformation(const InputRange1 &P, const InputRange2 &Q, Eigen::Ref< typename CongruentSetExplorationBase< Traits, PointType, TransformVisitor, PairFilteringFunctor, OptExts... >::MatrixType > transformation, const Sampler< PointType > &sampler, TransformVisitor &v)
Definition: congruentSetExplorationBase.hpp:61
FunctorBrute4PCS(std::vector< PointType > &sampled_Q_3D_, BaseCoordinates &base_3D_, const OptionType &options)
Definition: FunctorBrute4pcs.h:32
void ExtractPairs(Scalar pair_distance, Scalar pair_normals_angle, Scalar pair_distance_epsilon, int base_point1, int base_point2, PairsVector *pairs) const
Constructs pairs of points in Q, corresponding to a single pair in the in basein P.
Definition: FunctorBrute4pcs.h:118