FunctorSuper4pcs.h
Go to the documentation of this file.
1 //
2 // Created by Sandra Alfaro on 24/04/18.
3 //
4 
5 #ifndef SUPER4PCS_FUNCTORSUPER4PCS_H
6 #define SUPER4PCS_FUNCTORSUPER4PCS_H
7 
8 
9 #include <vector>
10 #include "gr/utils/shared.h"
11 #include "gr/algorithms/pairCreationFunctor.h"
12 
13 #ifdef SUPER4PCS_USE_CHEALPIX
14 #include "gr/accelerators/normalHealSet.h"
15 #else
16 #include "gr/accelerators/normalset.h"
17 #include "gr/accelerators/utils.h"
18 
19 #endif
20 
21 #include <fstream>
22 #include <array>
23 #include <time.h>
24 
25 namespace gr {
26 
27  /// Processing functor for the computation of the Super4PCS algorithm
28  /// \see Match4pcsBase
29  /// \tparam PairFilterFunctor filters pairs of points during the exploration.
30  /// Must implement PairFilterConcept
31  template <typename PointType, typename PointFilterFunctor, typename Options>
33  public :
34  using BaseCoordinates = typename Traits4pcs<PointType>::Coordinates;
35  using Scalar = typename PointType::Scalar;
36  using PairsVector = std::vector< std::pair<int, int> >;
37  using VectorType = typename PointType::VectorType;
38  using OptionType = Options;
39  using PairCreationFunctorType = PairCreationFunctor<PointType, Scalar, PointFilterFunctor, OptionType>;
40 
41 
42  private :
43  std::vector<PointType> &mySampled_Q_3D_;
44  BaseCoordinates &myBase_3D_;
45 
46  mutable PairCreationFunctorType pcfunctor_;
47 
48 
49  public :
50  inline FunctorSuper4PCS (std::vector<PointType> &sampled_Q_3D_,
51  BaseCoordinates& base_3D_,
52  const OptionType& options)
54  ,myBase_3D_(base_3D_)
56 
57  /// Initializes the data structures and needed values before the match
58  /// computation.
59  inline void Initialize() {
60  pcfunctor_.synch3DContent();
61  }
62 
63 
64  /// Constructs pairs of points in Q, corresponding to a single pair in the
65  /// in basein P.
66  /// @param [in] pair_distance The distance between the pairs in P that we have
67  /// to match in the pairs we select from Q.
68  /// @param [in] pair_distance_epsilon Tolerance on the pair distance. We allow
69  /// candidate pair in Q to have distance of
70  /// pair_distance+-pair_distance_epsilon.
71  /// @param [in] base_point1 The index of the first point in P.
72  /// @param [in] base_point2 The index of the second point in P.
73  /// @param [out] pairs A set of pairs in Q that match the pair in P with
74  /// respect to distance and normals, up to the given tolerance.
75  inline void ExtractPairs(Scalar pair_distance,
76  Scalar pair_normals_angle,
77  Scalar pair_distance_epsilon,
78  int base_point1,
79  int base_point2,
80  PairsVector* pairs) const {
81 
82  pcfunctor_.pairs = pairs;
83 
84  pairs->clear();
85  pairs->reserve(2 * pcfunctor_.points.size());
86 
87  pcfunctor_.pair_distance = pair_distance;
88  pcfunctor_.pair_distance_epsilon = pair_distance_epsilon;
89  pcfunctor_.pair_normals_angle = pair_normals_angle;
90  pcfunctor_.setRadius(pair_distance);
91  pcfunctor_.setBase(base_point1, base_point2, myBase_3D_);
92 
93 #ifdef MULTISCALE
94  BruteForceFunctor
95  <typename PairCreationFunctorType::Primitive, typename PairCreationFunctorType::Point, 3, Scalar> interFunctor;
96 #else
98  <typename PairCreationFunctorType::Primitive,
99  typename PairCreationFunctorType::Point, 3, Scalar> interFunctor;
100 #endif
101 
102  Scalar eps = pcfunctor_.getNormalizedEpsilon(pair_distance_epsilon);
103 
104  interFunctor.process(pcfunctor_.primitives,
105  pcfunctor_.points,
106  eps,
107  50,
108  pcfunctor_);
109  }
110 
111  /// Finds congruent candidates in the set Q, given the invariants and threshold
112  /// distances. Returns true if a non empty set can be found, false otherwise.
113  /// @param invariant1 [in] The first invariant corresponding to the set P_pairs
114  /// of pairs, previously extracted from Q.
115  /// @param invariant2 [in] The second invariant corresponding to the set
116  /// Q_pairs of pairs, previously extracted from Q.
117  /// @param [in] distance_threshold1 The distance for verification.
118  /// @param [in] distance_threshold2 The distance for matching middle points due
119  /// to the invariants (See the paper for e1, e2).
120  /// @param [in] First_pairs The first set of pairs found in Q.
121  /// @param [in] Second_pairs The second set of pairs found in Q.
122  /// @param [out] quadrilaterals The set of congruent quadrilateral. In fact,
123  /// it's a super set from which we extract the real congruent set.
125  Scalar invariant1,
126  Scalar invariant2,
127  Scalar /*distance_threshold1*/,
128  Scalar distance_threshold2,
129  const std::vector<std::pair<int, int>>& First_pairs,
130  const std::vector<std::pair<int, int>>& Second_pairs,
131  typename Traits4pcs<PointType>::Set* quadrilaterals) const {
132 
133  typedef typename PairCreationFunctorType::Point Point;
134 
135 #ifdef SUPER4PCS_USE_CHEALPIX
136  typedef gr::IndexedNormalHealSet IndexedNormalSet3D;
137 #else
138  typedef gr::IndexedNormalSet
139  < Point, //! \brief Point type used internally
140  3, //! \brief Nb dimension
141  7, //! \brief Nb cells/dim normal
142  Scalar> //! \brief Scalar type
143  IndexedNormalSet3D;
144 #endif
145 
146 
147  if (quadrilaterals == nullptr) return false;
148 
149  quadrilaterals->clear();
150 
151  // Compute the angle formed by the two vectors of the basis
152  const Scalar alpha =
153  (myBase_3D_[1]->pos() - myBase_3D_[0]->pos()).normalized().dot(
154  (myBase_3D_[3]->pos() - myBase_3D_[2]->pos()).normalized());
155 
156  // 1. Datastructure construction
157  const Scalar eps = pcfunctor_.getNormalizedEpsilon(distance_threshold2);
158 
159  IndexedNormalSet3D nset (eps);
160 
161  for (size_t i = 0; i < First_pairs.size(); ++i) {
162  const Point& p1 = pcfunctor_.points[First_pairs[i].first];
163  const Point& p2 = pcfunctor_.points[First_pairs[i].second];
164  const Point n = (p2 - p1).normalized();
165 
166  nset.addElement((p1+ typename Point::Scalar(invariant1) * (p2 - p1)).eval(), n, i);
167  }
168 
169 
170  std::set< std::pair<unsigned int, unsigned int > > comb;
171 
172  std::vector<unsigned int> nei;
173  // 2. Query time
174  for (unsigned int i = 0; i < Second_pairs.size(); ++i) {
175  const Point& p1 = pcfunctor_.points[Second_pairs[i].first];
176  const Point& p2 = pcfunctor_.points[Second_pairs[i].second];
177 
178  const VectorType& pq1 = mySampled_Q_3D_[Second_pairs[i].first].pos();
179  const VectorType& pq2 = mySampled_Q_3D_[Second_pairs[i].second].pos();
180 
181  nei.clear();
182 
183  const Point query = p1 + invariant2 * ( p2 - p1 );
184  const VectorType queryQ = pq1 + invariant2 * (pq2 - pq1);
185 
186  const Point queryn = (p2 - p1).normalized();
187 
188  nset.getNeighbors( query, queryn, alpha, nei);
189 
190 
191  VectorType invPoint;
192  //const Scalar distance_threshold2s = distance_threshold2 * distance_threshold2;
193  for (unsigned int k = 0; k != nei.size(); k++){
194  const int id = nei[k];
195 
196  const VectorType& pp1 = mySampled_Q_3D_[First_pairs[id].first].pos();
197  const VectorType& pp2 = mySampled_Q_3D_[First_pairs[id].second].pos();
198 
199  invPoint = pp1 + (pp2 - pp1) * invariant1;
200 
201  // use also distance_threshold2 for inv 1 and 2 in 4PCS
202  if ((queryQ-invPoint).squaredNorm() <= distance_threshold2){
203  comb.emplace(id, i);
204  }
205  }
206  }
207 
208  for (std::set< std::pair<unsigned int, unsigned int>>::const_iterator it = comb.cbegin();
209  it != comb.cend(); it++) {
210  const unsigned int & id = (*it).first;
211  const unsigned int & i = (*it).second;
212 
213  quadrilaterals->push_back( {First_pairs[id].first, First_pairs[id].second,
214  Second_pairs[i].first, Second_pairs[i].second });
215  }
216 
217  return quadrilaterals->size() != 0;
218  }
219 
220  };
221 }
222 
223 #endif //SUPER4PCS_FUNCTORSUPER4PCS_H
Definition: pairCreationFunctor.h:16
static constexpr int size()
Definition: match4pcsBase.h:27
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: FunctorSuper4pcs.h:124
Extract pairs of points by rasterizing primitives and collect points.
Definition: intersectionFunctor.h:74
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
Processing functor for the computation of the Super4PCS algorithm.
Definition: FunctorSuper4pcs.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: FunctorSuper4pcs.h:75
void Initialize()
Initializes the data structures and needed values before the match computation.
Definition: FunctorSuper4pcs.h:59
void getNeighbors(const Point &p, const Point &n, Scalar alpha, std::vector< unsigned int > &nei, bool tryReverse=false)
Get closest poitns in euclidean an normal space with angular deviation.
Definition: normalset.hpp:177
FunctorSuper4PCS(std::vector< PointType > &sampled_Q_3D_, BaseCoordinates &base_3D_, const OptionType &options)
Definition: FunctorSuper4pcs.h:50