nanoflann radius search

时间:2015-05-30 18:11:49

标签: c++ nearest-neighbor kdtree

我试图在项目中使用nanoflann并正在查看矢量矢量和半径搜索示例。

我找不到使用与坐标类型不同的数据类型执行半径搜索的方法。例如,我的坐标是vector的{​​{1}};我试图输入uint8_t类型的半径,但收效甚微。

我在源代码中看到uint32_t(我用于距离)使用带有两个模板参数的metric_L2 structL2_Adaptor本身有三个参数,第三个默认为第一个,如果我正确理解代码,这似乎是个问题。但是,尝试强制使用第三个总是会在半径搜索中产生0个匹配。

有办法做到这一点吗?

编辑:在下面的相同代码中,一切正常。但是,如果我将search_radius(和ret_matches)更改为uint32_t,则radiusSearch方法不起作用。

L2_Adaptor

更多信息:所以似乎距离类型(#include <iostream> #include <Eigen/Dense> #include <nanoflann.hpp> typedef Eigen::Matrix<uint8_t, Eigen::Dynamic, 1> coord_t; using namespace nanoflann; struct Point { coord_t address; Point() {} Point(uint8_t coordinates) : address(coord_t::Random(coordinates)) {} }; struct Container { std::vector<Point> points; Container(uint8_t coordinates, uint32_t l) : points(l) { for(auto& each_location: points) { each_location = Point(coordinates); } } }; struct ContainerAdaptor { typedef ContainerAdaptor self_t; typedef nanoflann::metric_L2::traits<uint8_t, self_t>::distance_t metric_t; typedef KDTreeSingleIndexAdaptor<metric_t, self_t, -1, size_t> index_t; index_t *index; const Container &container; ContainerAdaptor(const int dimensions, const Container &container, const int leaf_max_size = 10) : container(container) { assert(container.points.size() != 0 && container.points[0].address.rows() != 0); const size_t dims = container.points[0].address.rows(); index = new index_t(dims, *this, nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size)); index->buildIndex(); } ~ContainerAdaptor() { delete index; } inline void query(const uint8_t *query_point, const size_t num_closest, size_t *out_indices, uint32_t *out_distances_sq, const int ignoreThis = 10) const { nanoflann::KNNResultSet<uint32_t, size_t, size_t> resultSet(num_closest); resultSet.init(out_indices, out_distances_sq); index->findNeighbors(resultSet, query_point, nanoflann::SearchParams()); } const self_t& derived() const { return *this; } self_t& derived() { return *this; } inline size_t kdtree_get_point_count() const { return container.points.size(); } inline size_t kdtree_distance(const uint8_t *p1, const size_t idx_p2, size_t size) const { size_t s = 0; for (size_t i = 0; i < size; i++) { const uint8_t d = p1[i] - container.points[idx_p2].address[i]; s += d * d; } return s; } inline coord_t::Scalar kdtree_get_pt(const size_t idx, int dim) const { return container.points[idx].address[dim]; } template <class BBOX> bool kdtree_get_bbox(BBOX & bb) const { for(size_t i = 0; i < bb.size(); i++) { bb[i].low = 0; bb[i].high = UINT8_MAX; } return true; } }; void container_demo(const size_t points, const size_t coordinates) { Container s(coordinates, points); coord_t query_pt(coord_t::Random(coordinates)); typedef ContainerAdaptor my_kd_tree_t; my_kd_tree_t mat_index(coordinates, s, 25); mat_index.index->buildIndex(); const uint8_t search_radius = static_cast<uint8_t>(100); std::vector<std::pair<size_t, uint8_t>> ret_matches; nanoflann::SearchParams params; const size_t nMatches = mat_index.index->radiusSearch(query_pt.data(), search_radius, ret_matches, params); for (size_t i = 0; i < nMatches; i++) { std::cout << "idx[" << i << "]=" << +ret_matches[i].first << " dist[" << i << "]=" << +ret_matches[i].second << std::endl; } std::cout << std::endl; std::cout << "radiusSearch(): radius=" << +search_radius << " -> " << +nMatches << " matches" << std::endl; } int main() { container_demo(1e6, 32); return 0; } 的第三个参数)必须是带符号的类型。如果L2_Adaptorsearch_radius也更改为int64_t,则将metric_t typedef更改为以下内容即可解决问题。

ret_matches

0 个答案:

没有答案