Point Cloud Library (PCL)
1.7.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2011, Willow Garage, Inc. 00006 * Copyright (c) 2012-, Open Perception, Inc. 00007 * 00008 * All rights reserved. 00009 * 00010 * Redistribution and use in source and binary forms, with or without 00011 * modification, are permitted provided that the following conditions 00012 * are met: 00013 * 00014 * * Redistributions of source code must retain the above copyright 00015 * notice, this list of conditions and the following disclaimer. 00016 * * Redistributions in binary form must reproduce the above 00017 * copyright notice, this list of conditions and the following 00018 * disclaimer in the documentation and/or other materials provided 00019 * with the distribution. 00020 * * Neither the name of the copyright holder(s) nor the names of its 00021 * contributors may be used to endorse or promote products derived 00022 * from this software without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00025 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00026 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00027 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00028 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00029 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00030 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00031 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00032 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00033 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00034 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00035 * POSSIBILITY OF SUCH DAMAGE. 00036 * 00037 * $Id$ 00038 */ 00039 00040 #ifndef PCL_SPIN_IMAGE_H_ 00041 #define PCL_SPIN_IMAGE_H_ 00042 00043 #include <pcl/point_types.h> 00044 #include <pcl/features/feature.h> 00045 00046 namespace pcl 00047 { 00048 /** \brief Estimates spin-image descriptors in the given input points. 00049 * 00050 * This class represents spin image descriptor. Spin image is 00051 * a histogram of point locations summed along the bins of the image. 00052 * A 2D accumulator indexed by <VAR>a</VAR> and <VAR>b</VAR> is created. Next, 00053 * the coordinates (<VAR>a</VAR>, <VAR>b</VAR>) are computed for a vertex in 00054 * the surface mesh that is within the support of the spin image 00055 * (explained below). The bin indexed by (<VAR>a</VAR>, <VAR>b</VAR>) in 00056 * the accumulator is then incremented; bilinear interpolation is used 00057 * to smooth the contribution of the vertex. This procedure is repeated 00058 * for all vertices within the support of the spin image. 00059 * The resulting accumulator can be thought of as an image; 00060 * dark areas in the image correspond to bins that contain many projected points. 00061 * As long as the size of the bins in the accumulator is greater 00062 * than the median distance between vertices in the mesh 00063 * (the definition of mesh resolution), the position of individual 00064 * vertices will be averaged out during spin image generation. 00065 * 00066 * \attention The input normals given by \ref setInputNormals have to match 00067 * the input point cloud given by \ref setInputCloud. This behavior is 00068 * different than feature estimation methods that extend \ref 00069 * FeatureFromNormals, which match the normals with the search surface. 00070 * 00071 * With the default paramters, pcl::Histogram<153> is a good choice for PointOutT. 00072 * Of course the dimension of this descriptor must change to match the number 00073 * of bins set by the parameters. 00074 * 00075 * For further information please see: 00076 * 00077 * - Johnson, A. E., & Hebert, M. (1998). Surface Matching for Object 00078 * Recognition in Complex 3D Scenes. Image and Vision Computing, 16, 00079 * 635-651. 00080 * 00081 * The class also implements radial spin images and spin-images in angular domain 00082 * (or both). 00083 * 00084 * \author Roman Shapovalov, Alexander Velizhev 00085 * \ingroup features 00086 */ 00087 template <typename PointInT, typename PointNT, typename PointOutT> 00088 class SpinImageEstimation : public Feature<PointInT, PointOutT> 00089 { 00090 public: 00091 typedef boost::shared_ptr<SpinImageEstimation<PointInT, PointNT, PointOutT> > Ptr; 00092 typedef boost::shared_ptr<const SpinImageEstimation<PointInT, PointNT, PointOutT> > ConstPtr; 00093 using Feature<PointInT, PointOutT>::feature_name_; 00094 using Feature<PointInT, PointOutT>::getClassName; 00095 using Feature<PointInT, PointOutT>::indices_; 00096 using Feature<PointInT, PointOutT>::search_radius_; 00097 using Feature<PointInT, PointOutT>::k_; 00098 using Feature<PointInT, PointOutT>::surface_; 00099 using Feature<PointInT, PointOutT>::fake_surface_; 00100 using PCLBase<PointInT>::input_; 00101 00102 typedef typename Feature<PointInT, PointOutT>::PointCloudOut PointCloudOut; 00103 00104 typedef typename pcl::PointCloud<PointNT> PointCloudN; 00105 typedef typename PointCloudN::Ptr PointCloudNPtr; 00106 typedef typename PointCloudN::ConstPtr PointCloudNConstPtr; 00107 00108 typedef typename pcl::PointCloud<PointInT> PointCloudIn; 00109 typedef typename PointCloudIn::Ptr PointCloudInPtr; 00110 typedef typename PointCloudIn::ConstPtr PointCloudInConstPtr; 00111 00112 /** \brief Constructs empty spin image estimator. 00113 * 00114 * \param[in] image_width spin-image resolution, number of bins along one dimension 00115 * \param[in] support_angle_cos minimal allowed cosine of the angle between 00116 * the normals of input point and search surface point for the point 00117 * to be retained in the support 00118 * \param[in] min_pts_neighb min number of points in the support to correctly estimate 00119 * spin-image. If at some point the support contains less points, exception is thrown 00120 */ 00121 SpinImageEstimation (unsigned int image_width = 8, 00122 double support_angle_cos = 0.0, // when 0, this is bogus, so not applied 00123 unsigned int min_pts_neighb = 0); 00124 00125 /** \brief Empty destructor */ 00126 virtual ~SpinImageEstimation () {} 00127 00128 /** \brief Sets spin-image resolution. 00129 * 00130 * \param[in] bin_count spin-image resolution, number of bins along one dimension 00131 */ 00132 void 00133 setImageWidth (unsigned int bin_count) 00134 { 00135 image_width_ = bin_count; 00136 } 00137 00138 /** \brief Sets the maximum angle for the point normal to get to support region. 00139 * 00140 * \param[in] support_angle_cos minimal allowed cosine of the angle between 00141 * the normals of input point and search surface point for the point 00142 * to be retained in the support 00143 */ 00144 void 00145 setSupportAngle (double support_angle_cos) 00146 { 00147 if (0.0 > support_angle_cos || support_angle_cos > 1.0) // may be permit negative cosine? 00148 { 00149 throw PCLException ("Cosine of support angle should be between 0 and 1", 00150 "spin_image.h", "setSupportAngle"); 00151 } 00152 00153 support_angle_cos_ = support_angle_cos; 00154 } 00155 00156 /** \brief Sets minimal points count for spin image computation. 00157 * 00158 * \param[in] min_pts_neighb min number of points in the support to correctly estimate 00159 * spin-image. If at some point the support contains less points, exception is thrown 00160 */ 00161 void 00162 setMinPointCountInNeighbourhood (unsigned int min_pts_neighb) 00163 { 00164 min_pts_neighb_ = min_pts_neighb; 00165 } 00166 00167 /** \brief Provide a pointer to the input dataset that contains the point normals of 00168 * the input XYZ dataset given by \ref setInputCloud 00169 * 00170 * \attention The input normals given by \ref setInputNormals have to match 00171 * the input point cloud given by \ref setInputCloud. This behavior is 00172 * different than feature estimation methods that extend \ref 00173 * FeatureFromNormals, which match the normals with the search surface. 00174 * \param[in] normals the const boost shared pointer to a PointCloud of normals. 00175 * By convention, L2 norm of each normal should be 1. 00176 */ 00177 inline void 00178 setInputNormals (const PointCloudNConstPtr &normals) 00179 { 00180 input_normals_ = normals; 00181 } 00182 00183 /** \brief Sets single vector a rotation axis for all input points. 00184 * 00185 * It could be useful e.g. when the vertical axis is known. 00186 * \param[in] axis unit-length vector that serves as rotation axis for reference frame 00187 */ 00188 void 00189 setRotationAxis (const PointNT& axis) 00190 { 00191 rotation_axis_ = axis; 00192 use_custom_axis_ = true; 00193 use_custom_axes_cloud_ = false; 00194 } 00195 00196 /** \brief Sets array of vectors as rotation axes for input points. 00197 * 00198 * Useful e.g. when one wants to use tangents instead of normals as rotation axes 00199 * \param[in] axes unit-length vectors that serves as rotation axes for 00200 * the corresponding input points' reference frames 00201 */ 00202 void 00203 setInputRotationAxes (const PointCloudNConstPtr& axes) 00204 { 00205 rotation_axes_cloud_ = axes; 00206 00207 use_custom_axes_cloud_ = true; 00208 use_custom_axis_ = false; 00209 } 00210 00211 /** \brief Sets input normals as rotation axes (default setting). */ 00212 void 00213 useNormalsAsRotationAxis () 00214 { 00215 use_custom_axis_ = false; 00216 use_custom_axes_cloud_ = false; 00217 } 00218 00219 /** \brief Sets/unsets flag for angular spin-image domain. 00220 * 00221 * Angular spin-image differs from the vanilla one in the way that not 00222 * the points are collected in the bins but the angles between their 00223 * normals and the normal to the reference point. For further 00224 * information please see 00225 * Endres, F., Plagemann, C., Stachniss, C., & Burgard, W. (2009). 00226 * Unsupervised Discovery of Object Classes from Range Data using Latent Dirichlet Allocation. 00227 * In Robotics: Science and Systems. Seattle, USA. 00228 * \param[in] is_angular true for angular domain, false for point domain 00229 */ 00230 void 00231 setAngularDomain (bool is_angular = true) { is_angular_ = is_angular; } 00232 00233 /** \brief Sets/unsets flag for radial spin-image structure. 00234 * 00235 * Instead of rectangular coordinate system for reference frame 00236 * polar coordinates are used. Binning is done depending on the distance and 00237 * inclination angle from the reference point 00238 * \param[in] is_radial true for radial spin-image structure, false for rectangular 00239 */ 00240 void 00241 setRadialStructure (bool is_radial = true) { is_radial_ = is_radial; } 00242 00243 protected: 00244 /** \brief Estimate the Spin Image descriptors at a set of points given by 00245 * setInputWithNormals() using the surface in setSearchSurfaceWithNormals() and the spatial locator 00246 * \param[out] output the resultant point cloud that contains the Spin Image feature estimates 00247 */ 00248 virtual void 00249 computeFeature (PointCloudOut &output); 00250 00251 /** \brief initializes computations specific to spin-image. 00252 * 00253 * \return true iff input data and initialization are correct 00254 */ 00255 virtual bool 00256 initCompute (); 00257 00258 /** \brief Computes a spin-image for the point of the scan. 00259 * \param[in] index the index of the reference point in the input cloud 00260 * \return estimated spin-image (or its variant) as a matrix 00261 */ 00262 Eigen::ArrayXXd 00263 computeSiForPoint (int index) const; 00264 00265 private: 00266 PointCloudNConstPtr input_normals_; 00267 PointCloudNConstPtr rotation_axes_cloud_; 00268 00269 bool is_angular_; 00270 00271 PointNT rotation_axis_; 00272 bool use_custom_axis_; 00273 bool use_custom_axes_cloud_; 00274 00275 bool is_radial_; 00276 00277 unsigned int image_width_; 00278 double support_angle_cos_; 00279 unsigned int min_pts_neighb_; 00280 }; 00281 } 00282 00283 #ifdef PCL_NO_PRECOMPILE 00284 #include <pcl/features/impl/spin_image.hpp> 00285 #endif 00286 00287 #endif //#ifndef PCL_SPIN_IMAGE_H_ 00288