Point Cloud Library (PCL)  1.8.0
spin_image.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$
38  */
39 
40 #ifndef PCL_SPIN_IMAGE_H_
41 #define PCL_SPIN_IMAGE_H_
42 
43 #include <pcl/point_types.h>
44 #include <pcl/features/feature.h>
45 
46 namespace pcl
47 {
48  /** \brief Estimates spin-image descriptors in the given input points.
49  *
50  * This class represents spin image descriptor. Spin image is
51  * a histogram of point locations summed along the bins of the image.
52  * A 2D accumulator indexed by <VAR>a</VAR> and <VAR>b</VAR> is created. Next,
53  * the coordinates (<VAR>a</VAR>, <VAR>b</VAR>) are computed for a vertex in
54  * the surface mesh that is within the support of the spin image
55  * (explained below). The bin indexed by (<VAR>a</VAR>, <VAR>b</VAR>) in
56  * the accumulator is then incremented; bilinear interpolation is used
57  * to smooth the contribution of the vertex. This procedure is repeated
58  * for all vertices within the support of the spin image.
59  * The resulting accumulator can be thought of as an image;
60  * dark areas in the image correspond to bins that contain many projected points.
61  * As long as the size of the bins in the accumulator is greater
62  * than the median distance between vertices in the mesh
63  * (the definition of mesh resolution), the position of individual
64  * vertices will be averaged out during spin image generation.
65  *
66  * \attention The input normals given by \ref setInputNormals have to match
67  * the input point cloud given by \ref setInputCloud. This behavior is
68  * different than feature estimation methods that extend \ref
69  * FeatureFromNormals, which match the normals with the search surface.
70  *
71  * With the default paramters, pcl::Histogram<153> is a good choice for PointOutT.
72  * Of course the dimension of this descriptor must change to match the number
73  * of bins set by the parameters.
74  *
75  * For further information please see:
76  *
77  * - Johnson, A. E., & Hebert, M. (1998). Surface Matching for Object
78  * Recognition in Complex 3D Scenes. Image and Vision Computing, 16,
79  * 635-651.
80  *
81  * The class also implements radial spin images and spin-images in angular domain
82  * (or both).
83  *
84  * \author Roman Shapovalov, Alexander Velizhev
85  * \ingroup features
86  */
87  template <typename PointInT, typename PointNT, typename PointOutT>
88  class SpinImageEstimation : public Feature<PointInT, PointOutT>
89  {
90  public:
91  typedef boost::shared_ptr<SpinImageEstimation<PointInT, PointNT, PointOutT> > Ptr;
92  typedef boost::shared_ptr<const SpinImageEstimation<PointInT, PointNT, PointOutT> > ConstPtr;
101 
103 
107 
111 
112  /** \brief Constructs empty spin image estimator.
113  *
114  * \param[in] image_width spin-image resolution, number of bins along one dimension
115  * \param[in] support_angle_cos minimal allowed cosine of the angle between
116  * the normals of input point and search surface point for the point
117  * to be retained in the support
118  * \param[in] min_pts_neighb min number of points in the support to correctly estimate
119  * spin-image. If at some point the support contains less points, exception is thrown
120  */
121  SpinImageEstimation (unsigned int image_width = 8,
122  double support_angle_cos = 0.0, // when 0, this is bogus, so not applied
123  unsigned int min_pts_neighb = 0);
124 
125  /** \brief Empty destructor */
126  virtual ~SpinImageEstimation () {}
127 
128  /** \brief Sets spin-image resolution.
129  *
130  * \param[in] bin_count spin-image resolution, number of bins along one dimension
131  */
132  void
133  setImageWidth (unsigned int bin_count)
134  {
135  image_width_ = bin_count;
136  }
137 
138  /** \brief Sets the maximum angle for the point normal to get to support region.
139  *
140  * \param[in] support_angle_cos minimal allowed cosine of the angle between
141  * the normals of input point and search surface point for the point
142  * to be retained in the support
143  */
144  void
145  setSupportAngle (double support_angle_cos)
146  {
147  if (0.0 > support_angle_cos || support_angle_cos > 1.0) // may be permit negative cosine?
148  {
149  throw PCLException ("Cosine of support angle should be between 0 and 1",
150  "spin_image.h", "setSupportAngle");
151  }
152 
153  support_angle_cos_ = support_angle_cos;
154  }
155 
156  /** \brief Sets minimal points count for spin image computation.
157  *
158  * \param[in] min_pts_neighb min number of points in the support to correctly estimate
159  * spin-image. If at some point the support contains less points, exception is thrown
160  */
161  void
162  setMinPointCountInNeighbourhood (unsigned int min_pts_neighb)
163  {
164  min_pts_neighb_ = min_pts_neighb;
165  }
166 
167  /** \brief Provide a pointer to the input dataset that contains the point normals of
168  * the input XYZ dataset given by \ref setInputCloud
169  *
170  * \attention The input normals given by \ref setInputNormals have to match
171  * the input point cloud given by \ref setInputCloud. This behavior is
172  * different than feature estimation methods that extend \ref
173  * FeatureFromNormals, which match the normals with the search surface.
174  * \param[in] normals the const boost shared pointer to a PointCloud of normals.
175  * By convention, L2 norm of each normal should be 1.
176  */
177  inline void
178  setInputNormals (const PointCloudNConstPtr &normals)
179  {
180  input_normals_ = normals;
181  }
182 
183  /** \brief Sets single vector a rotation axis for all input points.
184  *
185  * It could be useful e.g. when the vertical axis is known.
186  * \param[in] axis unit-length vector that serves as rotation axis for reference frame
187  */
188  void
189  setRotationAxis (const PointNT& axis)
190  {
191  rotation_axis_ = axis;
192  use_custom_axis_ = true;
193  use_custom_axes_cloud_ = false;
194  }
195 
196  /** \brief Sets array of vectors as rotation axes for input points.
197  *
198  * Useful e.g. when one wants to use tangents instead of normals as rotation axes
199  * \param[in] axes unit-length vectors that serves as rotation axes for
200  * the corresponding input points' reference frames
201  */
202  void
203  setInputRotationAxes (const PointCloudNConstPtr& axes)
204  {
205  rotation_axes_cloud_ = axes;
206 
207  use_custom_axes_cloud_ = true;
208  use_custom_axis_ = false;
209  }
210 
211  /** \brief Sets input normals as rotation axes (default setting). */
212  void
214  {
215  use_custom_axis_ = false;
216  use_custom_axes_cloud_ = false;
217  }
218 
219  /** \brief Sets/unsets flag for angular spin-image domain.
220  *
221  * Angular spin-image differs from the vanilla one in the way that not
222  * the points are collected in the bins but the angles between their
223  * normals and the normal to the reference point. For further
224  * information please see
225  * Endres, F., Plagemann, C., Stachniss, C., & Burgard, W. (2009).
226  * Unsupervised Discovery of Object Classes from Range Data using Latent Dirichlet Allocation.
227  * In Robotics: Science and Systems. Seattle, USA.
228  * \param[in] is_angular true for angular domain, false for point domain
229  */
230  void
231  setAngularDomain (bool is_angular = true) { is_angular_ = is_angular; }
232 
233  /** \brief Sets/unsets flag for radial spin-image structure.
234  *
235  * Instead of rectangular coordinate system for reference frame
236  * polar coordinates are used. Binning is done depending on the distance and
237  * inclination angle from the reference point
238  * \param[in] is_radial true for radial spin-image structure, false for rectangular
239  */
240  void
241  setRadialStructure (bool is_radial = true) { is_radial_ = is_radial; }
242 
243  protected:
244  /** \brief Estimate the Spin Image descriptors at a set of points given by
245  * setInputWithNormals() using the surface in setSearchSurfaceWithNormals() and the spatial locator
246  * \param[out] output the resultant point cloud that contains the Spin Image feature estimates
247  */
248  virtual void
249  computeFeature (PointCloudOut &output);
250 
251  /** \brief initializes computations specific to spin-image.
252  *
253  * \return true iff input data and initialization are correct
254  */
255  virtual bool
256  initCompute ();
257 
258  /** \brief Computes a spin-image for the point of the scan.
259  * \param[in] index the index of the reference point in the input cloud
260  * \return estimated spin-image (or its variant) as a matrix
261  */
262  Eigen::ArrayXXd
263  computeSiForPoint (int index) const;
264 
265  private:
266  PointCloudNConstPtr input_normals_;
267  PointCloudNConstPtr rotation_axes_cloud_;
268 
269  bool is_angular_;
270 
271  PointNT rotation_axis_;
272  bool use_custom_axis_;
273  bool use_custom_axes_cloud_;
274 
275  bool is_radial_;
276 
277  unsigned int image_width_;
278  double support_angle_cos_;
279  unsigned int min_pts_neighb_;
280  };
281 }
282 
283 #ifdef PCL_NO_PRECOMPILE
284 #include <pcl/features/impl/spin_image.hpp>
285 #endif
286 
287 #endif //#ifndef PCL_SPIN_IMAGE_H_
288 
void setInputRotationAxes(const PointCloudNConstPtr &axes)
Sets array of vectors as rotation axes for input points.
Definition: spin_image.h:203
boost::shared_ptr< SpinImageEstimation< PointInT, PointNT, PointOutT > > Ptr
Definition: spin_image.h:91
SpinImageEstimation(unsigned int image_width=8, double support_angle_cos=0.0, unsigned int min_pts_neighb=0)
Constructs empty spin image estimator.
Definition: spin_image.hpp:54
virtual bool initCompute()
initializes computations specific to spin-image.
Definition: spin_image.hpp:239
A base class for all pcl exceptions which inherits from std::runtime_error.
Definition: exceptions.h:64
PointCloudN::Ptr PointCloudNPtr
Definition: spin_image.h:105
PointCloudIn::ConstPtr PointCloudInConstPtr
Definition: spin_image.h:110
virtual void computeFeature(PointCloudOut &output)
Estimate the Spin Image descriptors at a set of points given by setInputWithNormals() using the surfa...
Definition: spin_image.hpp:324
pcl::PointCloud< PointInT > PointCloudIn
Definition: spin_image.h:108
pcl::PointCloud< PointNT > PointCloudN
Definition: spin_image.h:104
boost::shared_ptr< const SpinImageEstimation< PointInT, PointNT, PointOutT > > ConstPtr
Definition: spin_image.h:92
boost::shared_ptr< PointCloud< PointNT > > Ptr
Definition: point_cloud.h:428
void setAngularDomain(bool is_angular=true)
Sets/unsets flag for angular spin-image domain.
Definition: spin_image.h:231
PointCloudN::ConstPtr PointCloudNConstPtr
Definition: spin_image.h:106
void setImageWidth(unsigned int bin_count)
Sets spin-image resolution.
Definition: spin_image.h:133
void setSupportAngle(double support_angle_cos)
Sets the maximum angle for the point normal to get to support region.
Definition: spin_image.h:145
PCL base class.
Definition: pcl_base.h:68
PointCloudIn::Ptr PointCloudInPtr
Definition: spin_image.h:109
boost::shared_ptr< const PointCloud< PointNT > > ConstPtr
Definition: point_cloud.h:429
PointCloud represents the base class in PCL for storing collections of 3D points. ...
void useNormalsAsRotationAxis()
Sets input normals as rotation axes (default setting).
Definition: spin_image.h:213
void setRotationAxis(const PointNT &axis)
Sets single vector a rotation axis for all input points.
Definition: spin_image.h:189
virtual ~SpinImageEstimation()
Empty destructor.
Definition: spin_image.h:126
Feature represents the base feature class.
Definition: feature.h:105
Feature< PointInT, PointOutT >::PointCloudOut PointCloudOut
Definition: spin_image.h:102
Eigen::ArrayXXd computeSiForPoint(int index) const
Computes a spin-image for the point of the scan.
Definition: spin_image.hpp:69
Estimates spin-image descriptors in the given input points.
Definition: spin_image.h:88
void setRadialStructure(bool is_radial=true)
Sets/unsets flag for radial spin-image structure.
Definition: spin_image.h:241
void setInputNormals(const PointCloudNConstPtr &normals)
Provide a pointer to the input dataset that contains the point normals of the input XYZ dataset given...
Definition: spin_image.h:178
void setMinPointCountInNeighbourhood(unsigned int min_pts_neighb)
Sets minimal points count for spin image computation.
Definition: spin_image.h:162