39 #ifndef PCL_SEGMENTATION_APPROXIMATE_PROGRESSIVE_MORPHOLOGICAL_FILTER_HPP_
40 #define PCL_SEGMENTATION_APPROXIMATE_PROGRESSIVE_MORPHOLOGICAL_FILTER_HPP_
43 #include <pcl/common/io.h>
44 #include <pcl/common/point_tests.h>
45 #include <pcl/filters/morphological_filter.h>
46 #include <pcl/segmentation/approximate_progressive_morphological_filter.h>
47 #include <pcl/point_cloud.h>
51 template <
typename Po
intT>
55 template <
typename Po
intT>
59 template <
typename Po
intT>
void
62 bool segmentation_is_possible = initCompute ();
63 if (!segmentation_is_possible)
70 std::vector<float> height_thresholds;
71 std::vector<float> window_sizes;
72 std::vector<int> half_sizes;
74 float window_size = 0.0f;
76 while (window_size < max_window_size_)
79 int half_size = (exponential_) ? (
static_cast<int> (std::pow (
static_cast<float> (base_), iteration))) : ((iteration+1) * base_);
81 window_size = 2 * half_size + 1;
84 float height_threshold = (iteration == 0) ? (initial_distance_) : (slope_ * (window_size - window_sizes[iteration-1]) * cell_size_ + initial_distance_);
87 if (height_threshold > max_distance_)
88 height_threshold = max_distance_;
90 half_sizes.push_back (half_size);
91 window_sizes.push_back (window_size);
92 height_thresholds.push_back (height_threshold);
98 Eigen::Vector4f global_max, global_min;
99 pcl::getMinMax3D<PointT> (*input_, global_min, global_max);
101 float xextent = global_max.x () - global_min.x ();
102 float yextent = global_max.y () - global_min.y ();
104 int rows =
static_cast<int> (std::floor (yextent / cell_size_) + 1);
105 int cols =
static_cast<int> (std::floor (xextent / cell_size_) + 1);
107 Eigen::MatrixXf A (rows, cols);
108 A.setConstant (std::numeric_limits<float>::quiet_NaN ());
110 Eigen::MatrixXf Z (rows, cols);
111 Z.setConstant (std::numeric_limits<float>::quiet_NaN ());
113 Eigen::MatrixXf Zf (rows, cols);
114 Zf.setConstant (std::numeric_limits<float>::quiet_NaN ());
116 if (input_->is_dense) {
117 #pragma omp parallel for \
119 shared(A, global_min) \
120 num_threads(threads_)
121 for (
int i = 0; i < static_cast<int>(input_->size ()); ++i) {
123 const PointT& p = (*input_)[i];
124 int row = std::floor((p.y - global_min.y ()) / cell_size_);
125 int col = std::floor((p.x - global_min.x ()) / cell_size_);
127 if (p.z < A (row, col) || std::isnan (A (row, col)))
132 #pragma omp parallel for \
134 shared(A, global_min) \
135 num_threads(threads_)
136 for (
int i = 0; i < static_cast<int>(input_->size ()); ++i) {
138 const PointT& p = (*input_)[i];
141 int row = std::floor((p.y - global_min.y ()) / cell_size_);
142 int col = std::floor((p.x - global_min.x ()) / cell_size_);
144 if (p.z < A (row, col) || std::isnan (A (row, col)))
151 if (input_->is_dense) {
156 ground.reserve(indices_->size());
157 for (
const auto& index: *indices_)
159 ground.push_back(index);
163 for (std::size_t i = 0; i < window_sizes.size (); ++i)
165 PCL_DEBUG (
" Iteration %d (height threshold = %f, window size = %f, half size = %d)...",
166 i, height_thresholds[i], window_sizes[i], half_sizes[i]);
170 pcl::copyPointCloud<PointT> (*input_, ground, *cloud);
173 #pragma omp parallel for \
175 shared(A, cols, half_sizes, i, rows, Z) \
176 num_threads(threads_)
177 for (
int row = 0; row < rows; ++row)
180 rs = ((row - half_sizes[i]) < 0) ? 0 : row - half_sizes[i];
181 re = ((row + half_sizes[i]) > (rows-1)) ? (rows-1) : row + half_sizes[i];
183 for (
int col = 0; col < cols; ++col)
186 cs = ((col - half_sizes[i]) < 0) ? 0 : col - half_sizes[i];
187 ce = ((col + half_sizes[i]) > (cols-1)) ? (cols-1) : col + half_sizes[i];
189 float min_coeff = std::numeric_limits<float>::max ();
191 for (
int j = rs; j < (re + 1); ++j)
193 for (
int k = cs; k < (ce + 1); ++k)
195 if (A (j, k) != std::numeric_limits<float>::quiet_NaN ())
197 if (A (j, k) < min_coeff)
198 min_coeff = A (j, k);
203 if (min_coeff != std::numeric_limits<float>::max ())
204 Z(row, col) = min_coeff;
208 #pragma omp parallel for \
210 shared(cols, half_sizes, i, rows, Z, Zf) \
211 num_threads(threads_)
212 for (
int row = 0; row < rows; ++row)
215 rs = ((row - half_sizes[i]) < 0) ? 0 : row - half_sizes[i];
216 re = ((row + half_sizes[i]) > (rows-1)) ? (rows-1) : row + half_sizes[i];
218 for (
int col = 0; col < cols; ++col)
221 cs = ((col - half_sizes[i]) < 0) ? 0 : col - half_sizes[i];
222 ce = ((col + half_sizes[i]) > (cols-1)) ? (cols-1) : col + half_sizes[i];
224 float max_coeff = -std::numeric_limits<float>::max ();
226 for (
int j = rs; j < (re + 1); ++j)
228 for (
int k = cs; k < (ce + 1); ++k)
230 if (Z (j, k) != std::numeric_limits<float>::quiet_NaN ())
232 if (Z (j, k) > max_coeff)
233 max_coeff = Z (j, k);
238 if (max_coeff != -std::numeric_limits<float>::max ())
239 Zf (row, col) = max_coeff;
246 for (std::size_t p_idx = 0; p_idx < ground.size (); ++p_idx)
248 const PointT& p = (*cloud)[p_idx];
249 int erow =
static_cast<int> (std::floor ((p.y - global_min.y ()) / cell_size_));
250 int ecol =
static_cast<int> (std::floor ((p.x - global_min.x ()) / cell_size_));
252 float diff = p.z - Zf (erow, ecol);
253 if (diff < height_thresholds[i])
254 pt_indices.push_back (ground[p_idx]);
260 ground.swap (pt_indices);
262 PCL_DEBUG (
"ground now has %d points\n", ground.size ());
269 #define PCL_INSTANTIATE_ApproximateProgressiveMorphologicalFilter(T) template class PCL_EXPORTS pcl::ApproximateProgressiveMorphologicalFilter<T>;
virtual void extract(Indices &ground)
This method launches the segmentation algorithm and returns indices of points determined to be ground...
ApproximateProgressiveMorphologicalFilter()
Constructor that sets default values for member variables.
~ApproximateProgressiveMorphologicalFilter() override
PointCloud represents the base class in PCL for storing collections of 3D points.
shared_ptr< PointCloud< PointT > > Ptr
Define standard C methods and C++ classes that are common to all methods.
Defines all the PCL implemented PointT point type structures.
bool isFinite(const PointT &pt)
Tests if the 3D components of a point are all finite param[in] pt point to be tested return true if f...
IndicesAllocator<> Indices
Type used for indices in PCL.
A point structure representing Euclidean xyz coordinates, and the RGB color.