Super4PCS Library  V1.1.2(719f5c0)
match4pcsBase.h
1 // Copyright 2017 Nicolas Mellado
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // -------------------------------------------------------------------------- //
16 //
17 // Authors: Dror Aiger, Yoni Weill, Nicolas Mellado
18 //
19 // This file is part of the implementation of the 4-points Congruent Sets (4PCS)
20 // algorithm presented in:
21 //
22 // 4-points Congruent Sets for Robust Surface Registration
23 // Dror Aiger, Niloy J. Mitra, Daniel Cohen-Or
24 // ACM SIGGRAPH 2008 and ACM Transaction of Graphics.
25 //
26 // Given two sets of points in 3-space, P and Q, the algorithm applies RANSAC
27 // in roughly O(n^2) time instead of O(n^3) for standard RANSAC, using an
28 // efficient method based on invariants, to find the set of all 4-points in Q
29 // that can be matched by rigid transformation to a given set of 4-points in P
30 // called a base. This avoids the need to examine all sets of 3-points in Q
31 // against any base of 3-points in P as in standard RANSAC.
32 // The algorithm can use colors and normals to speed-up the matching
33 // and to improve the quality. It can be easily extended to affine/similarity
34 // transformation but then the speed-up is smaller because of the large number
35 // of congruent sets. The algorithm can also limit the range of transformations
36 // when the application knows something on the initial pose but this is not
37 // necessary in general (though can speed the runtime significantly).
38 
39 // Home page of the 4PCS project (containing the paper, presentations and a
40 // demo): http://graphics.stanford.edu/~niloy/research/fpcs/fpcs_sig_08.html
41 // Use google search on "4-points congruent sets" to see many related papers
42 // and applications.
43 
44 #ifndef _SUPER4PCS_ALGO_MATCH_4PCS_BASE_
45 #define _SUPER4PCS_ALGO_MATCH_4PCS_BASE_
46 
47 #include <vector>
48 
49 #ifdef SUPER4PCS_USE_OPENMP
50 #include <omp.h>
51 #endif
52 
53 #include "super4pcs/shared4pcs.h"
54 #include "super4pcs/sampling.h"
55 #include "super4pcs/accelerators/kdtree.h"
56 #include "super4pcs/utils/logger.h"
57 
58 #ifdef TEST_GLOBAL_TIMINGS
59 # include "super4pcs/utils/timer.h"
60 #endif
61 
62 namespace GlobalRegistration{
63 
64 
66 
67 public:
68  using PairsVector = std::vector< std::pair<int, int> >;
69  using Scalar = typename Point3D::Scalar;
70  using VectorType = typename Point3D::VectorType;
71  using MatrixType = Eigen::Matrix<Scalar, 4, 4>;
74  inline void operator() (float, float, Eigen::Ref<Match4PCSBase::MatrixType>) const {}
75  constexpr bool needsGlobalTransformation() const { return false; }
76  };
78 
79  static constexpr int kNumberOfDiameterTrials = 1000;
80  static constexpr Scalar kLargeNumber = 1e9;
81  static constexpr Scalar distance_factor = 2.0;
82 
83  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
84 
85  virtual ~Match4PCSBase();
86 
88  inline const std::vector<Point3D>& getFirstSampled() const {
89  return sampled_P_3D_;
90  }
91 
93  inline const std::vector<Point3D>& getSecondSampled() const {
94  return sampled_Q_3D_;
95  }
96 
108  template <typename Sampler = DefaultSampler,
109  typename Visitor = DummyTransformVisitor>
110  Scalar
111  ComputeTransformation(const std::vector<Point3D>& P,
112  std::vector<Point3D>* Q,
113  Eigen::Ref<MatrixType> transformation,
114  const Sampler& sampler = Sampler(),
115  const Visitor& v = Visitor());
116 
117 
118 protected:
120  int number_of_trials_;
125  Scalar max_base_diameter_;
127  Scalar P_diameter_;
130  Scalar P_mean_distance_;
132  Eigen::Matrix<Scalar, 4, 4> transform_;
137  Eigen::Matrix<Scalar, 3, 1> qcentroid1_, qcentroid2_;
140  int base_[4];
144  int current_congruent_[4];
146  std::vector<Point3D> sampled_P_3D_;
148  std::vector<Point3D> sampled_Q_3D_;
150  std::vector<Point3D> base_3D_;
153  std::vector<Point3D> Q_copy_;
155  VectorType centroid_P_;
157  VectorType centroid_Q_;
159  Scalar best_LCP_;
161  int current_trial_;
163  KdTree<Scalar> kd_tree_;
165  const Match4PCSOptions options_;
166 
167  std::mt19937 randomGenerator_;
168 
169  const Utils::Logger &logger_;
170 
171 #ifdef SUPER4PCS_USE_OPENMP
172  const int omp_nthread_congruent_;
174 #endif
175 
176 #ifdef TEST_GLOBAL_TIMINGS
177 
178  Scalar totalTime;
179  Scalar kdTreeTime;
180  Scalar verifyTime;
181 
182  using Timer = GlobalRegistration::Utils::Timer;
183 
184 #endif
185 
186 protected:
187 
188  Match4PCSBase(const Match4PCSOptions& options
189  , const Utils::Logger &logger
190 #ifdef SUPER4PCS_USE_OPENMP
191  , const int omp_nthread_congruent = omp_get_max_threads()
192 #endif
193  );
194 
195  template <Utils::LogLevel level, typename...Args>
196  inline void Log(Args...args) const { logger_.Log<level>(args...); }
197 
198 
202  Scalar MeanDistance();
203 
204 
212  bool SelectRandomTriangle(int& base1, int& base2, int& base3);
213 
218  bool TryQuadrilateral(Scalar &invariant1, Scalar &invariant2,
219  int &base1, int &base2, int &base3, int &base4);
220 
221 
232  bool ComputeRigidTransformation(const std::array<Point3D, 4>& ref,
233  const std::array<Point3D, 4>& candidate,
234  const Eigen::Matrix<Scalar, 3, 1>& centroid1,
235  Eigen::Matrix<Scalar, 3, 1> centroid2,
236  Scalar max_angle,
237  Eigen::Ref<MatrixType> transform,
238  Scalar& rms_,
239  bool computeScale ) const;
240 
245  Scalar Verify(const Eigen::Ref<const MatrixType> & mat) const;
246 
251  template <typename Visitor>
252  bool Perform_N_steps(int n,
253  Eigen::Ref<MatrixType> transformation,
254  std::vector<Point3D>* Q,
255  const Visitor& v);
256 
260  template <typename Visitor>
261  bool TryOneBase(const Visitor &v);
262 
270  virtual void
271  Initialize(const std::vector<Point3D>& P,
272  const std::vector<Point3D>& Q) = 0;
273 
274  template <typename Sampler>
275  void init(const std::vector<Point3D>& P,
276  const std::vector<Point3D>& Q,
277  const Sampler& sampler);
278 
282  bool SelectQuadrilateral(Scalar &invariant1, Scalar &invariant2,
283  int& base1, int& base2, int& base3, int& base4);
284 
285  const std::vector<Point3D>& base3D() const { return base_3D_; }
286 
300  virtual void
301  ExtractPairs( Scalar pair_distance,
302  Scalar pair_normals_angle,
303  Scalar pair_distance_epsilon, int base_point1,
304  int base_point2,
305  PairsVector* pairs) const = 0;
306 
320  virtual bool
321  FindCongruentQuadrilaterals(Scalar invariant1, Scalar invariant2,
322  Scalar distance_threshold1,
323  Scalar distance_threshold2,
324  const PairsVector& P_pairs,
325  const PairsVector& Q_pairs,
326  std::vector<Quadrilateral>* quadrilaterals) const = 0;
327 
331  template <typename Visitor>
332  bool TryCongruentSet(int base_id1,
333  int base_id2,
334  int base_id3,
335  int base_id4,
336  const std::vector<Quadrilateral> &congruent_quads,
337  const Visitor &v,
338  size_t &nbCongruent);
339 private:
340  void initKdTree();
341 
342 };
343 }
344 
345 #include "super4pcs/algorithms/match4pcsBase.hpp"
346 
347 #endif
std::vector< std::pair< int, int > > PairsVector
Definition: match4pcsBase.h:68
const std::vector< Point3D > & getSecondSampled() const
Read access to the sampled clouds used for the registration.
Definition: match4pcsBase.h:93
Eigen::Matrix< Scalar, 4, 4 > MatrixType
Definition: match4pcsBase.h:71
static constexpr int kNumberOfDiameterTrials
Definition: match4pcsBase.h:79
Scalar ComputeTransformation(const std::vector< Point3D > &P, std::vector< Point3D > *Q, Eigen::Ref< MatrixType > transformation, const Sampler &sampler=Sampler(), const Visitor &v=Visitor())
Computes an approximation of the best LCP (directional) from Q to P and the rigid transformation that...
Definition: match4pcsBase.hpp:63
Sampling::UniformDistSampler DefaultSampler
Definition: match4pcsBase.h:77
void Log(const Args &...args) const
Definition: logger.h:74
Definition: bbox.h:54
typename Point3D::VectorType VectorType
Definition: match4pcsBase.h:70
LogLevel
Definition: logger.h:55
Definition: match4pcsBase.h:65
Eigen::Matrix< Scalar, 3, 1 > VectorType
Definition: shared4pcs.h:64
const std::vector< Point3D > & getFirstSampled() const
Read access to the sampled clouds used for the registration.
Definition: match4pcsBase.h:88
static constexpr Scalar distance_factor
Definition: match4pcsBase.h:81
void operator()(float, float, Eigen::Ref< Match4PCSBase::MatrixType >) const
Definition: match4pcsBase.h:74
delta and overlap_estimation are the application parameters. All other parameters are more likely to ...
Definition: shared4pcs.h:148
float Scalar
Definition: shared4pcs.h:63
constexpr bool needsGlobalTransformation() const
Definition: match4pcsBase.h:75
virtual EIGEN_MAKE_ALIGNED_OPERATOR_NEW ~Match4PCSBase()
Definition: match4pcsBase.cc:156
Definition: timer.h:56
typename Point3D::Scalar Scalar
Definition: match4pcsBase.h:69
static constexpr Scalar kLargeNumber
Definition: match4pcsBase.h:80
Definition: logger.h:62