Point Cloud Library (PCL)  1.9.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
our_cvfh.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, 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: cvfh.h 4936 2012-03-07 11:12:45Z aaldoma $
38  *
39  */
40 
41 #ifndef PCL_FEATURES_OURCVFH_H_
42 #define PCL_FEATURES_OURCVFH_H_
43 
44 #include <pcl/features/feature.h>
45 #include <pcl/search/pcl_search.h>
46 #include <pcl/common/common.h>
47 
48 namespace pcl
49 {
50  /** \brief OURCVFHEstimation estimates the Oriented, Unique and Repetable Clustered Viewpoint Feature Histogram (CVFH) descriptor for a given
51  * point cloud dataset given XYZ data and normals, as presented in:
52  * - OUR-CVFH – Oriented, Unique and Repeatable Clustered Viewpoint Feature Histogram for Object Recognition and 6DOF Pose Estimation
53  * A. Aldoma, F. Tombari, R.B. Rusu and M. Vincze
54  * DAGM-OAGM 2012
55  * Graz, Austria
56  * The suggested PointOutT is pcl::VFHSignature308.
57  *
58  * \author Aitor Aldoma
59  * \ingroup features
60  */
61  template<typename PointInT, typename PointNT, typename PointOutT = pcl::VFHSignature308>
62  class OURCVFHEstimation : public FeatureFromNormals<PointInT, PointNT, PointOutT>
63  {
64  public:
65  typedef boost::shared_ptr<OURCVFHEstimation<PointInT, PointNT, PointOutT> > Ptr;
66  typedef boost::shared_ptr<const OURCVFHEstimation<PointInT, PointNT, PointOutT> > ConstPtr;
74 
78  /** \brief Empty constructor. */
80  vpx_ (0), vpy_ (0), vpz_ (0), leaf_size_ (0.005f), normalize_bins_ (false), curv_threshold_ (0.03f), cluster_tolerance_ (leaf_size_ * 3),
81  eps_angle_threshold_ (0.125f), min_points_ (50), radius_normals_ (leaf_size_ * 3), centroids_dominant_orientations_ (),
83  {
84  search_radius_ = 0;
85  k_ = 1;
86  feature_name_ = "OURCVFHEstimation";
87  refine_clusters_ = 1.f;
88  min_axis_value_ = 0.925f;
89  axis_ratio_ = 0.8f;
90  }
91  ;
92 
93  /** \brief Creates an affine transformation from the RF axes
94  * \param[in] evx the x-axis
95  * \param[in] evy the y-axis
96  * \param[in] evz the z-axis
97  * \param[out] transformPC the resulting transformation
98  * \param[in] center_mat 4x4 matrix concatenated to the resulting transformation
99  */
100  inline Eigen::Matrix4f
101  createTransFromAxes (Eigen::Vector3f & evx, Eigen::Vector3f & evy, Eigen::Vector3f & evz, Eigen::Affine3f & transformPC,
102  Eigen::Matrix4f & center_mat)
103  {
104  Eigen::Matrix4f trans;
105  trans.setIdentity (4, 4);
106  trans (0, 0) = evx (0, 0);
107  trans (1, 0) = evx (1, 0);
108  trans (2, 0) = evx (2, 0);
109  trans (0, 1) = evy (0, 0);
110  trans (1, 1) = evy (1, 0);
111  trans (2, 1) = evy (2, 0);
112  trans (0, 2) = evz (0, 0);
113  trans (1, 2) = evz (1, 0);
114  trans (2, 2) = evz (2, 0);
115 
116  Eigen::Matrix4f homMatrix = Eigen::Matrix4f ();
117  homMatrix.setIdentity (4, 4);
118  homMatrix = transformPC.matrix ();
119 
120  Eigen::Matrix4f trans_copy = trans.inverse ();
121  trans = trans_copy * center_mat * homMatrix;
122  return trans;
123  }
124 
125  /** \brief Computes SGURF and the shape distribution based on the selected SGURF
126  * \param[in] processed the input cloud
127  * \param[out] output the resulting signature
128  * \param[in] cluster_indices the indices of the stable cluster
129  */
130  void
131  computeRFAndShapeDistribution (PointInTPtr & processed, PointCloudOut &output, std::vector<pcl::PointIndices> & cluster_indices);
132 
133  /** \brief Computes SGURF
134  * \param[in] centroid the centroid of the cluster
135  * \param[in] normal_centroid the average of the normals
136  * \param[in] processed the input cloud
137  * \param[out] transformations the transformations aligning the cloud to the SGURF axes
138  * \param[out] grid the cloud transformed internally
139  * \param[in] indices the indices of the stable cluster
140  */
141  bool
142  sgurf (Eigen::Vector3f & centroid, Eigen::Vector3f & normal_centroid, PointInTPtr & processed, std::vector<Eigen::Matrix4f, Eigen::aligned_allocator<Eigen::Matrix4f> > & transformations,
143  PointInTPtr & grid, pcl::PointIndices & indices);
144 
145  /** \brief Removes normals with high curvature caused by real edges or noisy data
146  * \param[in] cloud pointcloud to be filtered
147  * \param[in] indices_to_use
148  * \param[out] indices_out the indices of the points with higher curvature than threshold
149  * \param[out] indices_in the indices of the remaining points after filtering
150  * \param[in] threshold threshold value for curvature
151  */
152  void
153  filterNormalsWithHighCurvature (const pcl::PointCloud<PointNT> & cloud, std::vector<int> & indices_to_use, std::vector<int> &indices_out,
154  std::vector<int> &indices_in, float threshold);
155 
156  /** \brief Set the viewpoint.
157  * \param[in] vpx the X coordinate of the viewpoint
158  * \param[in] vpy the Y coordinate of the viewpoint
159  * \param[in] vpz the Z coordinate of the viewpoint
160  */
161  inline void
162  setViewPoint (float vpx, float vpy, float vpz)
163  {
164  vpx_ = vpx;
165  vpy_ = vpy;
166  vpz_ = vpz;
167  }
168 
169  /** \brief Set the radius used to compute normals
170  * \param[in] radius_normals the radius
171  */
172  inline void
173  setRadiusNormals (float radius_normals)
174  {
175  radius_normals_ = radius_normals;
176  }
177 
178  /** \brief Get the viewpoint.
179  * \param[out] vpx the X coordinate of the viewpoint
180  * \param[out] vpy the Y coordinate of the viewpoint
181  * \param[out] vpz the Z coordinate of the viewpoint
182  */
183  inline void
184  getViewPoint (float &vpx, float &vpy, float &vpz)
185  {
186  vpx = vpx_;
187  vpy = vpy_;
188  vpz = vpz_;
189  }
190 
191  /** \brief Get the centroids used to compute different CVFH descriptors
192  * \param[out] centroids vector to hold the centroids
193  */
194  inline void
195  getCentroidClusters (std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> > & centroids)
196  {
197  for (size_t i = 0; i < centroids_dominant_orientations_.size (); ++i)
198  centroids.push_back (centroids_dominant_orientations_[i]);
199  }
200 
201  /** \brief Get the normal centroids used to compute different CVFH descriptors
202  * \param[out] centroids vector to hold the normal centroids
203  */
204  inline void
205  getCentroidNormalClusters (std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> > & centroids)
206  {
207  for (size_t i = 0; i < dominant_normals_.size (); ++i)
208  centroids.push_back (dominant_normals_[i]);
209  }
210 
211  /** \brief Sets max. Euclidean distance between points to be added to the cluster
212  * \param[in] d the maximum Euclidean distance
213  */
214 
215  inline void
217  {
218  cluster_tolerance_ = d;
219  }
220 
221  /** \brief Sets max. deviation of the normals between two points so they can be clustered together
222  * \param[in] d the maximum deviation
223  */
224  inline void
226  {
227  eps_angle_threshold_ = d;
228  }
229 
230  /** \brief Sets curvature threshold for removing normals
231  * \param[in] d the curvature threshold
232  */
233  inline void
235  {
236  curv_threshold_ = d;
237  }
238 
239  /** \brief Set minimum amount of points for a cluster to be considered
240  * \param[in] min the minimum amount of points to be set
241  */
242  inline void
243  setMinPoints (size_t min)
244  {
245  min_points_ = min;
246  }
247 
248  /** \brief Sets whether the signatures should be normalized or not
249  * \param[in] normalize true if normalization is required, false otherwise
250  */
251  inline void
252  setNormalizeBins (bool normalize)
253  {
254  normalize_bins_ = normalize;
255  }
256 
257  /** \brief Gets the indices of the original point cloud used to compute the signatures
258  * \param[out] indices vector of point indices
259  */
260  inline void
261  getClusterIndices (std::vector<pcl::PointIndices> & indices)
262  {
263  indices = clusters_;
264  }
265 
266  /** \brief Gets the number of non-disambiguable axes that correspond to each centroid
267  * \param[out] cluster_axes vector mapping each centroid to the number of signatures
268  */
269  inline void
270  getClusterAxes (std::vector<short> & cluster_axes)
271  {
272  cluster_axes = cluster_axes_;
273  }
274 
275  /** \brief Sets the refinement factor for the clusters
276  * \param[in] rc the factor used to decide if a point is used to estimate a stable cluster
277  */
278  void
279  setRefineClusters (float rc)
280  {
281  refine_clusters_ = rc;
282  }
283 
284  /** \brief Returns the transformations aligning the point cloud to the corresponding SGURF
285  * \param[out] trans vector of transformations
286  */
287  void
288  getTransforms (std::vector<Eigen::Matrix4f, Eigen::aligned_allocator<Eigen::Matrix4f> > & trans)
289  {
290  trans = transforms_;
291  }
292 
293  /** \brief Returns a boolean vector indicating of the transformation obtained by getTransforms() represents
294  * a valid SGURF
295  * \param[out] valid vector of booleans
296  */
297  void
298  getValidTransformsVec (std::vector<bool> & valid)
299  {
300  valid = valid_transforms_;
301  }
302 
303  /** \brief Sets the min axis ratio between the SGURF axes to decide if disambiguition is feasible
304  * \param[in] f the ratio between axes
305  */
306  void
307  setAxisRatio (float f)
308  {
309  axis_ratio_ = f;
310  }
311 
312  /** \brief Sets the min disambiguition axis value to generate several SGURFs for the cluster when disambiguition is difficult
313  * \param[in] f the min axis value
314  */
315  void
316  setMinAxisValue (float f)
317  {
318  min_axis_value_ = f;
319  }
320 
321  /** \brief Overloaded computed method from pcl::Feature.
322  * \param[out] output the resultant point cloud model dataset containing the estimated features
323  */
324  void
325  compute (PointCloudOut &output);
326 
327  private:
328  /** \brief Values describing the viewpoint ("pinhole" camera model assumed).
329  * By default, the viewpoint is set to 0,0,0.
330  */
331  float vpx_, vpy_, vpz_;
332 
333  /** \brief Size of the voxels after voxel gridding. IMPORTANT: Must match the voxel
334  * size of the training data or the normalize_bins_ flag must be set to true.
335  */
336  float leaf_size_;
337 
338  /** \brief Whether to normalize the signatures or not. Default: false. */
339  bool normalize_bins_;
340 
341  /** \brief Curvature threshold for removing normals. */
342  float curv_threshold_;
343 
344  /** \brief allowed Euclidean distance between points to be added to the cluster. */
345  float cluster_tolerance_;
346 
347  /** \brief deviation of the normals between two points so they can be clustered together. */
348  float eps_angle_threshold_;
349 
350  /** \brief Minimum amount of points in a clustered region to be considered stable for CVFH
351  * computation.
352  */
353  size_t min_points_;
354 
355  /** \brief Radius for the normals computation. */
356  float radius_normals_;
357 
358  /** \brief Factor for the cluster refinement */
359  float refine_clusters_;
360 
361  std::vector<Eigen::Matrix4f, Eigen::aligned_allocator<Eigen::Matrix4f> > transforms_;
362  std::vector<bool> valid_transforms_;
363 
364  float axis_ratio_;
365  float min_axis_value_;
366 
367  /** \brief Estimate the OUR-CVFH descriptors at
368  * a set of points given by <setInputCloud (), setIndices ()> using the surface in
369  * setSearchSurface ()
370  *
371  * \param[out] output the resultant point cloud model dataset that contains the OUR-CVFH
372  * feature estimates
373  */
374  void
375  computeFeature (PointCloudOut &output);
376 
377  /** \brief Region growing method using Euclidean distances and neighbors normals to
378  * add points to a region.
379  * \param[in] cloud point cloud to split into regions
380  * \param[in] normals are the normals of cloud
381  * \param[in] tolerance is the allowed Euclidean distance between points to be added to
382  * the cluster
383  * \param[in] tree is the spatial search structure for nearest neighbour search
384  * \param[out] clusters vector of indices representing the clustered regions
385  * \param[in] eps_angle deviation of the normals between two points so they can be
386  * clustered together
387  * \param[in] min_pts_per_cluster minimum cluster size. (default: 1 point)
388  * \param[in] max_pts_per_cluster maximum cluster size. (default: all the points)
389  */
390  void
391  extractEuclideanClustersSmooth (const pcl::PointCloud<pcl::PointNormal> &cloud, const pcl::PointCloud<pcl::PointNormal> &normals,
392  float tolerance, const pcl::search::Search<pcl::PointNormal>::Ptr &tree,
393  std::vector<pcl::PointIndices> &clusters, double eps_angle, unsigned int min_pts_per_cluster = 1,
394  unsigned int max_pts_per_cluster = (std::numeric_limits<int>::max) ());
395 
396  protected:
397  /** \brief Centroids that were used to compute different OUR-CVFH descriptors */
398  std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> > centroids_dominant_orientations_;
399  /** \brief Normal centroids that were used to compute different OUR-CVFH descriptors */
400  std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> > dominant_normals_;
401  /** \brief Indices to the points representing the stable clusters */
402  std::vector<pcl::PointIndices> clusters_;
403  /** \brief Mapping from clusters to OUR-CVFH descriptors */
404  std::vector<short> cluster_axes_;
405  };
406 }
407 
408 #ifdef PCL_NO_PRECOMPILE
409 #include <pcl/features/impl/our_cvfh.hpp>
410 #endif
411 
412 #endif //#ifndef PCL_FEATURES_VFH_H_
boost::shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:428
pcl::PointCloud< PointInT >::Ptr PointInTPtr
Definition: our_cvfh.h:77
void compute(PointCloudOut &output)
Overloaded computed method from pcl::Feature.
Definition: our_cvfh.hpp:52
void getTransforms(std::vector< Eigen::Matrix4f, Eigen::aligned_allocator< Eigen::Matrix4f > > &trans)
Returns the transformations aligning the point cloud to the corresponding SGURF.
Definition: our_cvfh.h:288
std::string feature_name_
The feature name.
Definition: feature.h:222
boost::shared_ptr< const OURCVFHEstimation< PointInT, PointNT, PointOutT > > ConstPtr
Definition: our_cvfh.h:66
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:45
int k_
The number of K nearest neighbors to use for each point.
Definition: feature.h:242
void filterNormalsWithHighCurvature(const pcl::PointCloud< PointNT > &cloud, std::vector< int > &indices_to_use, std::vector< int > &indices_out, std::vector< int > &indices_in, float threshold)
Removes normals with high curvature caused by real edges or noisy data.
Definition: our_cvfh.hpp:161
void setMinPoints(size_t min)
Set minimum amount of points for a cluster to be considered.
Definition: our_cvfh.h:243
void computeRFAndShapeDistribution(PointInTPtr &processed, PointCloudOut &output, std::vector< pcl::PointIndices > &cluster_indices)
Computes SGURF and the shape distribution based on the selected SGURF.
Definition: our_cvfh.hpp:375
std::vector< Eigen::Vector3f, Eigen::aligned_allocator< Eigen::Vector3f > > centroids_dominant_orientations_
Centroids that were used to compute different OUR-CVFH descriptors.
Definition: our_cvfh.h:398
void setNormalizeBins(bool normalize)
Sets whether the signatures should be normalized or not.
Definition: our_cvfh.h:252
void getClusterIndices(std::vector< pcl::PointIndices > &indices)
Gets the indices of the original point cloud used to compute the signatures.
Definition: our_cvfh.h:261
void getCentroidNormalClusters(std::vector< Eigen::Vector3f, Eigen::aligned_allocator< Eigen::Vector3f > > &centroids)
Get the normal centroids used to compute different CVFH descriptors.
Definition: our_cvfh.h:205
void setRadiusNormals(float radius_normals)
Set the radius used to compute normals.
Definition: our_cvfh.h:173
void setRefineClusters(float rc)
Sets the refinement factor for the clusters.
Definition: our_cvfh.h:279
std::vector< Eigen::Vector3f, Eigen::aligned_allocator< Eigen::Vector3f > > dominant_normals_
Normal centroids that were used to compute different OUR-CVFH descriptors.
Definition: our_cvfh.h:400
boost::shared_ptr< pcl::search::Search< PointT > > Ptr
Definition: search.h:81
void getValidTransformsVec(std::vector< bool > &valid)
Returns a boolean vector indicating of the transformation obtained by getTransforms() represents a va...
Definition: our_cvfh.h:298
void setClusterTolerance(float d)
Sets max.
Definition: our_cvfh.h:216
void getClusterAxes(std::vector< short > &cluster_axes)
Gets the number of non-disambiguable axes that correspond to each centroid.
Definition: our_cvfh.h:270
void setAxisRatio(float f)
Sets the min axis ratio between the SGURF axes to decide if disambiguition is feasible.
Definition: our_cvfh.h:307
PointCloud represents the base class in PCL for storing collections of 3D points. ...
bool sgurf(Eigen::Vector3f &centroid, Eigen::Vector3f &normal_centroid, PointInTPtr &processed, std::vector< Eigen::Matrix4f, Eigen::aligned_allocator< Eigen::Matrix4f > > &transformations, PointInTPtr &grid, pcl::PointIndices &indices)
Computes SGURF.
Definition: our_cvfh.hpp:191
void getViewPoint(float &vpx, float &vpy, float &vpz)
Get the viewpoint.
Definition: our_cvfh.h:184
Feature represents the base feature class.
Definition: feature.h:105
void setEPSAngleThreshold(float d)
Sets max.
Definition: our_cvfh.h:225
void getCentroidClusters(std::vector< Eigen::Vector3f, Eigen::aligned_allocator< Eigen::Vector3f > > &centroids)
Get the centroids used to compute different CVFH descriptors.
Definition: our_cvfh.h:195
void setViewPoint(float vpx, float vpy, float vpz)
Set the viewpoint.
Definition: our_cvfh.h:162
pcl::search::Search< PointNormal >::Ptr KdTreePtr
Definition: our_cvfh.h:76
OURCVFHEstimation()
Empty constructor.
Definition: our_cvfh.h:79
boost::shared_ptr< OURCVFHEstimation< PointInT, PointNT, PointOutT > > Ptr
Definition: our_cvfh.h:65
void setMinAxisValue(float f)
Sets the min disambiguition axis value to generate several SGURFs for the cluster when disambiguition...
Definition: our_cvfh.h:316
std::vector< short > cluster_axes_
Mapping from clusters to OUR-CVFH descriptors.
Definition: our_cvfh.h:404
void setCurvatureThreshold(float d)
Sets curvature threshold for removing normals.
Definition: our_cvfh.h:234
Feature< PointInT, PointOutT >::PointCloudOut PointCloudOut
Definition: our_cvfh.h:75
std::vector< pcl::PointIndices > clusters_
Indices to the points representing the stable clusters.
Definition: our_cvfh.h:402
OURCVFHEstimation estimates the Oriented, Unique and Repetable Clustered Viewpoint Feature Histogram ...
Definition: our_cvfh.h:62
double search_radius_
The nearest neighbors search radius for each point.
Definition: feature.h:239
Eigen::Matrix4f createTransFromAxes(Eigen::Vector3f &evx, Eigen::Vector3f &evy, Eigen::Vector3f &evz, Eigen::Affine3f &transformPC, Eigen::Matrix4f &center_mat)
Creates an affine transformation from the RF axes.
Definition: our_cvfh.h:101