40 #ifndef PCL_KDTREE_KDTREE_FLANN_H_
41 #define PCL_KDTREE_KDTREE_FLANN_H_
56 template <
typename Po
intT,
typename Dist = flann::L2_Simple<
float> >
77 typedef boost::shared_ptr<KdTreeFLANN<PointT> >
Ptr;
78 typedef boost::shared_ptr<const KdTreeFLANN<PointT> >
ConstPtr;
87 flann_index_ (NULL), cloud_ (NULL),
88 index_mapping_ (), identity_mapping_ (false),
89 dim_ (0), total_nr_points_ (0),
90 param_k_ (flann::SearchParams (-1 , epsilon_)),
91 param_radius_ (flann::SearchParams (-1, epsilon_, sorted))
100 flann_index_ (NULL), cloud_ (NULL),
101 index_mapping_ (), identity_mapping_ (false),
102 dim_ (0), total_nr_points_ (0),
103 param_k_ (flann::SearchParams (-1 , epsilon_)),
104 param_radius_ (flann::SearchParams (-1, epsilon_, false))
116 flann_index_ = k.flann_index_;
118 index_mapping_ = k.index_mapping_;
119 identity_mapping_ = k.identity_mapping_;
121 total_nr_points_ = k.total_nr_points_;
122 param_k_ = k.param_k_;
123 param_radius_ = k.param_radius_;
134 param_k_ = flann::SearchParams (-1 , epsilon_);
135 param_radius_ = flann::SearchParams (-1 , epsilon_, sorted_);
142 param_k_ = flann::SearchParams (-1, epsilon_);
143 param_radius_ = flann::SearchParams (-1, epsilon_, sorted_);
179 std::vector<int> &k_indices, std::vector<float> &k_sqr_distances)
const;
199 std::vector<float> &k_sqr_distances,
unsigned int max_nn = 0)
const;
211 convertCloudToArray (
const PointCloud &cloud);
219 convertCloudToArray (
const PointCloud &cloud,
const std::vector<int> &indices);
224 getName ()
const {
return (
"KdTreeFLANN"); }
233 std::vector<int> index_mapping_;
236 bool identity_mapping_;
242 int total_nr_points_;
245 flann::SearchParams param_k_;
248 flann::SearchParams param_radius_;
273 typedef boost::shared_ptr<KdTreeFLANN<Eigen::MatrixXf> >
Ptr;
274 typedef boost::shared_ptr<const KdTreeFLANN<Eigen::MatrixXf> >
ConstPtr;
282 input_(), indices_(), epsilon_(0.0f), sorted_(sorted), flann_index_(NULL), cloud_(NULL),
283 index_mapping_ (), identity_mapping_ (false), dim_ (0),
284 param_k_ (flann::SearchParams (-1, epsilon_)),
285 param_radius_ (flann::SearchParams (-1, epsilon_, sorted)),
295 input_(), indices_(), epsilon_(0.0f), sorted_(false), flann_index_(NULL), cloud_(NULL),
296 index_mapping_ (), identity_mapping_ (false), dim_ (0),
297 param_k_ (flann::SearchParams (-1, epsilon_)),
298 param_radius_ (flann::SearchParams (-1, epsilon_, sorted_)),
311 indices_ = k.indices_;
312 epsilon_ = k.epsilon_;
314 flann_index_ = k.flann_index_;
316 index_mapping_ = k.index_mapping_;
317 identity_mapping_ = k.identity_mapping_;
319 param_k_ = k.param_k_;
320 param_radius_ = k.param_radius_;
321 total_nr_points_ = k.total_nr_points_;
332 param_k_ = flann::SearchParams (-1 , epsilon_);
333 param_radius_ = flann::SearchParams (-1, epsilon_, sorted_);
362 dim_ =
static_cast<int> (cloud->points.cols ());
367 total_nr_points_ =
static_cast<int> (indices_->size ());
368 convertCloudToArray (*input_, *indices_);
373 total_nr_points_ =
static_cast<int> (cloud->points.rows ());
374 convertCloudToArray (*input_);
378 flann::KDTreeSingleIndexParams (15));
379 flann_index_->buildIndex ();
404 template <
typename T>
int
406 std::vector<int> &k_indices, std::vector<float> &k_sqr_distances)
const
408 assert (isRowValid (point) &&
"Invalid (NaN, Inf) point coordinates given to nearestKSearch!");
410 if (k > total_nr_points_)
412 PCL_ERROR (
"[pcl::KdTreeFLANN::nearestKSearch] An invalid number of nearest neighbors was requested! (k = %d out of %d total points).\n", k, total_nr_points_);
413 k = total_nr_points_;
416 k_indices.resize (k);
417 k_sqr_distances.resize (k);
419 size_t dim = point.size ();
420 std::vector<float> query (dim);
421 for (
size_t i = 0; i < dim; ++i)
428 k_indices_mat, k_distances_mat,
432 if (!identity_mapping_)
434 for (
size_t i = 0; i < static_cast<size_t> (k); ++i)
436 int& neighbor_index = k_indices[i];
437 neighbor_index = index_mapping_[neighbor_index];
455 std::vector<int> &k_indices, std::vector<float> &k_sqr_distances)
const
457 assert (index >= 0 && index < static_cast<int> (cloud.
size ()) &&
"Out-of-bounds error in nearestKSearch!");
472 std::vector<int> &k_indices, std::vector<float> &k_sqr_distances)
const
474 if (indices_ == NULL)
476 assert (index >= 0 && index < static_cast<int> (input_->size ()) &&
"Out-of-bounds error in nearestKSearch!");
477 return (
nearestKSearch (input_->points.row (index), k, k_indices, k_sqr_distances));
481 assert (index >= 0 && index < static_cast<int> (indices_->size ()) &&
"Out-of-bounds error in nearestKSearch!");
482 return (
nearestKSearch (input_->points.row ((*indices_)[index]), k, k_indices, k_sqr_distances));
496 template <
typename T>
int
497 radiusSearch (
const T &point,
double radius, std::vector<int> &k_indices,
498 std::vector<float> &k_sqr_dists,
unsigned int max_nn = 0)
const
500 assert (isRowValid (point) &&
"Invalid (NaN, Inf) point coordinates given to radiusSearch!");
502 size_t dim = point.size ();
503 std::vector<float> query (dim);
504 for (
size_t i = 0; i < dim; ++i)
508 if (max_nn == 0 || max_nn > static_cast<unsigned int> (total_nr_points_))
509 max_nn = total_nr_points_;
511 std::vector<std::vector<int> > indices(1);
512 std::vector<std::vector<float> > dists(1);
514 flann::SearchParams params(param_radius_);
515 if (max_nn == static_cast<unsigned int>(total_nr_points_))
516 params.max_neighbors = -1;
518 params.max_neighbors = max_nn;
520 int neighbors_in_radius = flann_index_->radiusSearch (
flann::Matrix<float> (&query[0], 1, dim_),
523 static_cast<float> (radius * radius),
526 k_indices = indices[0];
527 k_sqr_dists = dists[0];
530 if (!identity_mapping_)
532 for (
int i = 0; i < neighbors_in_radius; ++i)
534 int& neighbor_index = k_indices[i];
535 neighbor_index = index_mapping_[neighbor_index];
539 return (neighbors_in_radius);
555 std::vector<int> &k_indices, std::vector<float> &k_sqr_distances,
556 unsigned int max_nn = 0)
const
558 assert (index >= 0 && index < static_cast<int> (cloud.
size ()) &&
"Out-of-bounds error in radiusSearch!");
559 return (
radiusSearch (cloud.
points.row (index), radius, k_indices, k_sqr_distances, max_nn));
575 std::vector<float> &k_sqr_distances,
unsigned int max_nn = 0)
const
577 if (indices_ == NULL)
579 assert (index >= 0 && index < static_cast<int> (input_->size ()) &&
"Out-of-bounds error in radiusSearch!");
580 return (
radiusSearch (input_->points.row (index), radius, k_indices, k_sqr_distances, max_nn));
584 assert (index >= 0 && index < static_cast<int> (indices_->size ()) &&
"Out-of-bounds error in radiusSearch!");
585 return (
radiusSearch (input_->points.row ((*indices_)[index]), radius, k_indices, k_sqr_distances, max_nn));
610 index_mapping_.clear ();
619 template <
typename Expr>
bool
620 isRowValid (
const Expr &pt)
const
622 for (
size_t i = 0; i < static_cast<size_t> (pt.size ()); ++i)
643 int original_no_of_points =
static_cast<int> (cloud.
points.rows ());
645 cloud_ =
static_cast<float*
> (malloc (original_no_of_points * dim_ *
sizeof (
float)));
646 float* cloud_ptr = cloud_;
647 index_mapping_.reserve (original_no_of_points);
648 identity_mapping_ =
true;
650 for (
int cloud_index = 0; cloud_index < original_no_of_points; ++cloud_index)
653 if (!isRowValid (cloud.
points.row (cloud_index)))
655 identity_mapping_ =
false;
659 index_mapping_.push_back (cloud_index);
661 for (
size_t i = 0; i < static_cast<size_t> (dim_); ++i)
663 *cloud_ptr = cloud.
points.coeffRef (cloud_index, i);
675 convertCloudToArray (
const PointCloud &cloud,
const std::vector<int> &indices)
684 int original_no_of_points =
static_cast<int> (indices.size ());
686 cloud_ =
static_cast<float*
> (malloc (original_no_of_points * dim_ *
sizeof (
float)));
687 float* cloud_ptr = cloud_;
688 index_mapping_.reserve (original_no_of_points);
689 identity_mapping_ =
true;
691 for (
int indices_index = 0; indices_index < original_no_of_points; ++indices_index)
693 int cloud_index = indices[indices_index];
695 if (!isRowValid (cloud.
points.row (cloud_index)))
697 identity_mapping_ =
false;
701 index_mapping_.push_back (indices_index);
703 for (
size_t i = 0; i < static_cast<size_t> (dim_); ++i)
705 *cloud_ptr = cloud.
points.coeffRef (cloud_index, i);
727 getName ()
const {
return (
"KdTreeFLANN"); }
736 std::vector<int> index_mapping_;
739 bool identity_mapping_;
745 flann::SearchParams param_k_;
748 flann::SearchParams param_radius_;
751 int total_nr_points_;