Point Cloud Library (PCL)  1.11.1-dev
ppf_registration.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, Alexandru-Eugen Ichim
5  * Willow Garage, Inc
6  * Copyright (c) 2012-, Open Perception, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of the copyright holder(s) nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * $Id$
38  *
39  */
40 
41 #pragma once
42 
43 #include <pcl/features/ppf.h>
44 #include <pcl/registration/registration.h>
45 
46 #include <unordered_map>
47 
48 namespace pcl {
50 public:
51  /** \brief Data structure to hold the information for the key in the feature hash map
52  * of the PPFHashMapSearch class \note It uses multiple pair levels in order to enable
53  * the usage of the boost::hash function which has the std::pair implementation (i.e.,
54  * does not require a custom hash function)
55  */
56  struct HashKeyStruct : public std::pair<int, std::pair<int, std::pair<int, int>>> {
57  HashKeyStruct() = default;
58 
59  HashKeyStruct(int a, int b, int c, int d)
60  {
61  this->first = a;
62  this->second.first = b;
63  this->second.second.first = c;
64  this->second.second.second = d;
65  }
66 
67  std::size_t
68  operator()(const HashKeyStruct& s) const noexcept
69  {
70  const std::size_t h1 = std::hash<int>{}(s.first);
71  const std::size_t h2 = std::hash<int>{}(s.second.first);
72  const std::size_t h3 = std::hash<int>{}(s.second.second.first);
73  const std::size_t h4 = std::hash<int>{}(s.second.second.second);
74  return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3);
75  }
76  };
77  using FeatureHashMapType =
78  std::unordered_multimap<HashKeyStruct,
79  std::pair<std::size_t, std::size_t>,
81  using FeatureHashMapTypePtr = shared_ptr<FeatureHashMapType>;
82  using Ptr = shared_ptr<PPFHashMapSearch>;
83  using ConstPtr = shared_ptr<const PPFHashMapSearch>;
84 
85  /** \brief Constructor for the PPFHashMapSearch class which sets the two step
86  * parameters for the enclosed data structure \param angle_discretization_step the
87  * step value between each bin of the hash map for the angular values \param
88  * distance_discretization_step the step value between each bin of the hash map for
89  * the distance values
90  */
91  PPFHashMapSearch(float angle_discretization_step = 12.0f / 180.0f *
92  static_cast<float>(M_PI),
93  float distance_discretization_step = 0.01f)
94  : feature_hash_map_(new FeatureHashMapType)
95  , internals_initialized_(false)
96  , angle_discretization_step_(angle_discretization_step)
97  , distance_discretization_step_(distance_discretization_step)
98  , max_dist_(-1.0f)
99  {}
100 
101  /** \brief Method that sets the feature cloud to be inserted in the hash map
102  * \param feature_cloud a const smart pointer to the PPFSignature feature cloud
103  */
104  void
105  setInputFeatureCloud(PointCloud<PPFSignature>::ConstPtr feature_cloud);
106 
107  /** \brief Function for finding the nearest neighbors for the given feature inside the
108  * discretized hash map \param f1 The 1st value describing the query PPFSignature
109  * feature \param f2 The 2nd value describing the query PPFSignature feature \param f3
110  * The 3rd value describing the query PPFSignature feature \param f4 The 4th value
111  * describing the query PPFSignature feature \param indices a vector of pair indices
112  * representing the feature pairs that have been found in the bin corresponding to the
113  * query feature
114  */
115  void
116  nearestNeighborSearch(float& f1,
117  float& f2,
118  float& f3,
119  float& f4,
120  std::vector<std::pair<std::size_t, std::size_t>>& indices);
121 
122  /** \brief Convenience method for returning a copy of the class instance as a
123  * shared_ptr */
124  Ptr
126  {
127  return Ptr(new PPFHashMapSearch(*this));
128  }
129 
130  /** \brief Returns the angle discretization step parameter (the step value between
131  * each bin of the hash map for the angular values) */
132  inline float
134  {
135  return angle_discretization_step_;
136  }
137 
138  /** \brief Returns the distance discretization step parameter (the step value between
139  * each bin of the hash map for the distance values) */
140  inline float
142  {
143  return distance_discretization_step_;
144  }
145 
146  /** \brief Returns the maximum distance found between any feature pair in the given
147  * input feature cloud */
148  inline float
150  {
151  return max_dist_;
152  }
153 
154  std::vector<std::vector<float>> alpha_m_;
155 
156 private:
157  FeatureHashMapTypePtr feature_hash_map_;
158  bool internals_initialized_;
159 
160  float angle_discretization_step_, distance_discretization_step_;
161  float max_dist_;
162 };
163 
164 /** \brief Class that registers two point clouds based on their sets of PPFSignatures.
165  * Please refer to the following publication for more details:
166  * B. Drost, M. Ulrich, N. Navab, S. Ilic
167  * Model Globally, Match Locally: Efficient and Robust 3D Object Recognition
168  * 2010 IEEE Conference on Computer Vision and Pattern Recognition (CVPR)
169  * 13-18 June 2010, San Francisco, CA
170  *
171  * \note This class works in tandem with the PPFEstimation class
172  *
173  * \author Alexandru-Eugen Ichim
174  */
175 template <typename PointSource, typename PointTarget>
176 class PPFRegistration : public Registration<PointSource, PointTarget> {
177 public:
178  /** \brief Structure for storing a pose (represented as an Eigen::Affine3f) and an
179  * integer for counting votes \note initially used std::pair<Eigen::Affine3f, unsigned
180  * int>, but it proved problematic because of the Eigen structures alignment problems
181  * - std::pair does not have a custom allocator
182  */
183  struct PoseWithVotes {
184  PoseWithVotes(Eigen::Affine3f& a_pose, unsigned int& a_votes)
185  : pose(a_pose), votes(a_votes)
186  {}
187 
188  Eigen::Affine3f pose;
189  unsigned int votes;
190  };
191  using PoseWithVotesList =
192  std::vector<PoseWithVotes, Eigen::aligned_allocator<PoseWithVotes>>;
193 
194  /// input_ is the model cloud
196  /// target_ is the scene cloud
201 
205 
209 
210  /** \brief Empty constructor that initializes all the parameters of the algorithm with
211  * default values */
213  : Registration<PointSource, PointTarget>()
214  , scene_reference_point_sampling_rate_(5)
215  , clustering_position_diff_threshold_(0.01f)
216  , clustering_rotation_diff_threshold_(20.0f / 180.0f * static_cast<float>(M_PI))
217  {}
218 
219  /** \brief Method for setting the position difference clustering parameter
220  * \param clustering_position_diff_threshold distance threshold below which two poses
221  * are considered close enough to be in the same cluster (for the clustering phase of
222  * the algorithm)
223  */
224  inline void
225  setPositionClusteringThreshold(float clustering_position_diff_threshold)
226  {
227  clustering_position_diff_threshold_ = clustering_position_diff_threshold;
228  }
229 
230  /** \brief Returns the parameter defining the position difference clustering parameter
231  * - distance threshold below which two poses are considered close enough to be in the
232  * same cluster (for the clustering phase of the algorithm)
233  */
234  inline float
236  {
237  return clustering_position_diff_threshold_;
238  }
239 
240  /** \brief Method for setting the rotation clustering parameter
241  * \param clustering_rotation_diff_threshold rotation difference threshold below which
242  * two poses are considered to be in the same cluster (for the clustering phase of the
243  * algorithm)
244  */
245  inline void
246  setRotationClusteringThreshold(float clustering_rotation_diff_threshold)
247  {
248  clustering_rotation_diff_threshold_ = clustering_rotation_diff_threshold;
249  }
250 
251  /** \brief Returns the parameter defining the rotation clustering threshold
252  */
253  inline float
255  {
256  return clustering_rotation_diff_threshold_;
257  }
258 
259  /** \brief Method for setting the scene reference point sampling rate
260  * \param scene_reference_point_sampling_rate sampling rate for the scene reference
261  * point
262  */
263  inline void
264  setSceneReferencePointSamplingRate(unsigned int scene_reference_point_sampling_rate)
265  {
266  scene_reference_point_sampling_rate_ = scene_reference_point_sampling_rate;
267  }
268 
269  /** \brief Returns the parameter for the scene reference point sampling rate of the
270  * algorithm */
271  inline unsigned int
273  {
274  return scene_reference_point_sampling_rate_;
275  }
276 
277  /** \brief Function that sets the search method for the algorithm
278  * \note Right now, the only available method is the one initially proposed by
279  * the authors - by using a hash map with discretized feature vectors
280  * \param search_method smart pointer to the search method to be set
281  */
282  inline void
284  {
285  search_method_ = search_method;
286  }
287 
288  /** \brief Getter function for the search method of the class */
289  inline PPFHashMapSearch::Ptr
291  {
292  return search_method_;
293  }
294 
295  /** \brief Provide a pointer to the input target (e.g., the point cloud that we want
296  * to align the input source to) \param cloud the input point cloud target
297  */
298  void
299  setInputTarget(const PointCloudTargetConstPtr& cloud) override;
300 
301 private:
302  /** \brief Method that calculates the transformation between the input_ and target_
303  * point clouds, based on the PPF features */
304  void
305  computeTransformation(PointCloudSource& output,
306  const Eigen::Matrix4f& guess) override;
307 
308  /** \brief the search method that is going to be used to find matching feature pairs
309  */
310  PPFHashMapSearch::Ptr search_method_;
311 
312  /** \brief parameter for the sampling rate of the scene reference points */
313  unsigned int scene_reference_point_sampling_rate_;
314 
315  /** \brief position and rotation difference thresholds below which two
316  * poses are considered to be in the same cluster (for the clustering phase of the
317  * algorithm) */
318  float clustering_position_diff_threshold_, clustering_rotation_diff_threshold_;
319 
320  /** \brief use a kd-tree with range searches of range max_dist to skip an O(N) pass
321  * through the point cloud */
322  typename pcl::KdTreeFLANN<PointTarget>::Ptr scene_search_tree_;
323 
324  /** \brief static method used for the std::sort function to order two PoseWithVotes
325  * instances by their number of votes*/
326  static bool
327  poseWithVotesCompareFunction(const PoseWithVotes& a, const PoseWithVotes& b);
328 
329  /** \brief static method used for the std::sort function to order two pairs <index,
330  * votes> by the number of votes (unsigned integer value) */
331  static bool
332  clusterVotesCompareFunction(const std::pair<std::size_t, unsigned int>& a,
333  const std::pair<std::size_t, unsigned int>& b);
334 
335  /** \brief Method that clusters a set of given poses by using the clustering
336  * thresholds and their corresponding number of votes (see publication for more
337  * details) */
338  void
339  clusterPoses(PoseWithVotesList& poses, PoseWithVotesList& result);
340 
341  /** \brief Method that checks whether two poses are close together - based on the
342  * clustering threshold parameters of the class */
343  bool
344  posesWithinErrorBounds(Eigen::Affine3f& pose1, Eigen::Affine3f& pose2);
345 };
346 } // namespace pcl
347 
348 #include <pcl/registration/impl/ppf_registration.hpp>
pcl
Definition: convolution.h:46
pcl::Registration
Registration represents the base registration class for general purpose, ICP-like methods.
Definition: registration.h:57
pcl::PPFRegistration::setInputTarget
void setInputTarget(const PointCloudTargetConstPtr &cloud) override
Provide a pointer to the input target (e.g., the point cloud that we want to align the input source t...
Definition: ppf_registration.hpp:53
pcl::PPFHashMapSearch::makeShared
Ptr makeShared()
Convenience method for returning a copy of the class instance as a shared_ptr.
Definition: ppf_registration.h:125
pcl::PPFRegistration::PointCloudTargetConstPtr
typename PointCloudTarget::ConstPtr PointCloudTargetConstPtr
Definition: ppf_registration.h:208
pcl::PPFHashMapSearch::alpha_m_
std::vector< std::vector< float > > alpha_m_
Definition: ppf_registration.h:154
pcl::PPFRegistration::getSearchMethod
PPFHashMapSearch::Ptr getSearchMethod()
Getter function for the search method of the class.
Definition: ppf_registration.h:290
pcl::PPFHashMapSearch
Definition: ppf_registration.h:49
pcl::PPFHashMapSearch::HashKeyStruct::HashKeyStruct
HashKeyStruct(int a, int b, int c, int d)
Definition: ppf_registration.h:59
pcl::PPFRegistration::setRotationClusteringThreshold
void setRotationClusteringThreshold(float clustering_rotation_diff_threshold)
Method for setting the rotation clustering parameter.
Definition: ppf_registration.h:246
pcl::PPFHashMapSearch::Ptr
shared_ptr< PPFHashMapSearch > Ptr
Definition: ppf_registration.h:82
pcl::PPFRegistration::getRotationClusteringThreshold
float getRotationClusteringThreshold()
Returns the parameter defining the rotation clustering threshold.
Definition: ppf_registration.h:254
pcl::PPFHashMapSearch::getModelDiameter
float getModelDiameter() const
Returns the maximum distance found between any feature pair in the given input feature cloud.
Definition: ppf_registration.h:149
pcl::PPFRegistration::PointCloudSourceConstPtr
typename PointCloudSource::ConstPtr PointCloudSourceConstPtr
Definition: ppf_registration.h:204
pcl::PPFRegistration::setSearchMethod
void setSearchMethod(PPFHashMapSearch::Ptr search_method)
Function that sets the search method for the algorithm.
Definition: ppf_registration.h:283
pcl::PPFHashMapSearch::HashKeyStruct::operator()
std::size_t operator()(const HashKeyStruct &s) const noexcept
Definition: ppf_registration.h:68
pcl::PointCloud< PointSource >
pcl::PPFRegistration::getSceneReferencePointSamplingRate
unsigned int getSceneReferencePointSamplingRate()
Returns the parameter for the scene reference point sampling rate of the algorithm.
Definition: ppf_registration.h:272
pcl::PPFHashMapSearch::FeatureHashMapType
std::unordered_multimap< HashKeyStruct, std::pair< std::size_t, std::size_t >, HashKeyStruct > FeatureHashMapType
Definition: ppf_registration.h:80
pcl::PPFRegistration::PoseWithVotesList
std::vector< PoseWithVotes, Eigen::aligned_allocator< PoseWithVotes > > PoseWithVotesList
Definition: ppf_registration.h:192
pcl::PPFHashMapSearch::FeatureHashMapTypePtr
shared_ptr< FeatureHashMapType > FeatureHashMapTypePtr
Definition: ppf_registration.h:81
pcl::PPFHashMapSearch::HashKeyStruct
Data structure to hold the information for the key in the feature hash map of the PPFHashMapSearch cl...
Definition: ppf_registration.h:56
M_PI
#define M_PI
Definition: pcl_macros.h:201
pcl::PPFHashMapSearch::PPFHashMapSearch
PPFHashMapSearch(float angle_discretization_step=12.0f/180.0f *static_cast< float >(M_PI), float distance_discretization_step=0.01f)
Constructor for the PPFHashMapSearch class which sets the two step parameters for the enclosed data s...
Definition: ppf_registration.h:91
pcl::PPFRegistration::PointCloudSourcePtr
typename PointCloudSource::Ptr PointCloudSourcePtr
Definition: ppf_registration.h:203
pcl::PPFHashMapSearch::getAngleDiscretizationStep
float getAngleDiscretizationStep() const
Returns the angle discretization step parameter (the step value between each bin of the hash map for ...
Definition: ppf_registration.h:133
pcl::PPFRegistration::PoseWithVotes
Structure for storing a pose (represented as an Eigen::Affine3f) and an integer for counting votes.
Definition: ppf_registration.h:183
pcl::PPFRegistration::PointCloudSource
pcl::PointCloud< PointSource > PointCloudSource
Definition: ppf_registration.h:202
pcl::PPFRegistration::PPFRegistration
PPFRegistration()
Empty constructor that initializes all the parameters of the algorithm with default values.
Definition: ppf_registration.h:212
pcl::PPFRegistration::setSceneReferencePointSamplingRate
void setSceneReferencePointSamplingRate(unsigned int scene_reference_point_sampling_rate)
Method for setting the scene reference point sampling rate.
Definition: ppf_registration.h:264
pcl::PointCloud< PointSource >::Ptr
shared_ptr< PointCloud< PointSource > > Ptr
Definition: point_cloud.h:406
pcl::PPFHashMapSearch::ConstPtr
shared_ptr< const PPFHashMapSearch > ConstPtr
Definition: ppf_registration.h:83
pcl::PPFHashMapSearch::getDistanceDiscretizationStep
float getDistanceDiscretizationStep() const
Returns the distance discretization step parameter (the step value between each bin of the hash map f...
Definition: ppf_registration.h:141
pcl::PPFRegistration
Class that registers two point clouds based on their sets of PPFSignatures.
Definition: ppf_registration.h:176
pcl::PointCloud::ConstPtr
shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:407
pcl::PPFRegistration::PoseWithVotes::PoseWithVotes
PoseWithVotes(Eigen::Affine3f &a_pose, unsigned int &a_votes)
Definition: ppf_registration.h:184
pcl::PPFRegistration::PoseWithVotes::votes
unsigned int votes
Definition: ppf_registration.h:189
pcl::PPFRegistration::getPositionClusteringThreshold
float getPositionClusteringThreshold()
Returns the parameter defining the position difference clustering parameter.
Definition: ppf_registration.h:235
pcl::PPFRegistration::setPositionClusteringThreshold
void setPositionClusteringThreshold(float clustering_position_diff_threshold)
Method for setting the position difference clustering parameter.
Definition: ppf_registration.h:225
pcl::PPFRegistration::PointCloudTargetPtr
typename PointCloudTarget::Ptr PointCloudTargetPtr
Definition: ppf_registration.h:207
pcl::KdTreeFLANN::Ptr
shared_ptr< KdTreeFLANN< PointT, Dist > > Ptr
Definition: kdtree_flann.h:84
PCL_EXPORTS
#define PCL_EXPORTS
Definition: pcl_macros.h:323
pcl::PPFRegistration::PoseWithVotes::pose
Eigen::Affine3f pose
Definition: ppf_registration.h:188