Skip to content

Commit 84933c8

Browse files
Merge normal and OMP classes as well cleanup redundant code
1 parent 0757613 commit 84933c8

File tree

5 files changed

+67
-322
lines changed

5 files changed

+67
-322
lines changed

features/include/pcl/features/fpfh.h

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,10 @@ namespace pcl
9393
using PointCloudOut = typename Feature<PointInT, PointOutT>::PointCloudOut;
9494

9595
/** \brief Empty constructor. */
96-
FPFHEstimation () :
96+
FPFHEstimation (unsigned int nr_threads = -1) :
9797
nr_bins_f1_ (11), nr_bins_f2_ (11), nr_bins_f3_ (11),
98-
d_pi_ (1.0f / (2.0f * static_cast<float> (M_PI)))
98+
d_pi_ (1.0f / (2.0f * static_cast<float> (M_PI))),
99+
threads_(nr_threads)
99100
{
100101
feature_name_ = "FPFHEstimation";
101102
};
@@ -177,6 +178,21 @@ namespace pcl
177178
nr_bins_f3 = nr_bins_f3_;
178179
}
179180

181+
/** \brief Initialize the scheduler and set the number of threads to use.
182+
* \param[in] nr_threads the number of hardware threads to use (0 sets the value back to automatic)
183+
*/
184+
void
185+
setNumberOfThreads (unsigned int nr_threads = 0) {
186+
if (nr_threads == 0)
187+
#ifdef _OPENMP
188+
threads_ = omp_get_num_procs();
189+
#else
190+
threads_ = 1;
191+
#endif
192+
else
193+
threads_ = nr_threads;
194+
}
195+
180196
protected:
181197

182198
/** \brief Estimate the set of all SPFH (Simple Point Feature Histograms) signatures for the input cloud
@@ -213,8 +229,15 @@ namespace pcl
213229
Eigen::VectorXf fpfh_histogram_;
214230

215231
/** \brief Float constant = 1.0 / (2.0 * M_PI) */
216-
float d_pi_;
232+
float d_pi_;
233+
234+
/** \brief The number of threads the scheduler should use. */
235+
unsigned int threads_;
217236
};
237+
238+
template <typename PointInT, typename PointNT, typename PointOutT>
239+
using FPFHEstimationOMP PCL_DEPRECATED(1, 12, "use FPFHEstimation instead") = FPFHEstimation<PointInT, PointNT, PointOutT>;
240+
218241
}
219242

220243
#ifdef PCL_NO_PRECOMPILE

features/include/pcl/features/fpfh_omp.h

Lines changed: 2 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -40,91 +40,8 @@
4040

4141
#pragma once
4242

