Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/features/include/pcl/features/3dsc.h
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 
00041 #ifndef PCL_FEATURES_3DSC_H_
00042 #define PCL_FEATURES_3DSC_H_
00043 
00044 #include <pcl/point_types.h>
00045 #include <pcl/features/boost.h>
00046 #include <pcl/features/feature.h>
00047 
00048 namespace pcl
00049 {
00050   /** \brief ShapeContext3DEstimation implements the 3D shape context descriptor as
00051     * described in:
00052     *   - Andrea Frome, Daniel Huber, Ravi Kolluri and Thomas Bülow, Jitendra Malik
00053     *     Recognizing Objects in Range Data Using Regional Point Descriptors,
00054     *     In proceedings of the 8th European Conference on Computer Vision (ECCV),
00055     *     Prague, May 11-14, 2004
00056     *
00057     * The suggested PointOutT is pcl::ShapeContext1980
00058     *
00059     * \attention
00060     * The convention for a 3D shape context descriptor is:
00061     *   - if a query point's nearest neighbors cannot be estimated, the feature descriptor will be set to NaN (not a number), and the RF to 0
00062     *   - it is impossible to estimate a 3D shape context descriptor for a
00063     *     point that doesn't have finite 3D coordinates. Therefore, any point
00064     *     that contains NaN data on x, y, or z, will have its boundary feature
00065     *     property set to NaN.
00066     *
00067     * \author Alessandro Franchi, Samuele Salti, Federico Tombari (original code)
00068     * \author Nizar Sallem (port to PCL)
00069     * \ingroup features
00070     */
00071   template <typename PointInT, typename PointNT, typename PointOutT = pcl::ShapeContext1980>
00072   class ShapeContext3DEstimation : public FeatureFromNormals<PointInT, PointNT, PointOutT>
00073   {
00074     public:
00075       typedef boost::shared_ptr<ShapeContext3DEstimation<PointInT, PointNT, PointOutT> > Ptr;
00076       typedef boost::shared_ptr<const ShapeContext3DEstimation<PointInT, PointNT, PointOutT> > ConstPtr;
00077 
00078       using Feature<PointInT, PointOutT>::feature_name_;
00079       using Feature<PointInT, PointOutT>::getClassName;
00080       using Feature<PointInT, PointOutT>::indices_;
00081       using Feature<PointInT, PointOutT>::search_parameter_;
00082       using Feature<PointInT, PointOutT>::search_radius_;
00083       using Feature<PointInT, PointOutT>::surface_;
00084       using Feature<PointInT, PointOutT>::input_;
00085       using Feature<PointInT, PointOutT>::searchForNeighbors;
00086       using FeatureFromNormals<PointInT, PointNT, PointOutT>::normals_;
00087 
00088       typedef typename Feature<PointInT, PointOutT>::PointCloudOut PointCloudOut;
00089       typedef typename Feature<PointInT, PointOutT>::PointCloudIn PointCloudIn;
00090 
00091       /** \brief Constructor.
00092         * \param[in] random If true the random seed is set to current time, else it is
00093         * set to 12345 prior to computing the descriptor (used to select X axis)
00094         */
00095       ShapeContext3DEstimation (bool random = false) :
00096         radii_interval_(0),
00097         theta_divisions_(0),
00098         phi_divisions_(0),
00099         volume_lut_(0),
00100         azimuth_bins_(12),
00101         elevation_bins_(11),
00102         radius_bins_(15),
00103         min_radius_(0.1),
00104         point_density_radius_(0.2),
00105         descriptor_length_ (),
00106         rng_alg_ (),
00107         rng_ (new boost::uniform_01<boost::mt19937> (rng_alg_))
00108       {
00109         feature_name_ = "ShapeContext3DEstimation";
00110         search_radius_ = 2.5;
00111 
00112         // Create a random number generator object
00113         if (random)
00114           rng_->base ().seed (static_cast<unsigned> (std::time(0)));
00115         else
00116           rng_->base ().seed (12345u);
00117       }
00118 
00119       virtual ~ShapeContext3DEstimation() {}
00120 
00121       //inline void
00122       //setAzimuthBins (size_t bins) { azimuth_bins_ = bins; }
00123 
00124       /** \return the number of bins along the azimuth */
00125       inline size_t
00126       getAzimuthBins () { return (azimuth_bins_); }
00127 
00128       //inline void
00129       //setElevationBins (size_t bins) { elevation_bins_ = bins; }
00130 
00131       /** \return The number of bins along the elevation */
00132       inline size_t
00133       getElevationBins () { return (elevation_bins_); }
00134 
00135       //inline void
00136       //setRadiusBins (size_t bins) { radius_bins_ = bins; }
00137 
00138       /** \return The number of bins along the radii direction */
00139       inline size_t
00140       getRadiusBins () { return (radius_bins_); }
00141 
00142       /** \brief The minimal radius value for the search sphere (rmin) in the original paper
00143         * \param[in] radius the desired minimal radius
00144         */
00145       inline void
00146       setMinimalRadius (double radius) { min_radius_ = radius; }
00147 
00148       /** \return The minimal sphere radius */
00149       inline double
00150       getMinimalRadius () { return (min_radius_); }
00151 
00152       /** \brief This radius is used to compute local point density
00153         * density = number of points within this radius
00154         * \param[in] radius value of the point density search radius
00155         */
00156       inline void
00157       setPointDensityRadius (double radius) { point_density_radius_ = radius; }
00158 
00159       /** \return The point density search radius */
00160       inline double
00161       getPointDensityRadius () { return (point_density_radius_); }
00162 
00163     protected:
00164       /** \brief Initialize computation by allocating all the intervals and the volume lookup table. */
00165       bool
00166       initCompute ();
00167 
00168       /** \brief Estimate a descriptor for a given point.
00169         * \param[in] index the index of the point to estimate a descriptor for
00170         * \param[in] normals a pointer to the set of normals
00171         * \param[in] rf the reference frame
00172         * \param[out] desc the resultant estimated descriptor
00173         * \return true if the descriptor was computed successfully, false if there was an error
00174         * (e.g. the nearest neighbor didn't return any neighbors)
00175         */
00176       bool
00177       computePoint (size_t index, const pcl::PointCloud<PointNT> &normals, float rf[9], std::vector<float> &desc);
00178 
00179       /** \brief Estimate the actual feature.
00180         * \param[out] output the resultant feature
00181         */
00182       void
00183       computeFeature (PointCloudOut &output);
00184 
00185       /** \brief Values of the radii interval */
00186       std::vector<float> radii_interval_;
00187 
00188       /** \brief Theta divisions interval */
00189       std::vector<float> theta_divisions_;
00190 
00191       /** \brief Phi divisions interval */
00192       std::vector<float> phi_divisions_;
00193 
00194       /** \brief Volumes look up table */
00195       std::vector<float> volume_lut_;
00196 
00197       /** \brief Bins along the azimuth dimension */
00198       size_t azimuth_bins_;
00199 
00200       /** \brief Bins along the elevation dimension */
00201       size_t elevation_bins_;
00202 
00203       /** \brief Bins along the radius dimension */
00204       size_t radius_bins_;
00205 
00206       /** \brief Minimal radius value */
00207       double min_radius_;
00208 
00209       /** \brief Point density radius */
00210       double point_density_radius_;
00211 
00212       /** \brief Descriptor length */
00213       size_t descriptor_length_;
00214 
00215       /** \brief Boost-based random number generator algorithm. */
00216       boost::mt19937 rng_alg_;
00217 
00218       /** \brief Boost-based random number generator distribution. */
00219       boost::shared_ptr<boost::uniform_01<boost::mt19937> > rng_;
00220 
00221       /** \brief Shift computed descriptor "L" times along the azimuthal direction
00222         * \param[in] block_size the size of each azimuthal block
00223         * \param[in] desc at input desc == original descriptor and on output it contains
00224         * shifted descriptor resized descriptor_length_ * azimuth_bins_
00225         */
00226       //void
00227       //shiftAlongAzimuth (size_t block_size, std::vector<float>& desc);
00228 
00229       /** \brief Boost-based random number generator. */
00230       inline double
00231       rnd ()
00232       {
00233         return ((*rng_) ());
00234       }
00235   };
00236 }
00237 
00238 #ifdef PCL_NO_PRECOMPILE
00239 #include <pcl/features/impl/3dsc.hpp>
00240 #endif
00241 
00242 #endif  //#ifndef PCL_3DSC_H_