Super4PCS Library  V1.1.2(719f5c0)
pairCreationFunctor.h
1 #ifndef _SUPER4PCS_ALGO_PAIRCREATIONFUNCTOR_H
2 #define _SUPER4PCS_ALGO_PAIRCREATIONFUNCTOR_H
3 
4 #include <iostream>
5 #include <vector>
6 #include "super4pcs/shared4pcs.h"
7 
8 #include "super4pcs/accelerators/bbox.h"
9 
10 #include "super4pcs/accelerators/pairExtraction/bruteForceFunctor.h"
11 #include "super4pcs/accelerators/pairExtraction/intersectionFunctor.h"
12 #include "super4pcs/accelerators/pairExtraction/intersectionPrimitive.h"
13 
14 namespace GlobalRegistration {
15 
16 template <typename _Scalar>
18 
19 public:
20  using Scalar = _Scalar;
21  using PairsVector = std::vector<std::pair<int, int>>;
22  using VectorType = typename Point3D::VectorType;
23 
24  // Processing data
27  double pair_distance;
29 
30  // Shared data
32  const std::vector<Point3D>& Q_;
33 
35 
36  std::vector<unsigned int> ids;
37 
38 
39  // Internal data
40  typedef Eigen::Matrix<Scalar, 3, 1> Point;
43 
44  std::vector< /*Eigen::Map<*/typename PairCreationFunctor::Point/*>*/ > points;
45  std::vector< Primitive > primitives;
46 
47 private:
48  VectorType segment1;
49  std::vector<Point3D> base_3D_;
50  int base_point1_, base_point2_;
51 
52  typename PairCreationFunctor::Point _gcenter;
53  Scalar _ratio;
54  static const typename PairCreationFunctor::Point half;
55 
56 public:
58  Match4PCSOptions options,
59  const std::vector<Point3D>& Q)
60  :options_(options), Q_(Q),
61  pairs(NULL), _ratio(1.f)
62  { }
63 
64 private:
65  inline Point worldToUnit(
66  const Eigen::MatrixBase<typename PairCreationFunctor::Point> &p) const {
67  static const Point half = Point::Ones() * Scalar(0.5f);
68  return (p-_gcenter) / _ratio + half;
69  }
70 
71 
72 public:
73  inline Point unitToWorld(
74  const Eigen::MatrixBase<typename PairCreationFunctor::Point> &p) const {
75  static const Point half = Point::Ones() * Scalar(0.5f);
76  return (p - half) * _ratio + _gcenter;
77  }
78 
79 
80  inline Scalar unitToWorld( Scalar d) const {
81  return d * _ratio;
82  }
83 
84 
85  inline Point getPointInWorldCoord(int i) const {
86  return unitToWorld(points[i]);
87  }
88 
89 
90  inline void synch3DContent(){
91  points.clear();
92  primitives.clear();
93 
95 
96  unsigned int nSamples = Q_.size();
97 
98  points.reserve(nSamples);
99  primitives.reserve(nSamples);
100 
101  // Compute bounding box on fine data to be SURE to have all points in the
102  // unit bounding box
103  for (unsigned int i = 0; i < nSamples; ++i) {
104  const VectorType &q = Q_[i].pos();
105  points.push_back(q);
106  bbox.extend(q);
107  }
108 
109  _gcenter = bbox.center();
110  // add a delta to avoid to have elements with coordinate = 1
111  _ratio = bbox.diagonal().maxCoeff() + 0.001;
112 
113  // update point cloud (worldToUnit use the ratio and gravity center
114  // previously computed)
115  // Generate primitives
116  for (unsigned int i = 0; i < nSamples; ++i) {
117  points[i] = worldToUnit(points[i]);
118 
119  primitives.emplace_back(points[i], Scalar(1.));
120  ids.push_back(i);
121  }
122  }
123 
124  inline void setRadius(Scalar radius) {
125  const Scalar nRadius = radius/_ratio;
126  for(typename std::vector< Primitive >::iterator it = primitives.begin();
127  it != primitives.end(); ++it)
128  (*it).radius() = nRadius;
129  }
130 
132  return eps/_ratio;
133  }
134 
135  inline void setBase( int base_point1, int base_point2,
136  const std::vector<Point3D>& base_3D){
137  base_3D_ = base_3D;
138  base_point1_ = base_point1;
139  base_point2_ = base_point2;
140 
141  segment1 = (base_3D_[base_point2_].pos() -
142  base_3D_[base_point1_].pos()).normalized();
143  }
144 
145 
146  inline void beginPrimitiveCollect(int /*primId*/){ }
147  inline void endPrimitiveCollect(int /*primId*/){ }
148 
149 
151  inline void process(int i, int j){
152  if (i>j){
153  const Point3D& p = Q_[j];
154  const Point3D& q = Q_[i];
155 
156  // Compute the distance and two normal angles to ensure working with
157  // wrong orientation. We want to verify that the angle between the
158  // normals is close to the angle between normals in the base. This can be
159  // checked independent of the full rotation angles which are not yet
160  // defined by segment matching alone..
161  const Scalar distance = (q.pos() - p.pos()).norm();
162 #ifndef MULTISCALE
163  if (std::abs(distance - pair_distance) > pair_distance_epsilon) return;
164 #endif
165 
166  if ( options_.max_normal_difference > 0 &&
167  q.normal().squaredNorm() > 0 &&
168  p.normal().squaredNorm() > 0) {
169  const Scalar norm_threshold =
170  0.5 * options_.max_normal_difference * M_PI / 180.0;
171  const double first_normal_angle = (q.normal() - p.normal()).norm();
172  const double second_normal_angle = (q.normal() + p.normal()).norm();
173  // Take the smaller normal distance.
174  const Scalar first_norm_distance =
175  std::min(std::abs(first_normal_angle - pair_normals_angle),
176  std::abs(second_normal_angle - pair_normals_angle));
177  // Verify appropriate angle between normals and distance.
178 
179  if (first_norm_distance > norm_threshold) return;
180  }
181  // Verify restriction on the rotation angle, translation and colors.
182  if (options_.max_color_distance > 0) {
183  const bool use_rgb = (p.rgb()[0] >= 0 && q.rgb()[0] >= 0 &&
184  base_3D_[base_point1_].rgb()[0] >= 0 &&
185  base_3D_[base_point2_].rgb()[0] >= 0);
186  bool color_good = (p.rgb() - base_3D_[base_point1_].rgb()).norm() <
187  options_.max_color_distance &&
188  (q.rgb() - base_3D_[base_point2_].rgb()).norm() <
189  options_.max_color_distance;
190 
191  if (use_rgb && ! color_good) return;
192  }
193 
194  if (options_.max_translation_distance > 0) {
195  const bool dist_good = (p.pos() - base_3D_[base_point1_].pos()).norm() <
196  options_.max_translation_distance &&
197  (q.pos() - base_3D_[base_point2_].pos()).norm() <
198  options_.max_translation_distance;
199  if (! dist_good) return;
200  }
201 
202  // need cleaning here
203  if (options_.max_angle > 0){
204  VectorType segment2 = (q.pos() - p.pos()).normalized();
205  if (std::acos(segment1.dot(segment2)) <= options_.max_angle * M_PI / 180.0) {
206  pairs->emplace_back(j, i);
207  }
208 
209  if (std::acos(segment1.dot(- segment2)) <= options_.max_angle * M_PI / 180.0) {
210  // Add ordered pair.
211  pairs->emplace_back(i, j);
212  }
213  }else {
214  pairs->emplace_back(j, i);
215  pairs->emplace_back(i, j);
216  }
217  }
218  }
219 };
220 
221 } // namespace Super4PCS
222 
223 #endif // PAIRCREATIONFUNCTOR_H
Eigen::Matrix< Scalar, 3, 1 > Point
Definition: pairCreationFunctor.h:40
double pair_normals_angle
Definition: pairCreationFunctor.h:26
Scalar max_color_distance
Maximum color RGB distance between corresponding vertices. Set negative to ignore.
Definition: shared4pcs.h:162
Point unitToWorld(const Eigen::MatrixBase< typename PairCreationFunctor::Point > &p) const
Definition: pairCreationFunctor.h:73
Scalar max_normal_difference
Maximum normal difference.
Definition: shared4pcs.h:156
std::vector< Primitive > primitives
Definition: pairCreationFunctor.h:45
void setRadius(Scalar radius)
Definition: pairCreationFunctor.h:124
void extend(InputIt first, InputIt last)
Definition: bbox.h:75
Scalar getNormalizedEpsilon(Scalar eps)
Definition: pairCreationFunctor.h:131
Definition: bbox.h:54
void synch3DContent()
Definition: pairCreationFunctor.h:90
Accelerators::PairExtraction::HyperSphere< typename PairCreationFunctor::Point, 3, Scalar > Primitive
Definition: pairCreationFunctor.h:42
const std::vector< Point3D > & Q_
Definition: pairCreationFunctor.h:32
The basic 3D point structure. A point potentially contains also directional information and color...
Definition: shared4pcs.h:61
const VectorType & rgb() const
Definition: shared4pcs.h:79
PairCreationFunctor(Match4PCSOptions options, const std::vector< Point3D > &Q)
Definition: pairCreationFunctor.h:57
void setBase(int base_point1, int base_point2, const std::vector< Point3D > &base_3D)
Definition: pairCreationFunctor.h:135
Eigen::Matrix< Scalar, 3, 1 > VectorType
Definition: shared4pcs.h:64
Scalar Scalar
Definition: pairCreationFunctor.h:20
std::vector< typename PairCreationFunctor::Point > points
Definition: pairCreationFunctor.h:44
PairsVector * pairs
Definition: pairCreationFunctor.h:34
std::vector< unsigned int > ids
Definition: pairCreationFunctor.h:36
double pair_distance_epsilon
Definition: pairCreationFunctor.h:28
Definition: pairCreationFunctor.h:17
Match4PCSOptions options_
Definition: pairCreationFunctor.h:31
Scalar max_angle
Maximum rotation angle. Set negative to ignore.
Definition: shared4pcs.h:160
Scalar max_translation_distance
Maximum translation distance. Set negative to ignore.
Definition: shared4pcs.h:158
void beginPrimitiveCollect(int)
Definition: pairCreationFunctor.h:146
Scalar norm_threshold
Definition: pairCreationFunctor.h:25
delta and overlap_estimation are the application parameters. All other parameters are more likely to ...
Definition: shared4pcs.h:148
Definition: bbox.h:57
Scalar unitToWorld(Scalar d) const
Definition: pairCreationFunctor.h:80
Point getPointInWorldCoord(int i) const
Definition: pairCreationFunctor.h:85
VectorType & pos()
Definition: shared4pcs.h:77
void endPrimitiveCollect(int)
Definition: pairCreationFunctor.h:147
const VectorType & normal() const
Definition: shared4pcs.h:81
double pair_distance
Definition: pairCreationFunctor.h:27
void process(int i, int j)
FIXME Pair filtering is the same than 4pcs. Need refactoring.
Definition: pairCreationFunctor.h:151
typename Point3D::VectorType VectorType
Definition: pairCreationFunctor.h:22
std::vector< std::pair< int, int > > PairsVector
Definition: pairCreationFunctor.h:21