43-
#include <pcl/features/feature.h>
44-
#include <pcl/features/fpfh.h>
45-
46-
namespace pcl
47-
{
48-
/** \brief FPFHEstimationOMP estimates the Fast Point Feature Histogram (FPFH) descriptor for a given point cloud
49-
* dataset containing points and normals, in parallel, using the OpenMP standard.
50-
*
51-
* \note If you use this code in any academic work, please cite:
52-
*
53-
* - R.B. Rusu, N. Blodow, M. Beetz.
54-
* Fast Point Feature Histograms (FPFH) for 3D Registration.
55-
* In Proceedings of the IEEE International Conference on Robotics and Automation (ICRA),
56-
* Kobe, Japan, May 12-17 2009.
57-
* - R.B. Rusu, A. Holzbach, N. Blodow, M. Beetz.
58-
* Fast Geometric Point Labeling using Conditional Random Fields.
59-
* In Proceedings of the 22nd IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS),
60-
* St. Louis, MO, USA, October 11-15 2009.
61-
*
62-
* \attention
63-
* The convention for FPFH features is:
64-
* - if a query point's nearest neighbors cannot be estimated, the FPFH feature will be set to NaN
65-
* (not a number)
66-
* - it is impossible to estimate a FPFH descriptor for a point that
67-
* doesn't have finite 3D coordinates. Therefore, any point that contains
68-
* NaN data on x, y, or z, will have its FPFH feature property set to NaN.
69-
*
70-
* \author Radu B. Rusu
71-
* \ingroup features
72-
*/
73-
template <typename PointInT, typename PointNT, typename PointOutT>
74-
class FPFHEstimationOMP : public FPFHEstimation<PointInT, PointNT, PointOutT>
75-
{
76-
public:
77-
using Ptr = shared_ptr<FPFHEstimationOMP<PointInT, PointNT, PointOutT> >;
78-
using ConstPtr = shared_ptr<const FPFHEstimationOMP<PointInT, PointNT, PointOutT> >;
79-
using Feature<PointInT, PointOutT>::feature_name_;
80-
using Feature<PointInT, PointOutT>::getClassName;
81-
using Feature<PointInT, PointOutT>::indices_;
82-
using Feature<PointInT, PointOutT>::k_;
83-
using Feature<PointInT, PointOutT>::search_parameter_;
84-
using Feature<PointInT, PointOutT>::input_;
85-
using Feature<PointInT, PointOutT>::surface_;
86-
using FeatureFromNormals<PointInT, PointNT, PointOutT>::normals_;
87-
using FPFHEstimation<PointInT, PointNT, PointOutT>::hist_f1_;
88-
using FPFHEstimation<PointInT, PointNT, PointOutT>::hist_f2_;
89-
using FPFHEstimation<PointInT, PointNT, PointOutT>::hist_f3_;
90-
using FPFHEstimation<PointInT, PointNT, PointOutT>::weightPointSPFHSignature;
91-
92-
using PointCloudOut = typename Feature<PointInT, PointOutT>::PointCloudOut;
93-
94-
/** \brief Initialize the scheduler and set the number of threads to use.
95-
* \param[in] nr_threads the number of hardware threads to use (0 sets the value back to automatic)
96-
*/
97-
FPFHEstimationOMP (unsigned int nr_threads = 0) : nr_bins_f1_ (11), nr_bins_f2_ (11), nr_bins_f3_ (11)
98-
{
99-
feature_name_ = "FPFHEstimationOMP";
43+
PCL_DEPRECATED_HEADER(1, 13, "Use <pcl/features/fpfh.h> instead.")
10044

101-
setNumberOfThreads(nr_threads);
102-
}
103-
104-
/** \brief Initialize the scheduler and set the number of threads to use.
105-
* \param[in] nr_threads the number of hardware threads to use (0 sets the value back to automatic)
106-
*/
107-
void
108-
setNumberOfThreads (unsigned int nr_threads = 0);
109-
110-
private:
111-
/** \brief Estimate the Fast Point Feature Histograms (FPFH) descriptors at a set of points given by
112-
* <setInputCloud (), setIndices ()> using the surface in setSearchSurface () and the spatial locator in
113-
* setSearchMethod ()
114-
* \param[out] output the resultant point cloud model dataset that contains the FPFH feature estimates
115-
*/
116-
void
117-
computeFeature (PointCloudOut &output) override;
45+
#include <pcl/features/fpfh.h>
11846

119-
public:
120-
/** \brief The number of subdivisions for each angular feature interval. */
121-
int nr_bins_f1_, nr_bins_f2_, nr_bins_f3_;
122-
private:
123-
/** \brief The number of threads the scheduler should use. */
124-
unsigned int threads_;
125-
};
126-
}
12747

128-
#ifdef PCL_NO_PRECOMPILE
129-
#include <pcl/features/impl/fpfh_omp.hpp>
130-
#endif

features/include/pcl/features/impl/fpfh.hpp

Lines changed: 39 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeSPFHSignatures (std::v
186186
std::vector<int> nn_indices (k_);
187187
std::vector<float> nn_dists (k_);
188188

189-
std::set<int> spfh_indices;
189+
std::set<int> spfh_indices_set;
190+
std::vector<int> spfh_indices_vec;
190191
spfh_hist_lookup.resize (surface_->size ());
191192

192193
// Build a list of (unique) indices for which we will need to compute SPFH signatures
@@ -199,26 +200,37 @@ pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeSPFHSignatures (std::v
199200
if (this->searchForNeighbors (p_idx, search_parameter_, nn_indices, nn_dists) == 0)
200201
continue;
201202

202-
spfh_indices.insert (nn_indices.begin (), nn_indices.end ());
203+
spfh_indices_set.insert (nn_indices.begin (), nn_indices.end ());
203204
}
205+
spfh_indices_vec.resize (spfh_indices_set.size ());
206+
std::copy (spfh_indices_set.cbegin (), spfh_indices_set.cend (), spfh_indices_vec.begin ());
204207
}
205208
else
206209
{
207210
// Special case: When a feature must be computed at every point, there is no need for a neighborhood search
208-
for (std::size_t idx = 0; idx < indices_->size (); ++idx)
209-
spfh_indices.insert (static_cast<int> (idx));
211+
spfh_indices_vec.resize (indices_->size ());
212+
std::iota(spfh_indices_vec.begin (), spfh_indices_vec.end (),
213+
static_cast<decltype(spfh_indices_vec)::value_type>(0));
210214
}
211215

212216
// Initialize the arrays that will store the SPFH signatures
213-
std::size_t data_size = spfh_indices.size ();
217+
const auto data_size = spfh_indices_vec.size ();
214218
hist_f1.setZero (data_size, nr_bins_f1_);
215219
hist_f2.setZero (data_size, nr_bins_f2_);
216220
hist_f3.setZero (data_size, nr_bins_f3_);
217221

