Super4PCS Library  V1.1.2(719f5c0)
intersectionPrimitive.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_INTERSECTION_PRIMITIVES_H_
49 #define _SUPER4PCS_ACCELERATORS_INTERSECTION_PRIMITIVES_H_
50 
51 #ifndef SQR
52 #define SQR(a) ((a)*(a))
53 #endif
54 
55 #include <Eigen/Core>
56 
57 namespace GlobalRegistration{
58 namespace Accelerators{
59 namespace PairExtraction{
60 
61 template <class Point, int _dim, typename Scalar>
63 private:
64  const Point _center;
65  Scalar _radius;
66 
67 
69  struct CustomFloorExpr{
70  inline CustomFloorExpr(Scalar e) : m_e(e) {}
71  inline const Scalar operator()(const Scalar &x) const
72  {
73  return std::round(x/m_e) * m_e;
74  }
75 
76  Scalar m_e;
77  };
78 
79 public:
80  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
81  enum { Dim = _dim};
82 
83  inline HyperSphere(const Point& center, Scalar radius)
84  : _center(center), _radius(radius) { }
85 
87  : _center(other._center), _radius(other._radius) { }
88 
90  inline HyperSphere<Point, _dim, Scalar> quantified ( Scalar eps ) const
91  {
92  CustomFloorExpr expr (eps);
93  return HyperSphere<Point, _dim, Scalar>(_center.unaryExpr(expr),
94  expr(_radius));
95  }
96 
98  inline bool operator<(const HyperSphere<Point, _dim, Scalar>& other) const{
99  if (_radius != other._radius)
100  return _radius < other._radius;
101  for( int i = 0; i < Dim; i++ ) {
102  if (_center[i] == other._center[i]) continue;
103  if (_center[i] < other._center[i]) return true;
104  return false;
105  }
106  return false;
107  }
108 
110  inline operator Point() const { return _center; }
111 
117  inline bool intersect( const Point& nodeCenter, Scalar halfEdgeLength) const
118  {
119  const Point min = nodeCenter.array() - halfEdgeLength;
120  const Point max = nodeCenter.array() + halfEdgeLength;
121  const Point sqmin = (_center.array() - min.array()).square();
122  const Point sqmax = (_center.array() - max.array()).square();
123 
124  // The computation of dmin below is equivalent to:
125  //for( int i = 0; i < Dim; i++ ) {
126  //if( _center[i] < min[i] ) dmin += sqmin[i]; else
127  //if( _center[i] > max[i] ) dmin += sqmax[i];
128  //}
129 
130  Scalar dmin = (_center.array() < min.array())
131  .select(
132  sqmin,
133  (_center.array() > max.array()).select(sqmax,Point::Zero())
134  ).sum();
135 
136  return ( dmin < _radius*_radius &&
137  _radius*_radius < sqmin.cwiseMax(sqmax).sum() );
138  }
139 
149  inline bool intersectFast( const Point& nodeCenter, Scalar halfEdgeLength) const
150  {
151  return SQR((nodeCenter-_center).norm()-halfEdgeLength) <= _radius;
152  }
153 
154  inline bool intersectPoint( const Point& pos, Scalar epsilon ) const
155  {
156  return SQR((pos - _center).norm()-_radius) < SQR(epsilon);
157  }
158 
159  static inline bool intersectPoint( const Point& pos, Scalar epsilon,
160  const Point& center, const Scalar &radius )
161  {
162  return SQR((pos - center).norm()-radius) < SQR(epsilon);
163  }
164 
165  inline const Point& center() const {return _center;}
166  inline const Scalar & radius() const {return _radius;}
167  inline Scalar& radius() { return _radius; }
168 };
169 
170 } // namespace Accelerators
171 } // namespace PairExtraction
172 } // namespace Super4PCS
173 
174 #endif
175 
bool intersectFast(const Point &nodeCenter, Scalar halfEdgeLength) const
intersectFast Fast but inacurate intersection test
Definition: intersectionPrimitive.h:149
bool intersect(const Point &nodeCenter, Scalar halfEdgeLength) const
Definition: intersectionPrimitive.h:117
bool intersectPoint(const Point &pos, Scalar epsilon) const
Definition: intersectionPrimitive.h:154
static bool intersectPoint(const Point &pos, Scalar epsilon, const Point &center, const Scalar &radius)
Definition: intersectionPrimitive.h:159
Definition: bbox.h:54
const Scalar & radius() const
Definition: intersectionPrimitive.h:166
HyperSphere(const HyperSphere< Point, _dim, Scalar > &other)
Definition: intersectionPrimitive.h:86
HyperSphere< Point, _dim, Scalar > quantified(Scalar eps) const
Construct a copy of the instance with a quantified radius and pos.
Definition: intersectionPrimitive.h:90
HyperSphere(const Point &center, Scalar radius)
Definition: intersectionPrimitive.h:83
Scalar & radius()
Definition: intersectionPrimitive.h:167
const Point & center() const
Definition: intersectionPrimitive.h:165