Super4PCS Library  V1.1.2(719f5c0)
utils.h
1 // Copyright 2014 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: Nicolas Mellado
18 //
19 // An implementation of the Super 4-points Congruent Sets (Super 4PCS)
20 // algorithm presented in:
21 //
22 // Super 4PCS: Fast Global Pointcloud Registration via Smart Indexing
23 // Nicolas Mellado, Dror Aiger, Niloy J. Mitra
24 // Symposium on Geometry Processing 2014.
25 //
26 // Data acquisition in large-scale scenes regularly involves accumulating
27 // information across multiple scans. A common approach is to locally align scan
28 // pairs using Iterative Closest Point (ICP) algorithm (or its variants), but
29 // requires static scenes and small motion between scan pairs. This prevents
30 // accumulating data across multiple scan sessions and/or different acquisition
31 // modalities (e.g., stereo, depth scans). Alternatively, one can use a global
32 // registration algorithm allowing scans to be in arbitrary initial poses. The
33 // state-of-the-art global registration algorithm, 4PCS, however has a quadratic
34 // time complexity in the number of data points. This vastly limits its
35 // applicability to acquisition of large environments. We present Super 4PCS for
36 // global pointcloud registration that is optimal, i.e., runs in linear time (in
37 // the number of data points) and is also output sensitive in the complexity of
38 // the alignment problem based on the (unknown) overlap across scan pairs.
39 // Technically, we map the algorithm as an 'instance problem' and solve it
40 // efficiently using a smart indexing data organization. The algorithm is
41 // simple, memory-efficient, and fast. We demonstrate that Super 4PCS results in
42 // significant speedup over alternative approaches and allows unstructured
43 // efficient acquisition of scenes at scales previously not possible. Complete
44 // source code and datasets are available for research use at
45 // http://geometry.cs.ucl.ac.uk/projects/2014/super4PCS/.
46 
47 
48 #ifndef _SUPER4PCS_ACCELERATORS_UTILS_H_
49 #define _SUPER4PCS_ACCELERATORS_UTILS_H_
50 
51 
52 #ifndef M_PI
53 #define M_PI 3.14159265358979323846
54 #endif
55 
56 
57 namespace GlobalRegistration{
58 namespace Utils{
59 
61 template<typename baseT, typename expoT>
62 constexpr baseT POW(baseT base, expoT expo)
63 {
64  return (expo != 0 )? base * POW(base, expo -1) : 1;
65 }
66 
67 
68 namespace internal{
69 
78 template <bool enable>
84  template <class IndexT, class SizeT>
85  static inline
86  constexpr IndexT validate(const IndexT& n,
87  const SizeT& gsize);
88 
92  template <class IndexT, class SizeT>
93  static inline
94  constexpr bool _test(const IndexT& n, const SizeT& gsize){
95  return n < gsize;
96  }
97 };
98 
99 template <>
100 template <class IndexT, class SizeT>
101 constexpr IndexT
103  const SizeT& gsize)
104 {
105  return IndexValidator<true>::_test(n, gsize) ?
106  n :
107  throw std::out_of_range(
108  std::string("[IndexValidator] ") +
109  std::to_string(n) +
110  std::string(" bigger than ") +
111  std::to_string(gsize) );
112 }
113 
114 template <>
115 template <class IndexT, class SizeT>
116 constexpr IndexT
118  const SizeT& /*gsize*/)
119 {
120  return n;
121 }
122 } // namespace GlobalRegistration::Utils::internal
123 
139 template<bool validate, class ndIndexT, class IndexT, class SizeT>
140 constexpr inline IndexT
141 UnrollIndexLoop(const ndIndexT& coord,
142  IndexT cdim,
143  SizeT gsize){
144  return (cdim != 0)
145  ? ( internal::IndexValidator<validate>::validate(IndexT(coord[cdim]), gsize)*POW(gsize, cdim) +
146  UnrollIndexLoop<validate>(coord, cdim-1, gsize) )
147  : internal::IndexValidator<validate>::validate(IndexT(coord[cdim]), gsize);
148 }
149 
150 
163 template<bool validate, class ndIndexT, class IndexT, class SizeT>
164 constexpr inline IndexT
165 UnrollIndexLoop(const ndIndexT& coord,
166  const ndIndexT& offset,
167  IndexT cdim,
168  SizeT gsize){
169  return (cdim != 0)
170  ? ( internal::IndexValidator<validate>::validate(IndexT(offset[cdim]+std::floor(coord[cdim])), gsize)*POW(gsize, cdim) +
171  UnrollIndexLoop<validate>(coord, offset, cdim-1, gsize) )
172  : internal::IndexValidator<validate>::validate(IndexT(offset[cdim]+std::floor(coord[cdim])), gsize);
173 }
174 
175 } //namespace GlobalRegistration::Utils
176 } //namespace Super4PCS
177 
178 
179 #endif
Helper structure used to (conditionnaly) validate indices.
Definition: utils.h:79
Definition: bbox.h:54
constexpr baseT POW(baseT base, expoT expo)
Compile time pow.
Definition: utils.h:62
static constexpr bool _test(const IndexT &n, const SizeT &gsize)
Test used internally to validate the input index.
Definition: utils.h:94
static constexpr IndexT validate(const IndexT &n, const SizeT &gsize)
Check if n is within [0:gsize] if enable=true.
constexpr IndexT UnrollIndexLoop(const ndIndexT &coord, IndexT cdim, SizeT gsize)
Convert a normalized n-d vector to a linear index in a uniform regular grid This function is recursiv...
Definition: utils.h:141