CloudCompare 中的 KDTree详解

CloudCompare 中的 KDTree 详解

1. 什么是 KDTree

KDTreeK 维空间划分树(K-Dimensional Tree),它是一种 用于高效查找最近邻点 的数据结构。
CloudCompare 中的 KDTree 主要用于:

  • 最近邻搜索(Nearest Neighbor Search)
  • 点云匹配和 ICP(Iterative Closest Point)配准
  • 点云去噪
  • 半径范围搜索
  • 点云加速索引

相比 DgmOctree(八叉树),KDTree高维数据查找 方面更高效,特别是在 点云数据较大 时。


2. KDTree 的核心数据结构

KDTree 主要由 KdCell 结构体和 KD 树递归构建、搜索等方法 组成。

class CC_CORE_LIB_API KDTree
{
public:
    //! 默认构造函数
    KDTree();

    //! 析构函数
    virtual ~KDTree();

    //! 构建 KD 树
    bool buildFromCloud(GenericIndexedCloud* cloud, GenericProgressCallback* progressCb = nullptr);

    //! 获取构建 KD 树的点云
    GenericIndexedCloud* getAssociatedCloud() const { return m_associatedCloud; }

    //! 进行最近邻搜索
    bool findNearestNeighbour( const PointCoordinateType* queryPoint,
                               unsigned& nearestPointIndex,
                               ScalarType maxDist );

    //! 进行带最大距离约束的最近邻搜索
    bool findNearestNeighbourWithMaxDist( const PointCoordinateType* queryPoint,
                                          ScalarType maxDist );

    //! 在给定距离范围内查找点
    unsigned radiusSearch( const PointCoordinateType* queryPoint,
                           ScalarType distance,
                           ScalarType tolerance,
                           std::vector<unsigned>& pointIndexes );

protected:
    struct KdCell
    {
        unsigned cuttingDim;         // 划分维度(x/y/z)
        PointCoordinateType cuttingCoordinate;  // 划分位置
        struct KdCell* leSon;       // 左子节点
        struct KdCell* gSon;        // 右子节点
        struct KdCell* father;      // 父节点
        unsigned startingPointIndex; // 该单元格中的起始点索引
        unsigned nbPoints;           // 该单元格包含的点数

        CCVector3 inbbmax; // 内部包围盒最大坐标
        CCVector3 inbbmin; // 内部包围盒最小坐标
        CCVector3 outbbmax; // 外部包围盒最大坐标
        CCVector3 outbbmin; // 外部包围盒最小坐标
    };

    KdCell* m_root;                    // 根节点
    std::vector<unsigned> m_indexes;    // 点索引
    GenericIndexedCloud* m_associatedCloud; // 关联的点云数据
    unsigned m_cellCount;               // 树中的单元格数
};

3. KDTree 的主要功能

(1)构建 KD 树

CloudCompare 通过 KDTree::buildFromCloud() 方法来 构建 KD 树

CCCoreLib::KDTree kdTree;
kdTree.buildFromCloud(&cloud);

构建 KD 树后,点云数据被组织成 层级化的树结构,便于加速最近邻搜索。


(2)最近邻搜索

findNearestNeighbour() 方法

查找最近邻点

CCCoreLib::KDTree kdTree;
unsigned nearestPointIndex;
CCVector3 queryPoint(1.0, 2.0, 3.0);
bool found = kdTree.findNearestNeighbour(queryPoint.u, nearestPointIndex, 10.0);
  • queryPoint 是查询点
  • nearestPointIndex 返回找到的最近邻点索引
  • 10.0 是搜索的最大距离阈值

返回值

  • true:找到最近点,且其距离 ≤ maxDist
  • false:未找到

findNearestNeighbourWithMaxDist() 方法

优化的最近邻搜索,仅判断是否存在某个点在 maxDist 以内:

bool exists = kdTree.findNearestNeighbourWithMaxDist(queryPoint.u, 10.0);

findNearestNeighbour() 速度更快,因为它不需要返回最近点的具体索引。


(3)半径范围搜索

radiusSearch() 方法用于 查找所有位于给定半径范围内的点

std::vector<unsigned> neighbors;
float searchRadius = 5.0;
float tolerance = 0.1;
unsigned count = kdTree.radiusSearch(queryPoint.u, searchRadius, tolerance, neighbors);

返回 位于 [radius - tolerance, radius + tolerance] 之间的所有点的索引


(4)递归 KD 树操作

KD 树的搜索和索引操作涉及递归遍历:

计算点到单元格的距离
ScalarType distance = kdTree.pointToCellSquareDistance(queryPoint.u, kdCell);

计算点到 KD 树单元格的平方距离。


递归遍历 KD 树查找最近点
int closestIndex = kdTree.checkClosestPointInSubTree(queryPoint.u, maxDist, kdCell);
  • 递归遍历 KD 树
  • 仅返回 maxDist 更近的点
  • 用于优化搜索速度

4. KDTree vs DgmOctree

数据结构 KDTree DgmOctree
主要用途 最近邻搜索 点云索引、邻域搜索
适用数据 任意维度的点云数据 三维点云
构建复杂度 O(n log n) O(n)
查询速度 O(log n) O(log n)
适用场景 ICP、点匹配、密集点云处理 点云分割、降采样、大规模点云

5. KDTree 的应用

(1)ICP(迭代最近点)配准

CloudCompare 使用 KDTree加速 ICP 计算最近邻点

CCCoreLib::ICPRegistrationTools::Parameters params;
params.kdTree = &kdTree;  // 使用 KD 树加速
CCCoreLib::ICPRegistrationTools::Result result;
CCCoreLib::ICPRegistrationTools::Register(&sourceCloud, &targetCloud, params, result);

(2)点云去噪

在 CloudCompare 进行 统计滤波 时,可用 KDTree 进行 K 近邻搜索

std::vector<unsigned> neighbors;
unsigned k = 10;  // 查找最近的 10 个邻居
for (size_t i = 0; i < cloud.size(); ++i)
{
    kdTree.findNearestNeighbour(cloud.getPoint(i).u, k, neighbors);
}
  • 计算点周围的 均值和标准差
  • 过滤掉离群点(噪声)

(3)点云匹配

CloudCompare 进行 点云配准时,可以使用 KDTree 加速最近邻搜索,从而提高计算效率。


6. 总结

KDTree加速最近邻搜索 的核心数据结构
✅ 适用于 ICP、点云去噪、K 近邻搜索、半径范围查询
✅ 对于 大规模点云数据KDTreeDgmOctree 更高效
✅ CloudCompare 通过 KDTree 优化 ICP 配准、点云匹配和点云降噪

你可能感兴趣的:(点云数据处理技术,算法,人工智能,数据结构,数据结构)