Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/features/include/pcl/features/rsd.h
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2009, 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_RSD_H_
00042 #define PCL_RSD_H_
00043 
00044 #include <pcl/features/feature.h>
00045 
00046 namespace pcl
00047 {
00048   /** \brief Transform a list of 2D matrices into a point cloud containing the values in a vector (Histogram<N>).
00049     * Can be used to transform the 2D histograms obtained in \ref RSDEstimation into a point cloud.
00050     * @note The template paramter N should be (greater or) equal to the product of the number of rows and columns.
00051     * \param[in] histograms2D the list of neighborhood 2D histograms
00052     * \param[out] histogramsPC the dataset containing the linearized matrices
00053     * \ingroup features
00054     */
00055   template <int N> void
00056   getFeaturePointCloud (const std::vector<Eigen::MatrixXf, Eigen::aligned_allocator<Eigen::MatrixXf> > &histograms2D, PointCloud<Histogram<N> > &histogramsPC)
00057   {
00058     histogramsPC.points.resize (histograms2D.size ());
00059     histogramsPC.width    = histograms2D.size ();
00060     histogramsPC.height   = 1;
00061     histogramsPC.is_dense = true;
00062 
00063     const int rows  = histograms2D.at(0).rows();
00064     const int cols = histograms2D.at(0).cols();
00065 
00066     typename PointCloud<Histogram<N> >::VectorType::iterator it = histogramsPC.points.begin ();
00067     BOOST_FOREACH (Eigen::MatrixXf h, histograms2D)
00068     {
00069       Eigen::Map<Eigen::MatrixXf> histogram (&(it->histogram[0]), rows, cols);
00070       histogram = h;
00071       ++it;
00072     }
00073   }
00074 
00075   /** \brief Estimate the Radius-based Surface Descriptor (RSD) for a given point based on its spatial neighborhood of 3D points with normals
00076     * \param[in] surface the dataset containing the XYZ points
00077     * \param[in] normals the dataset containing the surface normals at each point in the dataset
00078     * \param[in] indices the neighborhood point indices in the dataset (first point is used as the reference)
00079     * \param[in] max_dist the upper bound for the considered distance interval
00080     * \param[in] nr_subdiv the number of subdivisions for the considered distance interval
00081     * \param[in] plane_radius maximum radius, above which everything can be considered planar
00082     * \param[in] radii the output point of a type that should have r_min and r_max fields
00083     * \param[in] compute_histogram if not false, the full neighborhood histogram is provided, usable as a point signature
00084     * \ingroup features
00085     */
00086   template <typename PointInT, typename PointNT, typename PointOutT> Eigen::MatrixXf
00087   computeRSD (boost::shared_ptr<const pcl::PointCloud<PointInT> > &surface, boost::shared_ptr<const pcl::PointCloud<PointNT> > &normals,
00088              const std::vector<int> &indices, double max_dist,
00089              int nr_subdiv, double plane_radius, PointOutT &radii, bool compute_histogram = false);
00090 
00091   /** \brief Estimate the Radius-based Surface Descriptor (RSD) for a given point based on its spatial neighborhood of 3D points with normals
00092     * \param[in] normals the dataset containing the surface normals at each point in the dataset
00093     * \param[in] indices the neighborhood point indices in the dataset (first point is used as the reference)
00094     * \param[in] sqr_dists the squared distances from the first to all points in the neighborhood
00095     * \param[in] max_dist the upper bound for the considered distance interval
00096     * \param[in] nr_subdiv the number of subdivisions for the considered distance interval
00097     * \param[in] plane_radius maximum radius, above which everything can be considered planar
00098     * \param[in] radii the output point of a type that should have r_min and r_max fields
00099     * \param[in] compute_histogram if not false, the full neighborhood histogram is provided, usable as a point signature
00100     * \ingroup features
00101     */
00102   template <typename PointNT, typename PointOutT> Eigen::MatrixXf
00103   computeRSD (boost::shared_ptr<const pcl::PointCloud<PointNT> > &normals,
00104              const std::vector<int> &indices, const std::vector<float> &sqr_dists, double max_dist,
00105              int nr_subdiv, double plane_radius, PointOutT &radii, bool compute_histogram = false);
00106 
00107   /** \brief @b RSDEstimation estimates the Radius-based Surface Descriptor (minimal and maximal radius of the local surface's curves)
00108     * for a given point cloud dataset containing points and normals.
00109     *
00110     * @note If you use this code in any academic work, please cite:
00111     *
00112     * <ul>
00113     * <li> Z.C. Marton , D. Pangercic , N. Blodow , J. Kleinehellefort, M. Beetz
00114     *      General 3D Modelling of Novel Objects from a Single View
00115     *      In Proceedings of the 2010 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)
00116     *      Taipei, Taiwan, October 18-22, 2010
00117     * </li>
00118     * <li> Z.C. Marton, D. Pangercic, N. Blodow, Michael Beetz.
00119     *      Combined 2D-3D Categorization and Classification for Multimodal Perception Systems.
00120     *      In The International Journal of Robotics Research, Sage Publications
00121     *      pages 1378--1402, Volume 30, Number 11, September 2011.
00122     * </li>
00123     * </ul>
00124     *
00125     * @note The code is stateful as we do not expect this class to be multicore parallelized.
00126     * \author Zoltan-Csaba Marton
00127     * \ingroup features
00128     */
00129   template <typename PointInT, typename PointNT, typename PointOutT>
00130   class RSDEstimation : public FeatureFromNormals<PointInT, PointNT, PointOutT>
00131   {
00132     public:
00133       using Feature<PointInT, PointOutT>::feature_name_;
00134       using Feature<PointInT, PointOutT>::getClassName;
00135       using Feature<PointInT, PointOutT>::indices_;
00136       using Feature<PointInT, PointOutT>::search_radius_;
00137       using Feature<PointInT, PointOutT>::search_parameter_;
00138       using Feature<PointInT, PointOutT>::surface_;
00139       using FeatureFromNormals<PointInT, PointNT, PointOutT>::normals_;
00140 
00141       typedef typename Feature<PointInT, PointOutT>::PointCloudOut PointCloudOut;
00142       typedef typename Feature<PointInT, PointOutT>::PointCloudIn  PointCloudIn;
00143 
00144       typedef typename boost::shared_ptr<RSDEstimation<PointInT, PointNT, PointOutT> > Ptr;
00145       typedef typename boost::shared_ptr<const RSDEstimation<PointInT, PointNT, PointOutT> > ConstPtr;
00146 
00147 
00148       /** \brief Empty constructor. */
00149       RSDEstimation () : nr_subdiv_ (5), plane_radius_ (0.2), save_histograms_ (false)
00150       {
00151         feature_name_ = "RadiusSurfaceDescriptor";
00152       };
00153 
00154       /** \brief Set the number of subdivisions for the considered distance interval.
00155         * \param[in] nr_subdiv the number of subdivisions
00156         */
00157       inline void 
00158       setNrSubdivisions (int nr_subdiv) { nr_subdiv_ = nr_subdiv; }
00159 
00160       /** \brief Get the number of subdivisions for the considered distance interval. */
00161       inline int 
00162       getNrSubdivisions () const { return (nr_subdiv_); }
00163 
00164       /** \brief Set the maximum radius, above which everything can be considered planar.
00165         * \note the order of magnitude should be around 10-20 times the search radius (0.2 works well for typical datasets).
00166         * \note on accurate 3D data (e.g. openni sernsors) a search radius as low as 0.01 still gives good results.
00167         * \param[in] plane_radius the new plane radius
00168         */
00169       inline void 
00170       setPlaneRadius (double plane_radius) { plane_radius_ = plane_radius; }
00171 
00172       /** \brief Get the maximum radius, above which everything can be considered planar. */
00173       inline double 
00174       getPlaneRadius () const { return (plane_radius_); }
00175 
00176       /** \brief Disables the setting of the number of k nearest neighbors to use for the feature estimation. */
00177       inline void 
00178       setKSearch (int) 
00179       {
00180         PCL_ERROR ("[pcl::%s::setKSearch] RSD does not work with k nearest neighbor search. Use setRadiusSearch() instead!\n", getClassName ().c_str ());
00181       }
00182 
00183       /** \brief Set whether the full distance-angle histograms should be saved.
00184         * @note Obtain the list of histograms by getHistograms ()
00185         * \param[in] save set to true if histograms should be saved
00186         */
00187       inline void
00188       setSaveHistograms (bool save) { save_histograms_ = save; }
00189 
00190       /** \brief Returns whether the full distance-angle histograms are being saved. */
00191       inline bool
00192       getSaveHistograms () const { return (save_histograms_); }
00193 
00194       /** \brief Returns a pointer to the list of full distance-angle histograms for all points. */
00195       inline boost::shared_ptr<std::vector<Eigen::MatrixXf, Eigen::aligned_allocator<Eigen::MatrixXf> > >
00196       getHistograms () const { return (histograms_); }
00197 
00198     protected:
00199 
00200       /** \brief Estimate the estimates the Radius-based Surface Descriptor (RSD) at a set of points given by
00201         * <setInputCloud (), setIndices ()> using the surface in setSearchSurface () and the spatial locator in
00202         * setSearchMethod ()
00203         * \param output the resultant point cloud model dataset that contains the RSD feature estimates (r_min and r_max values)
00204         */
00205       void 
00206       computeFeature (PointCloudOut &output);
00207 
00208       /** \brief The list of full distance-angle histograms for all points. */
00209       boost::shared_ptr<std::vector<Eigen::MatrixXf, Eigen::aligned_allocator<Eigen::MatrixXf> > > histograms_;
00210 
00211     private:
00212       /** \brief The number of subdivisions for the considered distance interval. */
00213       int nr_subdiv_;
00214 
00215       /** \brief The maximum radius, above which everything can be considered planar. */
00216       double plane_radius_;
00217 
00218       /** \brief Signals whether the full distance-angle histograms are being saved. */
00219       bool save_histograms_;
00220 
00221     public:
00222       EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00223   };
00224 }
00225 
00226 #ifdef PCL_NO_PRECOMPILE
00227 #include <pcl/features/impl/rsd.hpp>
00228 #endif
00229 
00230 #endif  //#ifndef PCL_RSD_H_