Point Cloud Library (PCL)  1.14.1-dev
uniform_sampling.hpp
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2009, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage, Inc. nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * $Id$
35  *
36  */
37 
38 #ifndef PCL_FILTERS_UNIFORM_SAMPLING_IMPL_H_
39 #define PCL_FILTERS_UNIFORM_SAMPLING_IMPL_H_
40 
41 #include <pcl/common/common.h>
42 #include <pcl/filters/uniform_sampling.h>
43 #include <pcl/common/point_tests.h>
44 
45 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46 template <typename PointT> void
48 {
49  // The arrays to be used
50  indices.resize (indices_->size ());
51  removed_indices_->resize (indices_->size ());
52 
53  int oii = 0, rii = 0; // oii = output indices iterator, rii = removed indices iterator
54 
55  Eigen::Vector4f min_p, max_p;
56  // Get the minimum and maximum dimensions
57  pcl::getMinMax3D<PointT>(*input_, min_p, max_p);
58 
59  // Compute the minimum and maximum bounding box values
60  min_b_[0] = static_cast<int> (std::floor (min_p[0] * inverse_leaf_size_[0]));
61  max_b_[0] = static_cast<int> (std::floor (max_p[0] * inverse_leaf_size_[0]));
62  min_b_[1] = static_cast<int> (std::floor (min_p[1] * inverse_leaf_size_[1]));
63  max_b_[1] = static_cast<int> (std::floor (max_p[1] * inverse_leaf_size_[1]));
64  min_b_[2] = static_cast<int> (std::floor (min_p[2] * inverse_leaf_size_[2]));
65  max_b_[2] = static_cast<int> (std::floor (max_p[2] * inverse_leaf_size_[2]));
66 
67  // Compute the number of divisions needed along all axis
68  div_b_ = max_b_ - min_b_ + Eigen::Vector4i::Ones ();
69  div_b_[3] = 0;
70 
71  // Clear the leaves
72  leaves_.clear ();
73 
74  // Set up the division multiplier
75  divb_mul_ = Eigen::Vector4i (1, div_b_[0], div_b_[0] * div_b_[1], 0);
76 
77  // First pass: build a set of leaves with the point index closest to the leaf center
78  for (const auto& cp : *indices_)
79  {
80  if (!input_->is_dense)
81  {
82  // Check if the point is invalid
83  if (!pcl::isXYZFinite ((*input_)[cp]))
84  {
85  if (extract_removed_indices_)
86  (*removed_indices_)[rii++] = cp;
87  continue;
88  }
89  }
90 
91  Eigen::Vector4i ijk = Eigen::Vector4i::Zero ();
92  ijk[0] = static_cast<int> (std::floor ((*input_)[cp].x * inverse_leaf_size_[0]));
93  ijk[1] = static_cast<int> (std::floor ((*input_)[cp].y * inverse_leaf_size_[1]));
94  ijk[2] = static_cast<int> (std::floor ((*input_)[cp].z * inverse_leaf_size_[2]));
95 
96  // Compute the leaf index
97  int idx = (ijk - min_b_).dot (divb_mul_);
98  Leaf& leaf = leaves_[idx];
99 
100  // Increment the count of points in this voxel
101  ++leaf.count;
102 
103  // First time we initialize the index
104  if (leaf.idx == -1)
105  {
106  leaf.idx = cp;
107  continue;
108  }
109 
110  // Compute the voxel center
111  Eigen::Vector4f voxel_center = (ijk.cast<float>() + Eigen::Vector4f::Constant(0.5)) * search_radius_;
112  voxel_center[3] = 0;
113  // Check to see if this point is closer to the leaf center than the previous one we saved
114  float diff_cur = ((*input_)[cp].getVector4fMap () - voxel_center).squaredNorm ();
115  float diff_prev = ((*input_)[leaf.idx].getVector4fMap () - voxel_center).squaredNorm ();
116 
117  // If current point is closer, copy its index instead
118  if (diff_cur < diff_prev)
119  {
120  if (extract_removed_indices_)
121  (*removed_indices_)[rii++] = leaf.idx;
122  leaf.idx = cp;
123  }
124  else
125  {
126  if (extract_removed_indices_)
127  (*removed_indices_)[rii++] = cp;
128  }
129  }
130  removed_indices_->resize(rii);
131 
132  // Second pass: go over all leaves and copy data
133  indices.resize (leaves_.size ());
134  for (const auto& leaf : leaves_)
135  {
136  if (leaf.second.count >= min_points_per_voxel_)
137  indices[oii++] = leaf.second.idx;
138  }
139 
140  indices.resize (oii);
141  if(negative_){
142  indices.swap(*removed_indices_);
143  }
144 }
145 
146 #define PCL_INSTANTIATE_UniformSampling(T) template class PCL_EXPORTS pcl::UniformSampling<T>;
147 
148 #endif // PCL_FILTERS_UNIFORM_SAMPLING_IMPL_H_
149 
void applyFilter(Indices &indices) override
Filtered results are indexed by an indices array.
Define standard C methods and C++ classes that are common to all methods.
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:133
constexpr bool isXYZFinite(const PointT &) noexcept
Definition: point_tests.h:125
Simple structure to hold an nD centroid and the number of points in a leaf.