40 #ifndef PCL_SEARCH_IMPL_FLANN_SEARCH_H_
41 #define PCL_SEARCH_IMPL_FLANN_SEARCH_H_
43 #include <flann/algorithms/kdtree_index.h>
44 #include <flann/algorithms/kdtree_single_index.h>
45 #include <flann/algorithms/kmeans_index.h>
47 #include <pcl/search/flann_search.h>
48 #include <pcl/kdtree/kdtree_flann.h>
50 #include <pcl/kdtree/impl/kdtree_flann.hpp>
53 template <
typename Po
intT,
typename FlannDistance>
57 return (
static_cast<IndexPtr> (
new flann::KDTreeSingleIndex<FlannDistance> (*data,
static_cast<flann::KDTreeSingleIndexParams
> (max_leaf_size_))));
61 template <
typename Po
intT,
typename FlannDistance>
65 return (
static_cast<IndexPtr> (
new flann::KMeansIndex<FlannDistance> (*data,flann::KMeansIndexParams ())));
69 template <
typename Po
intT,
typename FlannDistance>
73 return (
static_cast<IndexPtr> (
new flann::KDTreeIndex<FlannDistance> (*data,
static_cast<flann::KDTreeIndexParams
> (trees_))));
77 template <
typename Po
intT,
typename FlannDistance>
85 template <
typename Po
intT,
typename FlannDistance>
88 if (input_copied_for_flann_)
89 delete [] input_flann_->ptr();
93 template <
typename Po
intT,
typename FlannDistance>
bool
98 convertInputToFlannMatrix ();
99 index_ = creator_->createIndex (input_flann_);
100 index_->buildIndex ();
105 template <
typename Po
intT,
typename FlannDistance>
int
108 assert (point_representation_->isValid (point) &&
"Invalid (NaN, Inf) point coordinates given to nearestKSearch!");
109 bool can_cast = point_representation_->isTrivial ();
111 float* data =
nullptr;
114 data =
new float [point_representation_->getNumberOfDimensions ()];
115 point_representation_->vectorize (point,data);
118 float* cdata = can_cast ?
const_cast<float*
> (
reinterpret_cast<const float*
> (&point)): data;
121 if (
static_cast<unsigned int>(k) > total_nr_points_)
122 k = total_nr_points_;
124 flann::SearchParams p;
126 p.sorted = sorted_results_;
128 if (indices.size() !=
static_cast<unsigned int> (k))
129 indices.resize (k,-1);
130 if (dists.size() !=
static_cast<unsigned int> (k))
133 int result =
knn_search(*index_, m, indices, d, k, p);
137 if (!identity_mapping_)
139 for (std::size_t i = 0; i < static_cast<unsigned int> (k); ++i)
141 auto& neighbor_index = indices[i];
142 neighbor_index = index_mapping_[neighbor_index];
149 template <
typename Po
intT,
typename FlannDistance>
void
151 const PointCloud& cloud,
const Indices& indices,
int k, std::vector<Indices>& k_indices,
152 std::vector< std::vector<float> >& k_sqr_distances)
const
154 if (indices.empty ())
156 k_indices.resize (cloud.size ());
157 k_sqr_distances.resize (cloud.size ());
159 if (! cloud.is_dense)
161 for (std::size_t i = 0; i < cloud.size(); i++)
163 assert (point_representation_->isValid (cloud[i]) &&
"Invalid (NaN, Inf) point coordinates given to nearestKSearch!");
167 bool can_cast = point_representation_->isTrivial ();
173 data =
new float[dim_*cloud.size ()];
174 for (std::size_t i = 0; i < cloud.size (); ++i)
176 float* out = data+i*dim_;
177 point_representation_->vectorize (cloud[i],out);
183 float* cdata = can_cast ?
const_cast<float*
> (
reinterpret_cast<const float*
> (&cloud[0])): data;
186 if (
static_cast<unsigned int>(k) > total_nr_points_)
187 k = total_nr_points_;
189 flann::SearchParams p;
190 p.sorted = sorted_results_;
193 knn_search(*index_, m, k_indices, k_sqr_distances, k, p);
199 k_indices.resize (indices.size ());
200 k_sqr_distances.resize (indices.size ());
202 if (! cloud.is_dense)
204 for (std::size_t i = 0; i < indices.size(); i++)
206 assert (point_representation_->isValid (cloud [indices[i]]) &&
"Invalid (NaN, Inf) point coordinates given to nearestKSearch!");
210 float* data=
new float [dim_*indices.size ()];
211 for (std::size_t i = 0; i < indices.size (); ++i)
213 float* out = data+i*dim_;
214 point_representation_->vectorize (cloud[indices[i]],out);
216 const flann::Matrix<float> m (data ,indices.size (), point_representation_->getNumberOfDimensions ());
218 flann::SearchParams p;
219 p.sorted = sorted_results_;
222 knn_search(*index_, m, k_indices, k_sqr_distances, k, p);
226 if (!identity_mapping_)
228 for (
auto &k_index : k_indices)
230 for (
auto &neighbor_index : k_index)
232 neighbor_index = index_mapping_[neighbor_index];
239 template <
typename Po
intT,
typename FlannDistance>
int
241 Indices &indices, std::vector<float> &distances,
242 unsigned int max_nn)
const
244 assert (point_representation_->isValid (point) &&
"Invalid (NaN, Inf) point coordinates given to radiusSearch!");
245 bool can_cast = point_representation_->isTrivial ();
247 float* data =
nullptr;
250 data =
new float [point_representation_->getNumberOfDimensions ()];
251 point_representation_->vectorize (point,data);
254 float* cdata = can_cast ?
const_cast<float*
> (
reinterpret_cast<const float*
> (&point)) : data;
257 flann::SearchParams p;
258 p.sorted = sorted_results_;
260 p.max_neighbors = max_nn > 0 ? max_nn : -1;
262 std::vector<Indices> i (1);
263 std::vector<std::vector<float> > d (1);
264 int result =
radius_search(*index_, m, i, d,
static_cast<float>(radius * radius), p);
270 if (!identity_mapping_)
272 for (
auto &neighbor_index : indices)
274 neighbor_index = index_mapping_ [neighbor_index];
281 template <
typename Po
intT,
typename FlannDistance>
void
283 const PointCloud& cloud,
const Indices& indices,
double radius, std::vector<Indices>& k_indices,
284 std::vector< std::vector<float> >& k_sqr_distances,
unsigned int max_nn)
const
286 if (indices.empty ())
288 k_indices.resize (cloud.size ());
289 k_sqr_distances.resize (cloud.size ());
291 if (! cloud.is_dense)
293 for (std::size_t i = 0; i < cloud.size(); i++)
295 assert (point_representation_->isValid (cloud[i]) &&
"Invalid (NaN, Inf) point coordinates given to radiusSearch!");
299 bool can_cast = point_representation_->isTrivial ();
301 float* data =
nullptr;
304 data =
new float[dim_*cloud.size ()];
305 for (std::size_t i = 0; i < cloud.size (); ++i)
307 float* out = data+i*dim_;
308 point_representation_->vectorize (cloud[i],out);
312 float* cdata = can_cast ?
const_cast<float*
> (
reinterpret_cast<const float*
> (&cloud[0])) : data;
315 flann::SearchParams p;
316 p.sorted = sorted_results_;
320 p.max_neighbors = max_nn != 0 ? max_nn : -1;
322 *index_, m, k_indices, k_sqr_distances,
static_cast<float>(radius * radius), p);
328 k_indices.resize (indices.size ());
329 k_sqr_distances.resize (indices.size ());
331 if (! cloud.is_dense)
333 for (std::size_t i = 0; i < indices.size(); i++)
335 assert (point_representation_->isValid (cloud [indices[i]]) &&
"Invalid (NaN, Inf) point coordinates given to radiusSearch!");
339 float* data =
new float [dim_ * indices.size ()];
340 for (std::size_t i = 0; i < indices.size (); ++i)
342 float* out = data+i*dim_;
343 point_representation_->vectorize (cloud[indices[i]], out);
345 const flann::Matrix<float> m (data, cloud.size (), point_representation_->getNumberOfDimensions ());
347 flann::SearchParams p;
348 p.sorted = sorted_results_;
352 p.max_neighbors = max_nn != 0 ? max_nn : -1;
354 *index_, m, k_indices, k_sqr_distances,
static_cast<float>(radius * radius), p);
358 if (!identity_mapping_)
360 for (
auto &k_index : k_indices)
362 for (
auto &neighbor_index : k_index)
364 neighbor_index = index_mapping_[neighbor_index];
371 template <
typename Po
intT,
typename FlannDistance>
void
374 std::size_t original_no_of_points = indices_ && !indices_->empty () ? indices_->size () : input_->size ();
376 if (input_copied_for_flann_)
377 delete input_flann_->ptr();
378 input_copied_for_flann_ =
true;
379 index_mapping_.clear();
380 identity_mapping_ =
true;
386 if (!indices_ || indices_->empty ())
389 if (input_->is_dense && point_representation_->isTrivial ())
392 input_flann_ =
static_cast<MatrixPtr> (
new flann::Matrix<float> (
const_cast<float*
>(
reinterpret_cast<const float*
>(&(*input_) [0])), original_no_of_points, point_representation_->getNumberOfDimensions (),sizeof (
PointT)));
393 input_copied_for_flann_ =
false;
394 total_nr_points_ = input_->points.size();
398 input_flann_ =
static_cast<MatrixPtr> (
new flann::Matrix<float> (
new float[original_no_of_points*point_representation_->getNumberOfDimensions ()], original_no_of_points, point_representation_->getNumberOfDimensions ()));
399 float* cloud_ptr = input_flann_->ptr();
400 for (std::size_t i = 0; i < original_no_of_points; ++i)
402 const PointT& point = (*input_)[i];
404 if (!point_representation_->isValid (point))
406 identity_mapping_ =
false;
410 index_mapping_.push_back (
static_cast<index_t> (i));
412 point_representation_->vectorize (point, cloud_ptr);
415 total_nr_points_ = index_mapping_.size();
421 input_flann_ =
static_cast<MatrixPtr> (
new flann::Matrix<float> (
new float[original_no_of_points*point_representation_->getNumberOfDimensions ()], original_no_of_points, point_representation_->getNumberOfDimensions ()));
422 float* cloud_ptr = input_flann_->ptr();
423 identity_mapping_ =
false;
424 for (std::size_t indices_index = 0; indices_index < original_no_of_points; ++indices_index)
426 index_t cloud_index = (*indices_)[indices_index];
427 const PointT& point = (*input_)[cloud_index];
429 if (!point_representation_->isValid (point))
434 index_mapping_.push_back (
static_cast<index_t> (cloud_index));
436 point_representation_->vectorize (point, cloud_ptr);
439 total_nr_points_ = index_mapping_.size();
441 if (input_copied_for_flann_)
442 input_flann_->rows = index_mapping_.size ();
445 #define PCL_INSTANTIATE_FlannSearch(T) template class PCL_EXPORTS pcl::search::FlannSearch<T>;
DefaultPointRepresentation extends PointRepresentation to define default behavior for common point ty...
virtual IndexPtr createIndex(MatrixConstPtr data)
Create a FLANN Index from the input data.
IndexPtr createIndex(MatrixConstPtr data) override
Create a FLANN Index from the input data.
virtual IndexPtr createIndex(MatrixConstPtr data)
Create a FLANN Index from the input data.
void convertInputToFlannMatrix()
converts the input data to a format usable by FLANN
int radiusSearch(const PointT &point, double radius, Indices &k_indices, std::vector< float > &k_sqr_distances, unsigned int max_nn=0) const override
Search for all the nearest neighbors of the query point in a given radius.
shared_ptr< flann::NNIndex< FlannDistance > > IndexPtr
shared_ptr< const flann::Matrix< float > > MatrixConstPtr
FlannSearch(bool sorted=true, FlannIndexCreatorPtr creator=FlannIndexCreatorPtr(new KdTreeIndexCreator()))
~FlannSearch() override
Destructor for FlannSearch.
bool setInputCloud(const PointCloudConstPtr &cloud, const IndicesConstPtr &indices=IndicesConstPtr()) override
Provide a pointer to the input dataset.
PointRepresentationConstPtr point_representation_
shared_ptr< FlannIndexCreator > FlannIndexCreatorPtr
int nearestKSearch(const PointT &point, int k, Indices &k_indices, std::vector< float > &k_sqr_distances) const override
Search for the k-nearest neighbors for the given query point.
typename Search< PointT >::PointCloudConstPtr PointCloudConstPtr
typename Search< PointT >::PointCloud PointCloud
FlannIndexCreatorPtr creator_
The index creator, used to (re-) create the index when the search data is passed.
IndexPtr index_
The FLANN index.
shared_ptr< flann::Matrix< float > > MatrixPtr
pcl::IndicesConstPtr IndicesConstPtr
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
IndicesAllocator<> Indices
Type used for indices in PCL.
int radius_search(const FlannIndex &index, const Query &query, Indices &indices, Distances &dists, float radius, const SearchParams ¶ms)
Compatibility template function to allow use of various types of indices with FLANN.
int knn_search(const FlannIndex &index, const Query &query, Indices &indices, Distances &dists, unsigned int k, const SearchParams ¶ms)
Compatibility template function to allow use of various types of indices with FLANN.
A point structure representing Euclidean xyz coordinates, and the RGB color.