open3D源码分析第六篇

2021SC@SDUSC


#open3D KDTree类

本篇对KDTreeFlann类和KDTreeSearchParam类进行源码分析。

KDTreeFlann

KDTreeFlann类:使用FLANN进行最近邻居搜索的KDTree。

注意点:

  1. 由于需要解析的代码较多,为使代码解读更加清晰,我将代码分析的详细过程写在代码段的注释中。
  2. 中文部分是源码解读,包含代码分析和遇到的问题。
#pragma once

#include <Eigen/Core>
#include <memory>
#include <vector>

#include "open3d/geometry/Geometry.h"
#include "open3d/geometry/KDTreeSearchParam.h"
#include "open3d/pipelines/registration/Feature.h"

/// @cond
namespace nanoflann {
struct metric_L2;
template <class MatrixType, int DIM, class Distance, bool row_major>
struct KDTreeEigenMatrixAdaptor;
}  // namespace nanoflann
/// @endcond

namespace open3d {
namespace geometry {

/// \class KDTreeFlann
/// 使用FLANN进行最近邻居搜索的KDTree。
class KDTreeFlann {
public:
    ///默认构造函数。
    KDTreeFlann();
    ///参数化构造函数。
    ///参数data 为KDTree构造所提供的一组数据点。
    KDTreeFlann(const Eigen::MatrixXd &data);
    ///参数化构造函数。
    ///参数geometry 为构造KDTree所提供的几何图形。
    KDTreeFlann(const Geometry &geometry);
    ///参数化构造函数。
    ///参数feature 提供一组构造KDTree的特性。
    KDTreeFlann(const pipelines::registration::Feature &feature);
    ~KDTreeFlann();
    KDTreeFlann(const KDTreeFlann &) = delete;
    KDTreeFlann &operator=(const KDTreeFlann &) = delete;

public:
    ///通过一个矩阵设置KDTree的数据。
	///参数data 构造KDTree的数据点。
    bool SetMatrixData(const Eigen::MatrixXd &data);
    ///设置KDTree的数据。
    ///
    ///参数geometry KDTree的几何结构。
    bool SetGeometry(const Geometry &geometry);
    ///根据特性数据设置KDTree的数据。
    ///参数feature KDTree构造的功能集。
    bool SetFeature(const pipelines::registration::Feature &feature);

    template <typename T>
    int Search(const T &query,
               const KDTreeSearchParam &param,
               std::vector<int> &indices,
               std::vector<double> &distance2) const;

    template <typename T>
    int SearchKNN(const T &query,
                  int knn,
                  std::vector<int> &indices,
                  std::vector<double> &distance2) const;

    template <typename T>
    int SearchRadius(const T &query,
                     double radius,
                     std::vector<int> &indices,
                     std::vector<double> &distance2) const;

    template <typename T>
    int SearchHybrid(const T &query,
                     double radius,
                     int max_nn,
                     std::vector<int> &indices,
                     std::vector<double> &distance2) const;

private:
    ///通过其他方法提供的数据中设置KDTree数据。
	///内部方法,根据特性、几何等方式提供的数据设置KDTree的所有成员。
    bool SetRawData(const Eigen::Map<const Eigen::MatrixXd> &data);

protected:
    using KDTree_t = nanoflann::KDTreeEigenMatrixAdaptor<
            Eigen::Map<const Eigen::MatrixXd>,
            -1,
            nanoflann::metric_L2,
            false>;

    std::vector<double> data_;
    std::unique_ptr<Eigen::Map<const Eigen::MatrixXd>> data_interface_;
    std::unique_ptr<KDTree_t> nanoflann_index_;
    size_t dimension_ = 0;
    size_t dataset_size_ = 0;
};

}  // namespace geometry
}  // namespace open3d

KDTreeSearchParam.h

KDTree搜索参数的基类。

#pragma once

namespace open3d {
namespace geometry {

/// \class KDTreeSearchParam
/// KDTree搜索参数的基类。
class KDTreeSearchParam {
public:
    /// \enum SearchType
    /// 指定搜索的搜索类型。
    enum class SearchType {
        Knn = 0,
        Radius = 1,
        Hybrid = 2,
    };

public:
    virtual ~KDTreeSearchParam() {}

protected:
    KDTreeSearchParam(SearchType type) : search_type_(type) {}

public:
    ///获取搜索参数的搜索类型(KNN, Radius, Hybrid)。
    SearchType GetSearchType() const { return search_type_; }

private:
    SearchType search_type_;
};

/// \class KDTreeSearchParamKNN
/// KDTree搜索参数为纯KNN搜索。
class KDTreeSearchParamKNN : public KDTreeSearchParam {
public:
    ///默认构造函数。
    ///参数knn 指定要搜索的knn类型的邻居。默认是30。
    KDTreeSearchParamKNN(int knn = 30)
        : KDTreeSearchParam(SearchType::Knn), knn_(knn) {}

public:
    ///将要搜索的邻居数。
    int knn_;
};

/// \class KDTreeSearchParamRadius
/// KDTree搜索参数的纯半径搜索。
class KDTreeSearchParamRadius : public KDTreeSearchParam {
public:
    ///默认构造函数。
    ///
    ///参数radius 指定搜索半径。
    KDTreeSearchParamRadius(double radius)
        : KDTreeSearchParam(SearchType::Radius), radius_(radius) {}

public:
    ///搜索半径。
    double radius_;
};

/// \class KDTreeSearchParamHybrid
///
///KDTree搜索参数为hybrid KNN和redius搜索。
class KDTreeSearchParamHybrid : public KDTreeSearchParam {
public:
    ///默认构造函数。
    ///
    ///参数radius 指定搜索的半径。
    ///参数max_nn 最大搜索邻居数。
    KDTreeSearchParamHybrid(double radius, int max_nn)
        : KDTreeSearchParam(SearchType::Hybrid),
          radius_(radius),
          max_nn_(max_nn) {}

public:
    ///搜索半径。
    double radius_;
    ///在最大值时,将搜索max_nn邻居。
    int max_nn_;
};

}  // namespace geometry
}  // namespace open3d

小结

本篇我对KDTree相关的类进行了源码分析,使得我更加了解了open3D对于KDTree的实现方式。下一篇是open3D中OCTree的相关类的源码分析。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值