KD-Tree 的开源实现与OpenCV中的实现

本文提供了一个自定义的KD-Tree模板类实现,支持最近邻搜索、K近邻搜索和一定范围内的邻居搜索。通过示例代码展示了如何使用该KD-Tree进行点查找操作,并与OpenCV的KDTree进行了KNN搜索速度的比较。总结指出,对于NN搜索,开源KD-Tree更快,而OpenCV的KNN搜索更优。
KD-Tree 开源实现代码
  • 添加头文件 #include <KDTree.hpp>
  • 测试代码及源文件 下载链接(OpenCV version: 4.5.1)
  • hpp 文件名为 “KDTree.hpp”
#ifndef __KDTREE_H__
#define __KDTREE_H__

#include <algorithm>
#include <cmath>
#include <exception>
#include <functional>
#include <numeric>
#include <vector>

namespace obstarcalib::caliblink {
   
   
/** @brief k-d tree class.
 */
template <typename PointT, int DIM = 2, typename Allocator = std::allocator<PointT>>
class KDTree {
   
   
public:
    /** @brief The constructors.
     */
    KDTree()
        : root_(nullptr) {
   
   };
    KDTree(const std::vector<PointT, Allocator>& points)
        : root_(nullptr)
    {
   
   
        build(points);
    }

    /** @brief The destructor.
     */
    ~KDTree() {
   
    clear(); }

    /** @brief Re-builds k-d tree.
     */
    void build(const std::vector<PointT, Allocator>& points)
    {
   
   
        clear();

        points_ = points;

        std::vector<int> indices(points.size());
        std::iota(std::begin(indices), std::end(indices), 0);

        root_ = buildRecursive(indices.data(), (int)points.size(), 0);
    }

    /** @brief Clears k-d tree.
     */
    void clear()
    {
   
   
        clearRecursive(root_);
        root_ = nullptr;
        points_.clear();
    }

    /** @brief Validates k-d tree.
     */
    bool validate() const
    {
   
   
        try {
   
   
            validateRecursive(root_, 0);
        } catch (const Exception&) {
   
   
            return false;
        }

        return true;
    }

    /** @brief Searches the nearest neighbor.
     */
    int nnSearch(const PointT& query, double* minDist = nullptr) const
    {
   
   
        int guess;
        double _minDist = std::numeric_limits<double>::max();

        nnSearchRecursive(query, root_, &guess, &_minDist);

        if (minDist)
            *minDist = _minDist;
            
        return guess;
    }

    /** @brief Searches k-nearest neighbors.
     */
    std::vector<int> knnSearch(const PointT& query, int k) const
    {
   
   
        KnnQueue queue(k);
        knnSearchRecursive(query, root_, queue, k);

        std::vector<int> indices(queue.size());
        for (size_t i = 0; i < queue.size(); i++)
            indices[i] = queue[i].second;

        return indices;
    
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值