Super4PCS Library  V1.1.2(719f5c0)
shared4pcs.h
1 // Copyright 2012 Dror Aiger
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 // An implementation of the 4-points Congruent Sets (4PCS) algorithm presented
20 // 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 _SHARED_4PCS_H_
45 #define _SHARED_4PCS_H_
46 
47 #include "super4pcs/utils/disablewarnings.h"
48 
49 #include <Eigen/Core>
50 
51 #include <vector>
52 #include <iostream>
53 #include <fstream>
54 #include <array>
55 #include <random>
56 
57 namespace GlobalRegistration {
58 
61 class Point3D {
62  public:
63  using Scalar = float; //_Scalar;
64  using VectorType = Eigen::Matrix<Scalar, 3, 1>;
65 
66  inline Point3D(Scalar x, Scalar y, Scalar z) : pos_({ x, y, z}) {}
67  inline Point3D(const Point3D& other):
68  pos_(other.pos_),
69  normal_(other.normal_),
70  rgb_(other.rgb_) {}
71  template<typename Scalar>
72  explicit inline Point3D(const Eigen::Matrix<Scalar, 3, 1>& other):
73  pos_({ other(0), other(1), other(2) }){
74  }
75 
76  inline Point3D() {}
77  inline VectorType& pos() { return pos_ ; }
78  inline const VectorType& pos() const { return pos_ ; }
79  inline const VectorType& rgb() const { return rgb_; }
80 
81  inline const VectorType& normal() const { return normal_; }
82  inline void set_rgb(const VectorType& rgb) {
83  rgb_ = rgb;
84  }
85  inline void set_normal(const VectorType& normal) {
86  normal_ = normal.normalized();
87  }
88 
89  inline void normalize() {
90  pos_.normalize();
91  }
92  inline bool hasColor() const { return rgb_.squaredNorm() > Scalar(0.001); }
93 
94  Scalar& x() { return pos_.coeffRef(0); }
95  Scalar& y() { return pos_.coeffRef(1); }
96  Scalar& z() { return pos_.coeffRef(2); }
97 
98  Scalar x() const { return pos_.coeff(0); }
99  Scalar y() const { return pos_.coeff(1); }
100  Scalar z() const { return pos_.coeff(2); }
101 
102 
103 
104  private:
106  VectorType pos_{0.0f, 0.0f, 0.0f};
108  VectorType normal_{0.0f, 0.0f, 0.0f};
110  VectorType rgb_{-1.0f, -1.0f, -1.0f};
111 };
112 
113 
114 
117  std::array <int, 4> vertices;
118  inline Quadrilateral(int vertex0, int vertex1, int vertex2, int vertex3) {
119  vertices = { vertex0, vertex1, vertex2, vertex3 };
120  }
121 
122  inline bool operator< (const Quadrilateral& rhs) const {
123  return vertices[0] != rhs[0] ? vertices[0] < rhs[0]
124  : vertices[1] != rhs[1] ? vertices[1] < rhs[1]
125  : vertices[2] != rhs[2] ? vertices[2] < rhs[2]
126  : vertices[3] < rhs[3];
127  }
128 
129  inline bool operator== (const Quadrilateral& rhs) const {
130  return vertices[0] == rhs[0] &&
131  vertices[1] == rhs[1] &&
132  vertices[2] == rhs[2] &&
133  vertices[3] == rhs[3];
134  }
135 
136  int operator[](int idx) const { return vertices[idx]; }
137  int& operator[](int idx) { return vertices[idx]; }
138 };
139 
140 inline std::ofstream& operator<<(std::ofstream& ofs, const Quadrilateral& q){
141  ofs << "[" << q[0] << " " << q[1] << " " << q[2] << " " << q[3] << "]";
142  return ofs;
143 }
144 
145 // ----- 4PCS Options -----
149  using Scalar = typename Point3D::Scalar;
151 
153  Scalar delta = 5.0;
154 
156  Scalar max_normal_difference = -1;
158  Scalar max_translation_distance = -1;
160  Scalar max_angle = -1;
162  Scalar max_color_distance = -1;
165  size_t sample_size = 200;
169  int max_time_seconds = 60;
171  unsigned int randomSeed = std::mt19937::default_seed;
172 
173  inline bool configureOverlap(Scalar overlap_, Scalar terminate_threshold_ = Scalar(1)) {
174  if(terminate_threshold_ < overlap_) return false;
175  overlap_estimation = overlap_;
176  terminate_threshold = terminate_threshold_;
177  return true;
178  }
179  inline Scalar getTerminateThreshold() const { return terminate_threshold; }
180  inline Scalar getOverlapEstimation() const { return overlap_estimation; }
181 
182 private:
185  Scalar terminate_threshold = 1.0;
189  Scalar overlap_estimation = 0.2;
190 };
191 
192 }
193 
194 
195 
196 #endif //_SHARED_4PCS_H_
const VectorType & pos() const
Definition: shared4pcs.h:78
Point3D(const Eigen::Matrix< Scalar, 3, 1 > &other)
Definition: shared4pcs.h:72
typename Point3D::Scalar Scalar
Definition: shared4pcs.h:149
Match4PCSOptions()
Definition: shared4pcs.h:150
void normalize()
Definition: shared4pcs.h:89
Scalar y() const
Definition: shared4pcs.h:99
void set_normal(const VectorType &normal)
Definition: shared4pcs.h:85
int & operator[](int idx)
Definition: shared4pcs.h:137
Point3D()
Definition: shared4pcs.h:76
Scalar getOverlapEstimation() const
Definition: shared4pcs.h:180
Scalar & z()
Definition: shared4pcs.h:96
Definition: bbox.h:54
Point3D(const Point3D &other)
Definition: shared4pcs.h:67
The basic 3D point structure. A point potentially contains also directional information and color...
Definition: shared4pcs.h:61
int operator[](int idx) const
Definition: shared4pcs.h:136
const VectorType & rgb() const
Definition: shared4pcs.h:79
Eigen::Matrix< Scalar, 3, 1 > VectorType
Definition: shared4pcs.h:64
Scalar getTerminateThreshold() const
Definition: shared4pcs.h:179
bool hasColor() const
Definition: shared4pcs.h:92
Scalar z() const
Definition: shared4pcs.h:100
delta and overlap_estimation are the application parameters. All other parameters are more likely to ...
Definition: shared4pcs.h:148
void set_rgb(const VectorType &rgb)
Definition: shared4pcs.h:82
std::ofstream & operator<<(std::ofstream &ofs, const Quadrilateral &q)
Definition: shared4pcs.h:140
std::array< int, 4 > vertices
Definition: shared4pcs.h:117
float Scalar
Definition: shared4pcs.h:63
VectorType & pos()
Definition: shared4pcs.h:77
Scalar & y()
Definition: shared4pcs.h:95
Holds a base from P. The base contains 4 points (indices) from the set P.
Definition: shared4pcs.h:116
const VectorType & normal() const
Definition: shared4pcs.h:81
Quadrilateral(int vertex0, int vertex1, int vertex2, int vertex3)
Definition: shared4pcs.h:118
Scalar x() const
Definition: shared4pcs.h:98
bool configureOverlap(Scalar overlap_, Scalar terminate_threshold_=Scalar(1))
Definition: shared4pcs.h:173
Scalar & x()
Definition: shared4pcs.h:94
Point3D(Scalar x, Scalar y, Scalar z)
Definition: shared4pcs.h:66