Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/filters/include/pcl/filters/passthrough.h
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-2012, Willow Garage, Inc.
00006  *
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of the copyright holder(s) nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  * $Id$
00037  *
00038  */
00039 
00040 #ifndef PCL_FILTERS_PASSTHROUGH_H_
00041 #define PCL_FILTERS_PASSTHROUGH_H_
00042 
00043 #include <pcl/filters/filter_indices.h>
00044 
00045 namespace pcl
00046 {
00047   /** \brief @b PassThrough passes points in a cloud based on constraints for one particular field of the point type.
00048     * \details Iterates through the entire input once, automatically filtering non-finite points and the points outside
00049     * the interval specified by setFilterLimits(), which applies only to the field specified by setFilterFieldName().
00050     * <br><br>
00051     * Usage example:
00052     * \code
00053     * pcl::PassThrough<PointType> ptfilter (true); // Initializing with true will allow us to extract the removed indices
00054     * ptfilter.setInputCloud (cloud_in);
00055     * ptfilter.setFilterFieldName ("x");
00056     * ptfilter.setFilterLimits (0.0, 1000.0);
00057     * ptfilter.filter (*indices_x);
00058     * // The indices_x array indexes all points of cloud_in that have x between 0.0 and 1000.0
00059     * indices_rem = ptfilter.getRemovedIndices ();
00060     * // The indices_rem array indexes all points of cloud_in that have x smaller than 0.0 or larger than 1000.0
00061     * // and also indexes all non-finite points of cloud_in
00062     * ptfilter.setIndices (indices_x);
00063     * ptfilter.setFilterFieldName ("z");
00064     * ptfilter.setFilterLimits (-10.0, 10.0);
00065     * ptfilter.setNegative (true);
00066     * ptfilter.filter (*indices_xz);
00067     * // The indices_xz array indexes all points of cloud_in that have x between 0.0 and 1000.0 and z larger than 10.0 or smaller than -10.0
00068     * ptfilter.setIndices (indices_xz);
00069     * ptfilter.setFilterFieldName ("intensity");
00070     * ptfilter.setFilterLimits (FLT_MIN, 0.5);
00071     * ptfilter.setNegative (false);
00072     * ptfilter.filter (*cloud_out);
00073     * // The resulting cloud_out contains all points of cloud_in that are finite and have:
00074     * // x between 0.0 and 1000.0, z larger than 10.0 or smaller than -10.0 and intensity smaller than 0.5.
00075     * \endcode
00076     * \author Radu Bogdan Rusu
00077     * \ingroup filters
00078     */
00079   template <typename PointT>
00080   class PassThrough : public FilterIndices<PointT>
00081   {
00082     protected:
00083       typedef typename FilterIndices<PointT>::PointCloud PointCloud;
00084       typedef typename PointCloud::Ptr PointCloudPtr;
00085       typedef typename PointCloud::ConstPtr PointCloudConstPtr;
00086       typedef typename pcl::traits::fieldList<PointT>::type FieldList;
00087 
00088     public:
00089 
00090       typedef boost::shared_ptr< PassThrough<PointT> > Ptr;
00091       typedef boost::shared_ptr< const PassThrough<PointT> > ConstPtr;
00092 
00093 
00094       /** \brief Constructor.
00095         * \param[in] extract_removed_indices Set to true if you want to be able to extract the indices of points being removed (default = false).
00096         */
00097       PassThrough (bool extract_removed_indices = false) :
00098         FilterIndices<PointT>::FilterIndices (extract_removed_indices),
00099         filter_field_name_ (""),
00100         filter_limit_min_ (FLT_MIN),
00101         filter_limit_max_ (FLT_MAX)
00102       {
00103         filter_name_ = "PassThrough";
00104       }
00105 
00106       /** \brief Provide the name of the field to be used for filtering data.
00107         * \details In conjunction with setFilterLimits(), points having values outside this interval for this field will be discarded.
00108         * \param[in] field_name The name of the field that will be used for filtering.
00109         */
00110       inline void
00111       setFilterFieldName (const std::string &field_name)
00112       {
00113         filter_field_name_ = field_name;
00114       }
00115 
00116       /** \brief Retrieve the name of the field to be used for filtering data.
00117         * \return The name of the field that will be used for filtering.
00118         */
00119       inline std::string const
00120       getFilterFieldName ()
00121       {
00122         return (filter_field_name_);
00123       }
00124 
00125       /** \brief Set the numerical limits for the field for filtering data.
00126         * \details In conjunction with setFilterFieldName(), points having values outside this interval for this field will be discarded.
00127         * \param[in] limit_min The minimum allowed field value (default = FLT_MIN).
00128         * \param[in] limit_max The maximum allowed field value (default = FLT_MAX).
00129         */
00130       inline void
00131       setFilterLimits (const float &limit_min, const float &limit_max)
00132       {
00133         filter_limit_min_ = limit_min;
00134         filter_limit_max_ = limit_max;
00135       }
00136 
00137       /** \brief Get the numerical limits for the field for filtering data.
00138         * \param[out] limit_min The minimum allowed field value (default = FLT_MIN).
00139         * \param[out] limit_max The maximum allowed field value (default = FLT_MAX).
00140         */
00141       inline void
00142       getFilterLimits (float &limit_min, float &limit_max)
00143       {
00144         limit_min = filter_limit_min_;
00145         limit_max = filter_limit_max_;
00146       }
00147 
00148       /** \brief Set to true if we want to return the data outside the interval specified by setFilterLimits (min, max)
00149         * Default: false.
00150         * \warning This method will be removed in the future. Use setNegative() instead.
00151         * \param[in] limit_negative return data inside the interval (false) or outside (true)
00152         */
00153       inline void
00154       setFilterLimitsNegative (const bool limit_negative)
00155       {
00156         negative_ = limit_negative;
00157       }
00158 
00159       /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false). 
00160         * \warning This method will be removed in the future. Use getNegative() instead.
00161         * \param[out] limit_negative true if data \b outside the interval [min; max] is to be returned, false otherwise
00162         */
00163       inline void
00164       getFilterLimitsNegative (bool &limit_negative)
00165       {
00166         limit_negative = negative_;
00167       }
00168 
00169       /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false). 
00170         * \warning This method will be removed in the future. Use getNegative() instead.
00171         * \return true if data \b outside the interval [min; max] is to be returned, false otherwise
00172         */
00173       inline bool
00174       getFilterLimitsNegative ()
00175       {
00176         return (negative_);
00177       }
00178 
00179     protected:
00180       using PCLBase<PointT>::input_;
00181       using PCLBase<PointT>::indices_;
00182       using Filter<PointT>::filter_name_;
00183       using Filter<PointT>::getClassName;
00184       using FilterIndices<PointT>::negative_;
00185       using FilterIndices<PointT>::keep_organized_;
00186       using FilterIndices<PointT>::user_filter_value_;
00187       using FilterIndices<PointT>::extract_removed_indices_;
00188       using FilterIndices<PointT>::removed_indices_;
00189 
00190       /** \brief Filtered results are stored in a separate point cloud.
00191         * \param[out] output The resultant point cloud.
00192         */
00193       void
00194       applyFilter (PointCloud &output);
00195 
00196       /** \brief Filtered results are indexed by an indices array.
00197         * \param[out] indices The resultant indices.
00198         */
00199       void
00200       applyFilter (std::vector<int> &indices)
00201       {
00202         applyFilterIndices (indices);
00203       }
00204 
00205       /** \brief Filtered results are indexed by an indices array.
00206         * \param[out] indices The resultant indices.
00207         */
00208       void
00209       applyFilterIndices (std::vector<int> &indices);
00210 
00211     private:
00212       /** \brief The name of the field that will be used for filtering. */
00213       std::string filter_field_name_;
00214 
00215       /** \brief The minimum allowed field value (default = FLT_MIN). */
00216       float filter_limit_min_;
00217 
00218       /** \brief The maximum allowed field value (default = FLT_MIN). */
00219       float filter_limit_max_;
00220   };
00221 
00222   ////////////////////////////////////////////////////////////////////////////////////////////
00223   /** \brief PassThrough uses the base Filter class methods to pass through all data that satisfies the user given
00224     * constraints.
00225     * \author Radu B. Rusu
00226     * \ingroup filters
00227     */
00228   template<>
00229   class PCL_EXPORTS PassThrough<pcl::PCLPointCloud2> : public Filter<pcl::PCLPointCloud2>
00230   {
00231     typedef pcl::PCLPointCloud2 PCLPointCloud2;
00232     typedef PCLPointCloud2::Ptr PCLPointCloud2Ptr;
00233     typedef PCLPointCloud2::ConstPtr PCLPointCloud2ConstPtr;
00234 
00235     using Filter<pcl::PCLPointCloud2>::removed_indices_;
00236     using Filter<pcl::PCLPointCloud2>::extract_removed_indices_;
00237 
00238     public:
00239       /** \brief Constructor. */
00240       PassThrough (bool extract_removed_indices = false) :
00241         Filter<pcl::PCLPointCloud2>::Filter (extract_removed_indices), keep_organized_ (false),
00242         user_filter_value_ (std::numeric_limits<float>::quiet_NaN ()),
00243         filter_field_name_ (""), filter_limit_min_ (-FLT_MAX), filter_limit_max_ (FLT_MAX),
00244         filter_limit_negative_ (false)
00245       {
00246         filter_name_ = "PassThrough";
00247       }
00248 
00249       /** \brief Set whether the filtered points should be kept and set to the
00250         * value given through \a setUserFilterValue (default: NaN), or removed
00251         * from the PointCloud, thus potentially breaking its organized
00252         * structure. By default, points are removed.
00253         *
00254         * \param[in] val set to true whether the filtered points should be kept and
00255         * set to a given user value (default: NaN)
00256         */
00257       inline void
00258       setKeepOrganized (bool val)
00259       {
00260         keep_organized_ = val;
00261       }
00262 
00263       /** \brief Obtain the value of the internal \a keep_organized_ parameter. */
00264       inline bool
00265       getKeepOrganized ()
00266       {
00267         return (keep_organized_);
00268       }
00269 
00270       /** \brief Provide a value that the filtered points should be set to
00271         * instead of removing them.  Used in conjunction with \a
00272         * setKeepOrganized ().
00273         * \param[in] val the user given value that the filtered point dimensions should be set to
00274         */
00275       inline void
00276       setUserFilterValue (float val)
00277       {
00278         user_filter_value_ = val;
00279       }
00280 
00281       /** \brief Provide the name of the field to be used for filtering data. In conjunction with  \a setFilterLimits,
00282         * points having values outside this interval will be discarded.
00283         * \param[in] field_name the name of the field that contains values used for filtering
00284         */
00285       inline void
00286       setFilterFieldName (const std::string &field_name)
00287       {
00288         filter_field_name_ = field_name;
00289       }
00290 
00291       /** \brief Get the name of the field used for filtering. */
00292       inline std::string const
00293       getFilterFieldName ()
00294       {
00295         return (filter_field_name_);
00296       }
00297 
00298       /** \brief Set the field filter limits. All points having field values outside this interval will be discarded.
00299         * \param[in] limit_min the minimum allowed field value
00300         * \param[in] limit_max the maximum allowed field value
00301         */
00302       inline void
00303       setFilterLimits (const double &limit_min, const double &limit_max)
00304       {
00305         filter_limit_min_ = limit_min;
00306         filter_limit_max_ = limit_max;
00307       }
00308 
00309       /** \brief Get the field filter limits (min/max) set by the user. The default values are -FLT_MAX, FLT_MAX. 
00310         * \param[out] limit_min the minimum allowed field value
00311         * \param[out] limit_max the maximum allowed field value
00312         */
00313       inline void
00314       getFilterLimits (double &limit_min, double &limit_max)
00315       {
00316         limit_min = filter_limit_min_;
00317         limit_max = filter_limit_max_;
00318       }
00319 
00320       /** \brief Set to true if we want to return the data outside the interval specified by setFilterLimits (min, max).
00321         * Default: false.
00322         * \param[in] limit_negative return data inside the interval (false) or outside (true)
00323         */
00324       inline void
00325       setFilterLimitsNegative (const bool limit_negative)
00326       {
00327         filter_limit_negative_ = limit_negative;
00328       }
00329 
00330       /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false). 
00331         * \param[out] limit_negative true if data \b outside the interval [min; max] is to be returned, false otherwise
00332         */
00333       inline void
00334       getFilterLimitsNegative (bool &limit_negative)
00335       {
00336         limit_negative = filter_limit_negative_;
00337       }
00338 
00339       /** \brief Get whether the data outside the interval (min/max) is to be returned (true) or inside (false). 
00340         * \return true if data \b outside the interval [min; max] is to be returned, false otherwise
00341         */
00342       inline bool
00343       getFilterLimitsNegative ()
00344       {
00345         return (filter_limit_negative_);
00346       }
00347 
00348     protected:
00349       void
00350       applyFilter (PCLPointCloud2 &output);
00351 
00352     private:
00353       /** \brief Keep the structure of the data organized, by setting the
00354         * filtered points to the a user given value (NaN by default). 
00355         */
00356       bool keep_organized_;
00357 
00358       /** \brief User given value to be set to any filtered point. Casted to
00359         * the correct field type. 
00360         */
00361       float user_filter_value_;
00362 
00363       /** \brief The desired user filter field name. */
00364       std::string filter_field_name_;
00365 
00366       /** \brief The minimum allowed filter value a point will be considered from. */
00367       double filter_limit_min_;
00368 
00369       /** \brief The maximum allowed filter value a point will be considered from. */
00370       double filter_limit_max_;
00371 
00372       /** \brief Set to true if we want to return the data outside (\a filter_limit_min_;\a filter_limit_max_). Default: false. */
00373       bool filter_limit_negative_;
00374 
00375   };
00376 }
00377 
00378 #ifdef PCL_NO_PRECOMPILE
00379 #include <pcl/filters/impl/passthrough.hpp>
00380 #endif
00381 
00382 #endif  // PCL_FILTERS_PASSTHROUGH_H_
00383