@@ -186,7 +186,8 @@ pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeSPFHSignatures (std::v
186
186
std::vector<int > nn_indices (k_);
187
187
std::vector<float > nn_dists (k_);
188
188
189
- std::set<int > spfh_indices;
189
+ std::set<int > spfh_indices_set;
190
+ std::vector<int > spfh_indices_vec;
190
191
spfh_hist_lookup.resize (surface_->size ());
191
192
192
193
// 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
199
200
if (this ->searchForNeighbors (p_idx, search_parameter_, nn_indices, nn_dists) == 0 )
200
201
continue ;
201
202
202
- spfh_indices .insert (nn_indices.begin (), nn_indices.end ());
203
+ spfh_indices_set .insert (nn_indices.begin (), nn_indices.end ());
203
204
}
205
+ spfh_indices_vec.resize (spfh_indices_set.size ());
206
+ std::copy (spfh_indices_set.cbegin (), spfh_indices_set.cend (), spfh_indices_vec.begin ());
204
207
}
205
208
else
206
209
{
207
210
// 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 ));
210
214
}
211
215
212
216
// 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 ();
214
218
hist_f1.setZero (data_size, nr_bins_f1_);
215
219
hist_f2.setZero (data_size, nr_bins_f2_);
216
220
hist_f3.setZero (data_size, nr_bins_f3_);
217
221
218
222
// 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)
221
230
{
231
+ // Get the next point index
232
+ int p_idx = spfh_indices_vec[i];
233
+
222
234
// Find the neighborhood around p_idx
223
235
if (this ->searchForNeighbors (*surface_, p_idx, search_parameter_, nn_indices, nn_dists) == 0 )
224
236
continue ;
@@ -228,7 +240,6 @@ pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeSPFHSignatures (std::v
228
240
229
241
// Populate a lookup table for converting a point index to its corresponding row in the spfh_hist_* matrices
230
242
spfh_hist_lookup[p_idx] = i;
231
- i++;
232
243
}
233
244
}
234
245
@@ -245,59 +256,32 @@ pcl::FPFHEstimation<PointInT, PointNT, PointOutT>::computeFeature (PointCloudOut
245
256
computeSPFHSignatures (spfh_hist_lookup, hist_f1_, hist_f2_, hist_f3_);
246
257
247
258
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_);
270
259
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)
276
262
{
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 );
287
276
continue ;
288
277
}
278
+ }
289
279
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 ();
297
282
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 ;
301
285
}
302
286
}
303
287
0 commit comments