Point Cloud Library (PCL)  1.14.1-dev
radius_outlier_removal.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2012, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id$
37  *
38  */
39 
40 #pragma once
41 
42 #include <pcl/filters/filter_indices.h>
43 #include <pcl/search/search.h> // for Search, Search<>::Ptr
44 
45 namespace pcl
46 {
47  /** \brief @b RadiusOutlierRemoval filters points in a cloud based on the number of neighbors they have.
48  * \details Iterates through the entire input once, and for each point, retrieves the number of neighbors within a certain radius.
49  * The point will be considered an outlier if it has too few neighbors, as determined by setMinNeighborsInRadius().
50  * The radius can be changed using setRadiusSearch().
51  * <br>
52  * The neighbors found for each query point will be found amongst ALL points of setInputCloud(), not just those indexed by setIndices().
53  * The setIndices() method only indexes the points that will be iterated through as search query points.
54  * <br><br>
55  * Usage example:
56  * \code
57  * pcl::RadiusOutlierRemoval<PointType> rorfilter (true); // Initializing with true will allow us to extract the removed indices
58  * rorfilter.setInputCloud (cloud_in);
59  * rorfilter.setRadiusSearch (0.1);
60  * rorfilter.setMinNeighborsInRadius (5);
61  * rorfilter.setNegative (true);
62  * rorfilter.filter (*cloud_out);
63  * // The resulting cloud_out contains all points of cloud_in that have 4 or less neighbors within the 0.1 search radius
64  * indices_rem = rorfilter.getRemovedIndices ();
65  * // The indices_rem array indexes all points of cloud_in that have 5 or more neighbors within the 0.1 search radius
66  * \endcode
67  * \sa StatisticalOutlierRemoval
68  * \author Radu Bogdan Rusu
69  * \ingroup filters
70  */
71  template<typename PointT>
72  class RadiusOutlierRemoval : public FilterIndices<PointT>
73  {
74  protected:
76  using PointCloudPtr = typename PointCloud::Ptr;
79 
80  public:
81 
82  using Ptr = shared_ptr<RadiusOutlierRemoval<PointT> >;
83  using ConstPtr = shared_ptr<const RadiusOutlierRemoval<PointT> >;
84 
85 
86  /** \brief Constructor.
87  * \param[in] extract_removed_indices Set to true if you want to be able to extract the indices of points being removed (default = false).
88  */
89  RadiusOutlierRemoval (bool extract_removed_indices = false) :
90  FilterIndices<PointT> (extract_removed_indices),
91  searcher_ ()
92  {
93  filter_name_ = "RadiusOutlierRemoval";
94  }
95 
96  /** \brief Set the radius of the sphere that will determine which points are neighbors.
97  * \details The number of points within this distance from the query point will need to be equal or greater
98  * than setMinNeighborsInRadius() in order to be classified as an inlier point (i.e. will not be filtered).
99  * \param[in] radius The radius of the sphere for nearest neighbor searching.
100  */
101  inline void
102  setRadiusSearch (double radius)
103  {
104  search_radius_ = radius;
105  }
106 
107  /** \brief Get the radius of the sphere that will determine which points are neighbors.
108  * \details The number of points within this distance from the query point will need to be equal or greater
109  * than setMinNeighborsInRadius() in order to be classified as an inlier point (i.e. will not be filtered).
110  * \return The radius of the sphere for nearest neighbor searching.
111  */
112  inline double
114  {
115  return (search_radius_);
116  }
117 
118  /** \brief Set the number of neighbors that need to be present in order to be classified as an inlier.
119  * \details The number of points within setRadiusSearch() from the query point will need to be equal or greater
120  * than this number in order to be classified as an inlier point (i.e. will not be filtered).
121  * \param min_pts The minimum number of neighbors (default = 1).
122  */
123  inline void
125  {
126  min_pts_radius_ = min_pts;
127  }
128 
129  /** \brief Get the number of neighbors that need to be present in order to be classified as an inlier.
130  * \details The number of points within setRadiusSearch() from the query point will need to be equal or greater
131  * than this number in order to be classified as an inlier point (i.e. will not be filtered).
132  * \return The minimum number of neighbors (default = 1).
133  */
134  inline int
136  {
137  return (min_pts_radius_);
138  }
139 
140  /** \brief Provide a pointer to the search object.
141  * Calling this is optional. If not called, the search method will be chosen automatically.
142  * \param[in] searcher a pointer to the spatial search object.
143  */
144  inline void
145  setSearchMethod (const SearcherPtr &searcher) { searcher_ = searcher; }
146 
147  /** \brief Set the number of threads to use.
148  * \param nr_threads the number of hardware threads to use (0 sets the value back
149  * to automatic)
150  */
151  void
152  setNumberOfThreads(unsigned int nr_threads = 0)
153  {
154 #ifdef _OPENMP
155  num_threads_ = nr_threads != 0 ? nr_threads : omp_get_num_procs();
156 #else
157  if (num_threads_ != 1) {
158  PCL_WARN("OpenMP is not available. Keeping number of threads unchanged at 1\n");
159  }
160  num_threads_ = 1;
161 #endif
162  }
163 
164  protected:
174 
175  /** \brief Filtered results are indexed by an indices array.
176  * \param[out] indices The resultant indices.
177  */
178  void
179  applyFilter (Indices &indices) override
180  {
181  applyFilterIndices (indices);
182  }
183 
184  /** \brief Filtered results are indexed by an indices array.
185  * \param[out] indices The resultant indices.
186  */
187  void
188  applyFilterIndices (Indices &indices);
189 
190  private:
191  /** \brief A pointer to the spatial search object. */
192  SearcherPtr searcher_;
193 
194  /** \brief The nearest neighbors search radius for each point. */
195  double search_radius_{0.0};
196 
197  /** \brief The minimum number of neighbors that a point needs to have in the given search radius to be considered an inlier. */
198  int min_pts_radius_{1};
199 
200  /**
201  * @brief Number of threads used during filtering
202  */
203  int num_threads_{1};
204  };
205 
206  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
207  /** \brief @b RadiusOutlierRemoval is a simple filter that removes outliers if the number of neighbors in a certain
208  * search radius is smaller than a given K.
209  * \author Radu Bogdan Rusu
210  * \ingroup filters
211  */
212  template<>
213  class PCL_EXPORTS RadiusOutlierRemoval<pcl::PCLPointCloud2> : public FilterIndices<pcl::PCLPointCloud2>
214  {
217 
220 
222  using KdTreePtr = pcl::search::Search<pcl::PointXYZ>::Ptr;
223 
227 
228  public:
229  /** \brief Empty constructor. */
230  RadiusOutlierRemoval (bool extract_removed_indices = false) :
231  FilterIndices<pcl::PCLPointCloud2>::FilterIndices (extract_removed_indices)
232  {
233  filter_name_ = "RadiusOutlierRemoval";
234  }
235 
236  /** \brief Set the sphere radius that is to be used for determining the k-nearest neighbors for filtering.
237  * \param radius the sphere radius that is to contain all k-nearest neighbors
238  */
239  inline void
240  setRadiusSearch (double radius)
241  {
242  search_radius_ = radius;
243  }
244 
245  /** \brief Get the sphere radius used for determining the k-nearest neighbors. */
246  inline double
248  {
249  return (search_radius_);
250  }
251 
252  /** \brief Set the minimum number of neighbors that a point needs to have in the given search radius in order to
253  * be considered an inlier (i.e., valid).
254  * \param min_pts the minimum number of neighbors
255  */
256  inline void
258  {
259  min_pts_radius_ = min_pts;
260  }
261 
262  /** \brief Get the minimum number of neighbors that a point needs to have in the given search radius to be
263  * considered an inlier and avoid being filtered.
264  */
265  inline double
267  {
268  return (min_pts_radius_);
269  }
270 
271  protected:
272  /** \brief The nearest neighbors search radius for each point. */
273  double search_radius_{0.0};
274 
275  /** \brief The minimum number of neighbors that a point needs to have in the given search radius to be considered
276  * an inlier.
277  */
278  int min_pts_radius_{1};
279 
280  /** \brief A pointer to the spatial search object. */
281  KdTreePtr searcher_;
282 
283  void
284  applyFilter (PCLPointCloud2 &output) override;
285 
286  void
287  applyFilter (Indices &indices) override;
288  };
289 }
290 
291 #ifdef PCL_NO_PRECOMPILE
292 #include <pcl/filters/impl/radius_outlier_removal.hpp>
293 #endif
Filter represents the base filter class.
Definition: filter.h:81
shared_ptr< Filter< PointT > > Ptr
Definition: filter.h:83
shared_ptr< const Filter< PointT > > ConstPtr
Definition: filter.h:84
std::string filter_name_
The filter name.
Definition: filter.h:158
FilterIndices represents the base class for filters that are about binary point removal.
PCLPointCloud2::Ptr PCLPointCloud2Ptr
Definition: pcl_base.h:185
PCLPointCloud2::ConstPtr PCLPointCloud2ConstPtr
Definition: pcl_base.h:186
PCL base class.
Definition: pcl_base.h:70
typename PointCloud::Ptr PointCloudPtr
Definition: pcl_base.h:73
typename PointCloud::ConstPtr PointCloudConstPtr
Definition: pcl_base.h:74
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: point_cloud.h:173
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:413
shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:414
void applyFilter(Indices &indices) override
Abstract filter method for point cloud indices.
double getRadiusSearch()
Get the sphere radius used for determining the k-nearest neighbors.
double getMinNeighborsInRadius()
Get the minimum number of neighbors that a point needs to have in the given search radius to be consi...
void setRadiusSearch(double radius)
Set the sphere radius that is to be used for determining the k-nearest neighbors for filtering.
KdTreePtr searcher_
A pointer to the spatial search object.
RadiusOutlierRemoval(bool extract_removed_indices=false)
Empty constructor.
void applyFilter(PCLPointCloud2 &output) override
Abstract filter method for point cloud.
void setMinNeighborsInRadius(int min_pts)
Set the minimum number of neighbors that a point needs to have in the given search radius in order to...
RadiusOutlierRemoval filters points in a cloud based on the number of neighbors they have.
void applyFilterIndices(Indices &indices)
Filtered results are indexed by an indices array.
int getMinNeighborsInRadius()
Get the number of neighbors that need to be present in order to be classified as an inlier.
void applyFilter(Indices &indices) override
Filtered results are indexed by an indices array.
void setMinNeighborsInRadius(int min_pts)
Set the number of neighbors that need to be present in order to be classified as an inlier.
void setRadiusSearch(double radius)
Set the radius of the sphere that will determine which points are neighbors.
RadiusOutlierRemoval(bool extract_removed_indices=false)
Constructor.
typename pcl::search::Search< PointT >::Ptr SearcherPtr
double getRadiusSearch()
Get the radius of the sphere that will determine which points are neighbors.
void setSearchMethod(const SearcherPtr &searcher)
Provide a pointer to the search object.
void setNumberOfThreads(unsigned int nr_threads=0)
Set the number of threads to use.
shared_ptr< pcl::search::Search< PointT > > Ptr
Definition: search.h:81
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:133
#define PCL_EXPORTS
Definition: pcl_macros.h:325
shared_ptr< ::pcl::PCLPointCloud2 > Ptr
shared_ptr< const ::pcl::PCLPointCloud2 > ConstPtr
A point structure representing Euclidean xyz coordinates, and the RGB color.