Point Cloud Library (PCL)  1.15.1
statistical_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
44 
45 namespace pcl
46 {
47  /** \brief @b StatisticalOutlierRemoval uses point neighborhood statistics to filter outlier data.
48  * \details The algorithm iterates through the entire input twice:
49  * During the first iteration it will compute the average distance that each point has to its nearest k neighbors.
50  * The value of k can be set using setMeanK().
51  * Next, the mean and standard deviation of all these distances are computed in order to determine a distance threshold.
52  * The distance threshold will be equal to: mean + stddev_mult * stddev.
53  * The multiplier for the standard deviation can be set using setStddevMulThresh().
54  * During the next iteration the points will be classified as inlier or outlier if their average neighbor distance is below or above this threshold respectively.
55  * <br>
56  * The neighbors found for each query point will be found amongst ALL points of setInputCloud(), not just those indexed by setIndices().
57  * The setIndices() method only indexes the points that will be iterated through as search query points.
58  * <br><br>
59  * For more information:
60  * - R. B. Rusu, Z. C. Marton, N. Blodow, M. Dolha, and M. Beetz.
61  * Towards 3D Point Cloud Based Object Maps for Household Environments
62  * Robotics and Autonomous Systems Journal (Special Issue on Semantic Knowledge), 2008.
63  * <br><br>
64  * Usage example:
65  * \code
66  * pcl::StatisticalOutlierRemoval<PointType> sorfilter (true); // Initializing with true will allow us to extract the removed indices
67  * sorfilter.setInputCloud (cloud_in);
68  * sorfilter.setMeanK (8);
69  * sorfilter.setStddevMulThresh (1.0);
70  * sorfilter.filter (*cloud_out);
71  * // The resulting cloud_out contains all points of cloud_in that have an average distance to their 8 nearest neighbors that is below the computed threshold
72  * // Using a standard deviation multiplier of 1.0 and assuming the average distances are normally distributed there is a 84.1% chance that a point will be an inlier
73  * indices_rem = sorfilter.getRemovedIndices ();
74  * // The indices_rem array indexes all points of cloud_in that are outliers
75  * \endcode
76  * \sa RadiusOutlierRemoval
77  * \author Radu Bogdan Rusu
78  * \ingroup filters
79  */
80  template<typename PointT>
82  {
83  protected:
85  using PointCloudPtr = typename PointCloud::Ptr;
88 
89  public:
90 
91  using Ptr = shared_ptr<StatisticalOutlierRemoval<PointT> >;
92  using ConstPtr = shared_ptr<const StatisticalOutlierRemoval<PointT> >;
93 
94 
95  /** \brief Constructor.
96  * \param[in] extract_removed_indices Set to true if you want to be able to extract the indices of points being removed (default = false).
97  */
98  StatisticalOutlierRemoval (bool extract_removed_indices = false) :
99  FilterIndices<PointT> (extract_removed_indices),
100  searcher_ ()
101  {
102  filter_name_ = "StatisticalOutlierRemoval";
103  }
104 
105  /** \brief Set the number of nearest neighbors to use for mean distance estimation.
106  * \param[in] nr_k The number of points to use for mean distance estimation.
107  */
108  inline void
109  setMeanK (int nr_k)
110  {
111  mean_k_ = nr_k;
112  }
113 
114  /** \brief Get the number of nearest neighbors to use for mean distance estimation.
115  * \return The number of points to use for mean distance estimation.
116  */
117  inline int
119  {
120  return (mean_k_);
121  }
122 
123  /** \brief Set the standard deviation multiplier for the distance threshold calculation.
124  * \details The distance threshold will be equal to: mean + stddev_mult * stddev.
125  * Points will be classified as inlier or outlier if their average neighbor distance is below or above this threshold respectively.
126  * \param[in] stddev_mult The standard deviation multiplier.
127  */
128  inline void
129  setStddevMulThresh (double stddev_mult)
130  {
131  std_mul_ = stddev_mult;
132  }
133 
134  /** \brief Get the standard deviation multiplier for the distance threshold calculation.
135  * \details The distance threshold will be equal to: mean + stddev_mult * stddev.
136  * Points will be classified as inlier or outlier if their average neighbor distance is below or above this threshold respectively.
137  */
138  inline double
140  {
141  return (std_mul_);
142  }
143 
144  /** \brief Provide a pointer to the search object.
145  * Calling this is optional. If not called, the search method will be chosen automatically.
146  * \param[in] searcher a pointer to the spatial search object.
147  */
148  inline void
149  setSearchMethod (const SearcherPtr &searcher) { searcher_ = searcher; }
150  protected:
160 
161  /** \brief Filtered results are indexed by an indices array.
162  * \param[out] indices The resultant indices.
163  */
164  void
165  applyFilter (Indices &indices) override
166  {
167  applyFilterIndices (indices);
168  }
169 
170  /** \brief Filtered results are indexed by an indices array.
171  * \param[out] indices The resultant indices.
172  */
173  void
174  applyFilterIndices (Indices &indices);
175 
176  private:
177  /** \brief A pointer to the spatial search object. */
178  SearcherPtr searcher_;
179 
180  /** \brief The number of points to use for mean distance estimation. */
181  int mean_k_{1};
182 
183  /** \brief Standard deviations threshold (i.e., points outside of
184  * \f$ \mu \pm \sigma \cdot std\_mul \f$ will be marked as outliers). */
185  double std_mul_{0.0};
186  };
187 
188  /** \brief @b StatisticalOutlierRemoval uses point neighborhood statistics to filter outlier data. For more
189  * information check:
190  * - R. B. Rusu, Z. C. Marton, N. Blodow, M. Dolha, and M. Beetz.
191  * Towards 3D Point Cloud Based Object Maps for Household Environments
192  * Robotics and Autonomous Systems Journal (Special Issue on Semantic Knowledge), 2008.
193  *
194  * \author Radu Bogdan Rusu
195  * \ingroup filters
196  */
197  template<>
198  class PCL_EXPORTS StatisticalOutlierRemoval<pcl::PCLPointCloud2> : public FilterIndices<pcl::PCLPointCloud2>
199  {
202 
205 
207  using KdTreePtr = pcl::search::Search<pcl::PointXYZ>::Ptr;
208 
212 
213  public:
214  /** \brief Empty constructor. */
215  StatisticalOutlierRemoval (bool extract_removed_indices = false) :
216  FilterIndices<pcl::PCLPointCloud2>::FilterIndices (extract_removed_indices)
217  {
218  filter_name_ = "StatisticalOutlierRemoval";
219  }
220 
221  /** \brief Set the number of points (k) to use for mean distance estimation
222  * \param nr_k the number of points to use for mean distance estimation
223  */
224  inline void
225  setMeanK (int nr_k)
226  {
227  mean_k_ = nr_k;
228  }
229 
230  /** \brief Get the number of points to use for mean distance estimation. */
231  inline int
233  {
234  return (mean_k_);
235  }
236 
237  /** \brief Set the standard deviation multiplier threshold. All points outside the
238  * \f[ \mu \pm \sigma \cdot std\_mul \f]
239  * will be considered outliers, where \f$ \mu \f$ is the estimated mean,
240  * and \f$ \sigma \f$ is the standard deviation.
241  * \param std_mul the standard deviation multiplier threshold
242  */
243  inline void
244  setStddevMulThresh (double std_mul)
245  {
246  std_mul_ = std_mul;
247  }
248 
249  /** \brief Get the standard deviation multiplier threshold as set by the user. */
250  inline double
252  {
253  return (std_mul_);
254  }
255 
256  protected:
257  /** \brief The number of points to use for mean distance estimation. */
258  int mean_k_{2};
259 
260  /** \brief Standard deviations threshold (i.e., points outside of
261  * \f$ \mu \pm \sigma \cdot std\_mul \f$ will be marked as outliers).
262  */
263  double std_mul_{0.0};
264 
265  /** \brief A pointer to the spatial search object. */
266  KdTreePtr tree_;
267 
268  void
269  applyFilter (Indices &indices) override;
270 
271  void
272  applyFilter (PCLPointCloud2 &output) override;
273 
274  /**
275  * \brief Compute the statistical values used in both applyFilter methods.
276  *
277  * This method tries to avoid duplicate code.
278  */
279  virtual void
280  generateStatistics (double& mean, double& variance, double& stddev, std::vector<float>& distances);
281  };
282 }
283 
284 #ifdef PCL_NO_PRECOMPILE
285 #include <pcl/filters/impl/statistical_outlier_removal.hpp>
286 #endif
void setMeanK(int nr_k)
Set the number of points (k) to use for mean distance estimation.
shared_ptr< ::pcl::PCLPointCloud2 > Ptr
void setSearchMethod(const SearcherPtr &searcher)
Provide a pointer to the search object.
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:414
void setStddevMulThresh(double std_mul)
Set the standard deviation multiplier threshold.
typename pcl::search::Search< PointT >::Ptr SearcherPtr
void applyFilter(Indices &indices) override
Filtered results are indexed by an indices array.
shared_ptr< const ::pcl::PCLPointCloud2 > ConstPtr
int getMeanK()
Get the number of nearest neighbors to use for mean distance estimation.
double getStddevMulThresh()
Get the standard deviation multiplier threshold as set by the user.
void setStddevMulThresh(double stddev_mult)
Set the standard deviation multiplier for the distance threshold calculation.
void setMeanK(int nr_k)
Set the number of nearest neighbors to use for mean distance estimation.
double getStddevMulThresh()
Get the standard deviation multiplier for the distance threshold calculation.
FilterIndices represents the base class for filters that are about binary point removal.
StatisticalOutlierRemoval uses point neighborhood statistics to filter outlier data.
StatisticalOutlierRemoval(bool extract_removed_indices=false)
Constructor.
Filter represents the base filter class.
Definition: filter.h:80
StatisticalOutlierRemoval(bool extract_removed_indices=false)
Empty constructor.
PCL base class.
Definition: pcl_base.h:69
typename PointCloud::Ptr PointCloudPtr
Definition: pcl_base.h:73
void applyFilterIndices(Indices &indices)
Filtered results are indexed by an indices array.
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:133
PointCloud represents the base class in PCL for storing collections of 3D points. ...
Definition: distances.h:55
shared_ptr< StatisticalOutlierRemoval< PointT > > Ptr
int getMeanK()
Get the number of points to use for mean distance estimation.
KdTreePtr tree_
A pointer to the spatial search object.
PCLPointCloud2::ConstPtr PCLPointCloud2ConstPtr
Definition: pcl_base.h:186
shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:415
shared_ptr< pcl::search::Search< PointT > > Ptr
Definition: search.h:81
std::string filter_name_
The filter name.
Definition: filter.h:158
shared_ptr< const Filter< PointT > > ConstPtr
Definition: filter.h:84
A point structure representing Euclidean xyz coordinates, and the RGB color.
PCLPointCloud2::Ptr PCLPointCloud2Ptr
Definition: pcl_base.h:185
typename PointCloud::ConstPtr PointCloudConstPtr
Definition: pcl_base.h:74