218222
// Compute SPFH signatures for every point that needs them
219-
std::size_t i = 0;
220-
for (const auto& p_idx: spfh_indices)
223+
#pragma omp parallel for \
224+
default(none) \
225+
shared(spfh_hist_lookup, spfh_indices_vec, hist_f1, hist_f2, hist_f3) \
226+
firstprivate(nn_indices, nn_dists) \
227+
num_threads(threads_) \
228+
if (threads_ != -1)
229+
for (std::ptrdiff_t i = 0; i < static_cast<std::ptrdiff_t> (spfh_indices_vec.size ()); ++i)
221230
{
231+
// Get the next point index
232+
int p_idx = spfh_indices_vec[i];
233+
222234
// Find the neighborhood around p_idx
223235
if (this->searchForNeighbors (*surface_, p_idx, search_parameter_, nn_indices, nn_dists) == 0)
224236
continue;
@@ -228,7 +240,6 @@ pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeSPFHSignatures (std::v
228240

229241
// Populate a lookup table for converting a point index to its corresponding row in the spfh_hist_* matrices
230242
spfh_hist_lookup[p_idx] = i;
231-
i++;
232243
}
233244
}
234245

@@ -245,59 +256,32 @@ pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeFeature (PointCloudOut
245256
computeSPFHSignatures (spfh_hist_lookup, hist_f1_, hist_f2_, hist_f3_);
246257

247258
output.is_dense = true;
248-
// Save a few cycles by not checking every point for NaN/Inf values if the cloud is set to dense
249-
if (input_->is_dense)
250-
{
251-
// Iterate over the entire index vector
252-
for (std::size_t idx = 0; idx < indices_->size (); ++idx)
253-
{
254-
if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
255-
{
256-
for (Eigen::Index d = 0; d < fpfh_histogram_.size (); ++d)
257-
output[idx].histogram[d] = std::numeric_limits<float>::quiet_NaN ();
258-
259-
output.is_dense = false;
260-
continue;
261-
}
262-
263-
// ... and remap the nn_indices values so that they represent row indices in the spfh_hist_* matrices
264-
// instead of indices into surface_->points
265-
for (auto &nn_index : nn_indices)
266-
nn_index = spfh_hist_lookup[nn_index];
267-
268-
// Compute the FPFH signature (i.e. compute a weighted combination of local SPFH signatures) ...
269-
weightPointSPFHSignature (hist_f1_, hist_f2_, hist_f3_, nn_indices, nn_dists, fpfh_histogram_);
270259

271-
// ...and copy it into the output cloud
272-
std::copy_n(fpfh_histogram_.data (), fpfh_histogram_.size (), output[idx].histogram);
273-
}
274-
}
275-
else
260+
// Iterate over the entire index vector
261+
for (std::size_t idx = 0; idx < indices_->size (); ++idx)
276262
{
277-
// Iterate over the entire index vector
278-
for (std::size_t idx = 0; idx < indices_->size (); ++idx)
279-
{
280-
if (!isFinite ((*input_)[(*indices_)[idx]]) ||
281-
this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
282-
{
283-
for (Eigen::Index d = 0; d < fpfh_histogram_.size (); ++d)
284-
output[idx].histogram[d] = std::numeric_limits<float>::quiet_NaN ();
285-
286-
output.is_dense = false;
263+
if (input_->is_dense || isFinite ((*input_)[(*indices_)[idx]])) {
264+
if (this->searchForNeighbors(
265+
(*indices_)[idx], search_parameter_, nn_indices, nn_dists)) {
266+
// ... and remap the nn_indices values so that they represent row indices in the spfh_hist_* matrices
267+
// instead of indices into surface_->points
268+
for (auto &nn_index : nn_indices)
269+
nn_index = spfh_hist_lookup[nn_index];
270+
271+
// Compute the FPFH signature (i.e. compute a weighted combination of local SPFH signatures) ...
272+
weightPointSPFHSignature (hist_f1_, hist_f2_, hist_f3_, nn_indices, nn_dists, fpfh_histogram_);
273+
274+
// ...and copy it into the output cloud
275+
std::copy_n(fpfh_histogram_.data (), fpfh_histogram_.size (), output[idx].histogram);
287276
continue;
288277
}
278+
}
289279

290-
// ... and remap the nn_indices values so that they represent row indices in the spfh_hist_* matrices
291-
// instead of indices into surface_->points
292-
for (auto &nn_index : nn_indices)
293-
nn_index = spfh_hist_lookup[nn_index];
294-
295-
// Compute the FPFH signature (i.e. compute a weighted combination of local SPFH signatures) ...
296-
weightPointSPFHSignature (hist_f1_, hist_f2_, hist_f3_, nn_indices, nn_dists, fpfh_histogram_);
280+
for (Eigen::Index d = 0; d < fpfh_histogram_.size(); ++d)
281+
output[idx].histogram[d] = std::numeric_limits<float>::quiet_NaN();
297282

298-
// ...and copy it into the output cloud
299-
std::copy_n(fpfh_histogram_.data (), fpfh_histogram_.size (), output[idx].histogram);
300-
}
283+
if (output.is_dense)
284+
output.is_dense = false;
301285
}
302286
}
303287

0 commit comments

Comments
 (0)