Super4PCS Library  V1.1.2(719f5c0)
normalset.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_INDEXED_NORMAL_SET_H_
49 #define _SUPER4PCS_ACCELERATORS_INDEXED_NORMAL_SET_H_
50 
51 #include "super4pcs/utils/disablewarnings.h"
52 #include "super4pcs/accelerators/utils.h"
53 
54 namespace GlobalRegistration{
55 
65 template <
66  class Point,
67  int dim,
68  int _ngSize,
69  typename _Scalar
70  >
72  typedef std::array< std::vector<unsigned int>,
73  Utils::POW(_ngSize, dim)> AngularGrid;
74 
76  using Scalar = _Scalar;
77 
78 #ifdef DEBUG
79 #define VALIDATE_INDICES true
80 #pragma message "Index validation is enabled in debug mode"
81 #else
82 #define VALIDATE_INDICES false
83 #endif
84 
85 private:
86  static constexpr Scalar _nepsilon = Scalar(1.)/Scalar(_ngSize) + 0.00001;
87  std::vector<AngularGrid*> _grid;
88  Scalar _epsilon;
89  int _egSize;
90 
92  inline int indexPos ( const Point& p) const;
94  inline int indexNormal( const Point& n) const;
95 
97  inline Point coordinatesPos ( const Point& p) const
98  { return p/_epsilon; }
100  inline Point coordinatesNormal( const Point& n) const
101  {
102  static const Point half = Point::Ones()/Scalar(2.);
103  return (n/Scalar(2.) + half)/_nepsilon;
104  }
105 
107  inline int indexCoordinatesPos ( const Point& pCoord) const;
109  inline int indexCoordinatesNormal( const Point& nCoord) const;
110 
111  //inline Point indexToPos (int id) const;
112 
113 public:
114  inline IndexedNormalSet(const Scalar epsilon)
115  : _epsilon(epsilon) {
117  const int gridDepth = -std::log2(epsilon);
118  _egSize = std::pow(2,gridDepth);
119  _epsilon = 1.f/_egSize;
120 
121  _grid = std::vector<AngularGrid*> (std::pow(_egSize, dim), NULL);
122  }
123 
124  virtual inline ~IndexedNormalSet();
125 
127  inline bool addElement(const Point& pos,
128  const Point& normal,
129  unsigned int id);
130 
132  inline AngularGrid* angularGrid(const Point& p) {
133  const int pId = indexPos(p);
134  if (pId == -1) return NULL;
135  return _grid[pId];
136  }
137 
139  inline void getNeighbors( const Point& p,
140  std::vector<unsigned int>&nei);
142  inline void getNeighbors( const Point& p,
143  const Point& n,
144  std::vector<unsigned int>&nei);
146  inline void getNeighbors( const Point& p,
147  const Point& n,
148  Scalar alpha,
149  std::vector<unsigned int>&nei,
150  bool tryReverse = false);
151 };
152 
153 } // namespace Super4PCS
154 
155 #include "super4pcs/accelerators/normalset.hpp"
156 
157 #endif // _INDEXED_NORMAL_SET_H_
IndexedNormalSet(const Scalar epsilon)
Definition: normalset.h:114
Normal set indexed by a position in euclidean space.
Definition: normalset.h:71
virtual ~IndexedNormalSet()
Definition: normalset.hpp:62
MOVE_DIR
Definition: normalset.h:75
bool addElement(const Point &pos, const Point &normal, unsigned int id)
Add a new couple pos/normal, and its associated id.
Definition: normalset.hpp:116
Definition: bbox.h:54
constexpr baseT POW(baseT base, expoT expo)
Compile time pow.
Definition: utils.h:62
std::array< std::vector< unsigned int >, Utils::POW(_ngSize, dim)> AngularGrid
Definition: normalset.h:73
_Scalar Scalar
Definition: normalset.h:76
void getNeighbors(const Point &p, std::vector< unsigned int > &nei)
Get closest points in euclidean space.
Definition: normalset.hpp:136
AngularGrid * angularGrid(const Point &p)
Definition: normalset.h:132