congruentSetExplorationBase.h
Go to the documentation of this file.
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 _OPENGR_ALGO_CSE_
45 #define _OPENGR_ALGO_CSE_
46 
47 #include <vector>
48 
49 #ifdef OpenGR_USE_OPENMP
50 #include <omp.h>
51 #endif
52 
53 #include "gr/utils/shared.h"
54 #include "gr/algorithms/matchBase.h"
55 #include "gr/utils/registrationMetrics.h"
56 
57 #ifdef TEST_GLOBAL_TIMINGS
58 # include "gr/utils/timer.h"
59 #endif
60 
61 namespace gr{
62 
63 
64 template < class Derived, class TBase>
65 class CongruentSetExplorationOptions : public TBase
66 {
67 public:
68  using Scalar = typename TBase::Scalar;
69 
70  inline bool configureOverlap(Scalar overlap_, Scalar terminate_threshold_ = Scalar(1)) {
71  if(terminate_threshold_ < overlap_) return false;
72  overlap_estimation = overlap_;
73  terminate_threshold = terminate_threshold_;
74  return true;
75  }
76  inline Scalar getTerminateThreshold() const { return terminate_threshold; }
77  inline Scalar getOverlapEstimation() const { return overlap_estimation; }
78 private:
79  /// Threshold on the value of the target function (LCP, see the paper).
80  /// It is used to terminate the process once we reached this value.
81  Scalar terminate_threshold = 1.0;
82  /// Estimated overlap between P and Q. This is the fraction of points in P that
83  /// may have corresponding point in Q. It's being used to estimate the number
84  /// of RANSAC iterations needed to guarantee small failure probability.
85  Scalar overlap_estimation = 0.2;
86 };
87 
88 
89 /// \brief Base class for Congruent Sec Exploration algorithms
90 /// \tparam _Traits Defines properties of the Base used to build the congruent set.
91 template <typename _Traits,
92  typename _PointType,
93  typename _TransformVisitor,
94  typename _PairFilteringFunctor, /// <\brief Must implements PairFilterConcept
95  template < class, class > class ... OptExts >
97 
98 public:
99  using Traits = _Traits;
100  using TransformVisitor = _TransformVisitor;
101  using CongruentBaseType = typename Traits::Base;
102  using Set = typename Traits::Set;
103  using Coordinates = typename Traits::Coordinates;
104  using PairFilteringFunctor = _PairFilteringFunctor;
105 
109 
110  using PairsVector = std::vector< std::pair<int, int> >;
111  using Scalar = typename MatchBaseType::Scalar;
114  static constexpr Scalar kLargeNumber = 1e9;
115  static constexpr Scalar distance_factor = 2.0;
116 
117  using LogLevel = typename MatchBaseType::LogLevel;
118 
119 #ifdef OPENGR_USE_WEIGHTED_LCP
121 #else
123 
124 #endif
125 
126  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
127 
128 
129  CongruentSetExplorationBase(const OptionsType& options
130  , const Utils::Logger &logger
131  );
132 
133  virtual ~CongruentSetExplorationBase();
134 
135  /// Computes an approximation of the best LCP (directional) from Q to P
136  /// and the rigid transformation that realizes it. The input sets may or may
137  /// not contain normal information for any point.
138  /// @param [in] P The first input set.
139  /// @param [in] Q The second input set.
140  /// @param [out] transformation Rigid transformation matrix (4x4) that brings
141  /// Q to the (approximate) optimal LCP. Initial value is considered as a guess
142  /// @return the computed LCP measure as a fraction of the size of P ([0..1]).
143  template <typename InputRange1,
144  typename InputRange2,
145  template<typename> class Sampler>
147  const InputRange2& Q,
149  const Sampler<_PointType>& sampler,
151 
152  /// Tries to compute an inital base from P
153  /// @param [out] base The base, if found. Initial value is not used. Modified as
154  /// the computed base if the return value is true.
155  /// @return true if a base is found an initialized, false otherwise
156  virtual bool initBase (CongruentBaseType &base) = 0;
157 
158 protected:
159  /// Maximum base diameter. It is computed automatically from the diameter of
160  /// P and the estimated overlap and used to limit the distance between the
161  /// points in the base in P so that the probability to have all points in
162  /// the base as inliers is increased.
164  /// Number of trials. Every trial picks random base from P.
166  /// The points in the base (indices to P). It is being updated in every
167  /// RANSAC iteration.
168  CongruentBaseType base_;
169  /// The current congruent 4 points from Q. Every RANSAC iteration the
170  /// algorithm examines a set of such congruent 4-points from Q and retains
171  /// the best from them (the one that realizes the best LCP).
172  CongruentBaseType current_congruent_;
173  /// The 3D points of the base.
174  Coordinates base_3D_;
175  /// The best LCP (Largest Common Point) fraction so far.
177  /// Current trial.
179 
180 #ifdef OpenGR_USE_OPENMP
181  /// number of threads used to verify the congruent set
182  const int omp_nthread_congruent_;
183 #endif
184 
185 #ifdef TEST_GLOBAL_TIMINGS
186 
187  mutable Scalar totalTime;
188  mutable Scalar kdTreeTime;
189  mutable Scalar verifyTime;
190 
191  using Timer = gr::Utils::Timer;
192 
193 #endif
194 
195 protected :
196  /// Performs n RANSAC iterations, each one of them containing base selection,
197  /// finding congruent sets and verification. Returns true if the process can be
198  /// terminated (the target LCP was obtained or the maximum number of trials has
199  /// been reached), false otherwise.
200  bool Perform_N_steps(int n,
201  Eigen::Ref<MatrixType> transformation,
202  TransformVisitor& v);
203  /// Tries one base and finds the best transformation for this base.
204  /// Returns true if the achieved LCP is greater than terminate_threshold_,
205  /// else otherwise.
206  bool TryOneBase(TransformVisitor &v);
207 
208  /// Loop over the set of congruent 4-points and test the compatibility with the
209  /// input base.
210  /// \param [out] Nb Number of quads corresponding to valid configurations
211  bool TryCongruentSet(CongruentBaseType& base, Set& set, TransformVisitor &v,size_t &nbCongruent);
212 
213  const CongruentBaseType& base3D() const { return base_3D_; }
214 
215  /// Find all the congruent set similar to the base in the second 3D model (Q).
216  /// It could be with a 3 point base or a 4 point base.
217  /// \param base use to find the similar points congruent in Q.
218  /// \param congruent_set a set of all point congruent found in Q.
219  virtual bool generateCongruents (CongruentBaseType& base,Set& congruent_set) = 0;
220 
221  /// For each randomly picked base, verifies the computed transformation by
222  /// computing the number of points that this transformation brings near points
223  /// in Q. Returns the current LCP. R is the rotation matrix, (tx,ty,tz) is
224  /// the translation vector and (cx,cy,cz) is the center of transformation.template <class MatrixDerived>
225  Scalar Verify(const Eigen::Ref<const MatrixType> & mat) const;
226 
227 }; /// class MatchBaseType
228 } /// namespace gr
230 
231 #endif // _OPENGR_ALGO_CSE_
virtual bool generateCongruents(CongruentBaseType &base, Set &congruent_set)=0
Find all the congruent set similar to the base in the second 3D model (Q). It could be with a 3 point...
Scalar ComputeTransformation(const InputRange1 &P, const InputRange2 &Q, Eigen::Ref< MatrixType > transformation, const Sampler< _PointType > &sampler, TransformVisitor &v)
Computes an approximation of the best LCP (directional) from Q to P and the rigid transformation that...
int number_of_trials_
Number of trials. Every trial picks random base from P.
Definition: congruentSetExplorationBase.h:165
int current_trial_
Current trial.
Definition: congruentSetExplorationBase.h:178
Scalar best_LCP_
The best LCP (Largest Common Point) fraction so far.
Definition: congruentSetExplorationBase.h:176
Scalar Verify(const Eigen::Ref< const MatrixType > &mat) const
For each randomly picked base, verifies the computed transformation by computing the number of points...
Definition: congruentSetExplorationBase.hpp:378
bool configureOverlap(Scalar overlap_, Scalar terminate_threshold_=Scalar(1))
Definition: congruentSetExplorationBase.h:70
Definition: congruentSetExplorationBase.h:65
Scalar getOverlapEstimation() const
Definition: congruentSetExplorationBase.h:77
bool Perform_N_steps(int n, Eigen::Ref< MatrixType > transformation, TransformVisitor &v)
Performs n RANSAC iterations, each one of them containing base selection, finding congruent sets and ...
Definition: congruentSetExplorationBase.hpp:130
virtual bool initBase(CongruentBaseType &base)=0
Tries to compute an inital base from P.
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
CongruentBaseType base_
The points in the base (indices to P). It is being updated in every RANSAC iteration.
Definition: congruentSetExplorationBase.h:168
bool TryOneBase(TransformVisitor &v)
Tries one base and finds the best transformation for this base. Returns true if the achieved LCP is g...
Definition: congruentSetExplorationBase.hpp:195
virtual ~CongruentSetExplorationBase()
Definition: congruentSetExplorationBase.hpp:51
Scalar getTerminateThreshold() const
Definition: congruentSetExplorationBase.h:76
void get(int queryId, int nElPerDim, int, typename NeighborhoodType< 3 >::ptr first, typename NeighborhoodType< 3 >::ptr)
Definition: utils.h:279
const CongruentBaseType & base3D() const
Definition: congruentSetExplorationBase.h:213
EIGEN_MAKE_ALIGNED_OPERATOR_NEW CongruentSetExplorationBase(const OptionsType &options, const Utils::Logger &logger)
Definition: congruentSetExplorationBase.hpp:36
bool TryCongruentSet(CongruentBaseType &base, Set &set, TransformVisitor &v, size_t &nbCongruent)
Loop over the set of congruent 4-points and test the compatibility with the input base...
Definition: congruentSetExplorationBase.hpp:215
Definition: logger.h:62
CongruentBaseType current_congruent_
The current congruent 4 points from Q. Every RANSAC iteration the algorithm examines a set of such co...
Definition: congruentSetExplorationBase.h:172
Scalar max_base_diameter_
Maximum base diameter. It is computed automatically from the diameter of P and the estimated overlap ...
Definition: congruentSetExplorationBase.h:163
Coordinates base_3D_
The 3D points of the base.
Definition: congruentSetExplorationBase.h:174