40 #ifndef PCL_SEARCH_IMPL_FLANN_SEARCH_H_
41 #define PCL_SEARCH_IMPL_FLANN_SEARCH_H_
47 template <
typename Po
intT,
typename FlannDistance>
48 typename pcl::search::FlannSearch<PointT, FlannDistance>::IndexPtr
51 return (IndexPtr (
new flann::KDTreeSingleIndex<FlannDistance> (*data,flann::KDTreeSingleIndexParams (max_leaf_size_))));
56 template <
typename Po
intT,
typename FlannDistance>
58 creator_ (creator), eps_ (0), input_copied_for_flann_ (false)
61 dim_ = point_representation_->getNumberOfDimensions ();
65 template <
typename Po
intT,
typename FlannDistance>
69 if (input_copied_for_flann_)
70 delete [] input_flann_->ptr();
74 template <
typename Po
intT,
typename FlannDistance>
void
79 convertInputToFlannMatrix ();
80 index_ = creator_->createIndex (input_flann_);
81 index_->buildIndex ();
85 template <
typename Po
intT,
typename FlannDistance>
int
88 assert (point_representation_->isValid (point) &&
"Invalid (NaN, Inf) point coordinates given to nearestKSearch!");
89 bool can_cast = point_representation_->isTrivial ();
94 data =
new float [point_representation_->getNumberOfDimensions ()];
95 point_representation_->vectorize (point,data);
98 float* cdata = can_cast ?
const_cast<float*
> (
reinterpret_cast<const float*
> (&point)): data;
101 flann::SearchParams p(-1);
103 p.sorted = sorted_results_;
104 if (indices.size() !=
static_cast<unsigned int> (k))
105 indices.resize (k,-1);
106 if (dists.size() !=
static_cast<unsigned int> (k))
110 int result = index_->knnSearch (m,i,d,k, p);
114 if (!identity_mapping_)
116 for (
size_t i = 0; i < static_cast<unsigned int> (k); ++i)
118 int& neighbor_index = indices[i];
119 neighbor_index = index_mapping_[neighbor_index];
126 template <
typename Po
intT,
typename FlannDistance>
void
128 const PointCloud& cloud,
const std::vector<int>& indices,
int k, std::vector< std::vector<int> >& k_indices,
129 std::vector< std::vector<float> >& k_sqr_distances)
const
131 if (indices.empty ())
133 k_indices.resize (cloud.
size ());
134 k_sqr_distances.resize (cloud.
size ());
138 for (
size_t i = 0; i < cloud.
size(); i++)
140 assert (point_representation_->isValid (cloud[i]) &&
"Invalid (NaN, Inf) point coordinates given to nearestKSearch!");
144 bool can_cast = point_representation_->isTrivial ();
150 data =
new float[dim_*cloud.
size ()];
151 for (
size_t i = 0; i < cloud.
size (); ++i)
153 float* out = data+i*dim_;
154 point_representation_->vectorize (cloud[i],out);
160 float* cdata = can_cast ?
const_cast<float*
> (
reinterpret_cast<const float*
> (&cloud[0])): data;
163 flann::SearchParams p;
164 p.sorted = sorted_results_;
166 index_->knnSearch (m,k_indices,k_sqr_distances,k, p);
172 k_indices.resize (indices.size ());
173 k_sqr_distances.resize (indices.size ());
177 for (
size_t i = 0; i < indices.size(); i++)
179 assert (point_representation_->isValid (cloud [indices[i]]) &&
"Invalid (NaN, Inf) point coordinates given to nearestKSearch!");
183 float* data=
new float [dim_*indices.size ()];
184 for (
size_t i = 0; i < indices.size (); ++i)
186 float* out = data+i*dim_;
187 point_representation_->vectorize (cloud[indices[i]],out);
189 const flann::Matrix<float> m (data ,indices.size (), point_representation_->getNumberOfDimensions ());
191 flann::SearchParams p;
192 p.sorted = sorted_results_;
194 index_->knnSearch (m,k_indices,k_sqr_distances,k, p);
198 if (!identity_mapping_)
200 for (
size_t j = 0; j < k_indices.size (); ++j)
202 for (
size_t i = 0; i < static_cast<unsigned int> (k); ++i)
204 int& neighbor_index = k_indices[j][i];
205 neighbor_index = index_mapping_[neighbor_index];
212 template <
typename Po
intT,
typename FlannDistance>
int
214 std::vector<int> &indices, std::vector<float> &distances,
215 unsigned int max_nn)
const
217 assert (point_representation_->isValid (point) &&
"Invalid (NaN, Inf) point coordinates given to radiusSearch!");
218 bool can_cast = point_representation_->isTrivial ();
223 data =
new float [point_representation_->getNumberOfDimensions ()];
224 point_representation_->vectorize (point,data);
227 float* cdata = can_cast ?
const_cast<float*
> (
reinterpret_cast<const float*
> (&point)) : data;
230 flann::SearchParams p;
231 p.sorted = sorted_results_;
233 p.max_neighbors = max_nn > 0 ? max_nn : -1;
234 std::vector<std::vector<int> > i (1);
235 std::vector<std::vector<float> > d (1);
236 int result = index_->radiusSearch (m,i,d,static_cast<float> (radius * radius), p);
242 if (!identity_mapping_)
244 for (
size_t i = 0; i < indices.size (); ++i)
246 int& neighbor_index = indices [i];
247 neighbor_index = index_mapping_ [neighbor_index];
254 template <
typename Po
intT,
typename FlannDistance>
void
256 const PointCloud& cloud,
const std::vector<int>& indices,
double radius, std::vector< std::vector<int> >& k_indices,
257 std::vector< std::vector<float> >& k_sqr_distances,
unsigned int max_nn)
const
259 if (indices.empty ())
261 k_indices.resize (cloud.
size ());
262 k_sqr_distances.resize (cloud.
size ());
266 for (
size_t i = 0; i < cloud.
size(); i++)
268 assert (point_representation_->isValid (cloud[i]) &&
"Invalid (NaN, Inf) point coordinates given to radiusSearch!");
272 bool can_cast = point_representation_->isTrivial ();
277 data =
new float[dim_*cloud.
size ()];
278 for (
size_t i = 0; i < cloud.
size (); ++i)
280 float* out = data+i*dim_;
281 point_representation_->vectorize (cloud[i],out);
285 float* cdata = can_cast ?
const_cast<float*
> (
reinterpret_cast<const float*
> (&cloud[0])) : data;
288 flann::SearchParams p;
289 p.sorted = sorted_results_;
292 p.max_neighbors = max_nn > 0 ? max_nn : -1;
293 index_->radiusSearch (m,k_indices,k_sqr_distances,static_cast<float> (radius * radius), p);
299 k_indices.resize (indices.size ());
300 k_sqr_distances.resize (indices.size ());
304 for (
size_t i = 0; i < indices.size(); i++)
306 assert (point_representation_->isValid (cloud [indices[i]]) &&
"Invalid (NaN, Inf) point coordinates given to radiusSearch!");
310 float* data =
new float [dim_ * indices.size ()];
311 for (
size_t i = 0; i < indices.size (); ++i)
313 float* out = data+i*dim_;
314 point_representation_->vectorize (cloud[indices[i]], out);
318 flann::SearchParams p;
319 p.sorted = sorted_results_;
322 p.max_neighbors = max_nn > 0 ? max_nn : -1;
323 index_->radiusSearch (m, k_indices, k_sqr_distances, static_cast<float> (radius * radius), p);
327 if (!identity_mapping_)
329 for (
size_t j = 0; j < k_indices.size (); ++j )
331 for (
size_t i = 0; i < k_indices[j].size (); ++i)
333 int& neighbor_index = k_indices[j][i];
334 neighbor_index = index_mapping_[neighbor_index];
341 template <
typename Po
intT,
typename FlannDistance>
void
344 size_t original_no_of_points = indices_ && !indices_->empty () ? indices_->size () : input_->size ();
346 if (input_copied_for_flann_)
347 delete input_flann_->ptr();
348 input_copied_for_flann_ =
true;
349 index_mapping_.clear();
350 identity_mapping_ =
true;
356 if (!indices_ || indices_->empty ())
359 if (input_->is_dense && point_representation_->isTrivial ())
362 input_flann_ = MatrixPtr (
new flann::Matrix<float> (const_cast<float*>(reinterpret_cast<const float*>(&(*input_) [0])), original_no_of_points, point_representation_->getNumberOfDimensions (),
sizeof (
PointT)));
363 input_copied_for_flann_ =
false;
367 input_flann_ = MatrixPtr (
new flann::Matrix<float> (
new float[original_no_of_points*point_representation_->getNumberOfDimensions ()], original_no_of_points, point_representation_->getNumberOfDimensions ()));
368 float* cloud_ptr = input_flann_->ptr();
369 for (
size_t i = 0; i < original_no_of_points; ++i)
371 const PointT& point = (*input_)[i];
373 if (!point_representation_->isValid (point))
375 identity_mapping_ =
false;
379 index_mapping_.push_back (static_cast<int> (i));
381 point_representation_->vectorize (point, cloud_ptr);
389 input_flann_ = MatrixPtr (
new flann::Matrix<float> (
new float[original_no_of_points*point_representation_->getNumberOfDimensions ()], original_no_of_points, point_representation_->getNumberOfDimensions ()));
390 float* cloud_ptr = input_flann_->ptr();
391 for (
size_t indices_index = 0; indices_index < original_no_of_points; ++indices_index)
393 int cloud_index = (*indices_)[indices_index];
394 const PointT& point = (*input_)[cloud_index];
396 if (!point_representation_->isValid (point))
398 identity_mapping_ =
false;
402 index_mapping_.push_back (static_cast<int> (indices_index));
404 point_representation_->vectorize (point, cloud_ptr);
408 if (input_copied_for_flann_)
409 input_flann_->rows = index_mapping_.size ();
412 #define PCL_INSTANTIATE_FlannSearch(T) template class PCL_EXPORTS pcl::search::FlannSearch<T>;