43 #include <pcl/features/boundary.h>
44 #include <pcl/common/point_tests.h>
52 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
55 unsigned int nr_threads)
59 threads_ = omp_get_num_procs();
61 threads_ = nr_threads;
62 PCL_DEBUG(
"[pcl::BoundaryEstimation::setNumberOfThreads] Setting number of threads "
69 "[pcl::BoundaryEstimation::setNumberOfThreads] Parallelization is requested, "
70 "but OpenMP is not available! Continuing without parallelization.\n");
75 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
bool
79 const Eigen::Vector4f &u,
const Eigen::Vector4f &v,
80 const float angle_threshold)
const
82 return (isBoundaryPoint (cloud, cloud[q_idx], indices, u, v, angle_threshold));
86 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
bool
90 const Eigen::Vector4f &u,
const Eigen::Vector4f &v,
91 const float angle_threshold)
const
93 if (indices.size () < 3)
96 if (!std::isfinite (q_point.x) || !std::isfinite (q_point.y) || !std::isfinite (q_point.z))
100 std::vector<float> angles (indices.size ());
101 float max_dif = 0, dif;
104 for (
const auto &index : indices)
106 if (!std::isfinite (cloud[index].x) ||
107 !std::isfinite (cloud[index].y) ||
108 !std::isfinite (cloud[index].z))
111 Eigen::Vector4f delta = cloud[index].getVector4fMap () - q_point.getVector4fMap ();
112 if (delta == Eigen::Vector4f::Zero())
115 angles[cp++] = std::atan2 (v.dot (delta), u.dot (delta));
121 std::sort (angles.begin (), angles.end ());
124 for (std::size_t i = 0; i < angles.size () - 1; ++i)
126 dif = angles[i + 1] - angles[i];
131 dif = 2 *
static_cast<float> (
M_PI) - angles[angles.size () - 1] + angles[0];
136 return (max_dif > angle_threshold);
140 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
void
146 std::vector<float> nn_dists (k_);
148 Eigen::Vector4f u = Eigen::Vector4f::Zero (), v = Eigen::Vector4f::Zero ();
150 output.is_dense =
true;
152 if (input_->is_dense)
154 #pragma omp parallel for \
157 firstprivate(nn_indices, nn_dists, u, v) \
158 num_threads(threads_) \
159 schedule(dynamic, chunk_size_)
161 for (std::ptrdiff_t idx = 0; idx < static_cast<std::ptrdiff_t>(indices_->size());
164 if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
166 output[idx].boundary_point = std::numeric_limits<std::uint8_t>::quiet_NaN ();
167 output.is_dense =
false;
174 getCoordinateSystemOnPlane ((*normals_)[(*indices_)[idx]], u, v);
177 output[idx].boundary_point = isBoundaryPoint (*surface_, (*input_)[(*indices_)[idx]], nn_indices, u, v, angle_threshold_);
182 #pragma omp parallel for \
185 firstprivate(nn_indices, nn_dists, u, v) \
186 num_threads(threads_) \
187 schedule(dynamic, chunk_size_)
189 for (std::ptrdiff_t idx = 0; idx < static_cast<std::ptrdiff_t>(indices_->size());
192 if (!
isFinite ((*input_)[(*indices_)[idx]]) ||
193 this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
195 output[idx].boundary_point = std::numeric_limits<std::uint8_t>::quiet_NaN ();
196 output.is_dense =
false;
203 getCoordinateSystemOnPlane ((*normals_)[(*indices_)[idx]], u, v);
206 output[idx].boundary_point = isBoundaryPoint (*surface_, (*input_)[(*indices_)[idx]], nn_indices, u, v, angle_threshold_);
211 #define PCL_INSTANTIATE_BoundaryEstimation(PointInT,PointNT,PointOutT) template class PCL_EXPORTS pcl::BoundaryEstimation<PointInT, PointNT, PointOutT>;
void computeFeature(PointCloudOut &output) override
Estimate whether a set of points is lying on surface boundaries using an angle criterion for all poin...
typename Feature< PointInT, PointOutT >::PointCloudOut PointCloudOut
void setNumberOfThreads(unsigned int nr_threads=0)
Initialize the scheduler and set the number of threads to use.
bool isBoundaryPoint(const pcl::PointCloud< PointInT > &cloud, int q_idx, const pcl::Indices &indices, const Eigen::Vector4f &u, const Eigen::Vector4f &v, const float angle_threshold) const
Check whether a point is a boundary point in a planar patch of projected points given by indices.
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.