其他分享
首页 > 其他分享> > KdTree && Octree 原理学习对比以及可视化分析--"索引树"

KdTree && Octree 原理学习对比以及可视化分析--"索引树"

作者:互联网

1. Kdtree 原理

k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构。主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索);

索引结构中相似性查询有两种基本的方式:
(1). "范围查询" :给定查询点和查询距离的阈值,从数据集中找出所有与查询点距离小于阈值的数据;
(2). "K近邻查询" :K近邻查询是给定查询点及正整数K,从数据集中找到距离查询点最近的"K"个数据,当K=1,则为[最近邻查询];

 

2.Octree原理

Octree即为八叉树,它的特性为树中的任一节点的子节点恰好只会有八个或零个。经常应用于3D场景管理,它可以迅速搜索物体在3D场景中的位置,或侦测到与其他物体是否有碰撞以及判断是否在可视范围内。

"算法原理简介"
    八叉树是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素,每个节点有八个子节点,将八个子节点所表示的体积元素加在一起就等于父节点的体积。
"算法流程"
    (1). 设定最大递归深度
    (2). 找出场景的最大尺寸,并以此尺寸建立第一个立方体
    (3). 依序将单位元元素丢入能被包含且没有子节点的立方体
    (4). 若没有达到最大递归深度,就进行细分八等份,再将该立方体所装的单位元元素全部分担给八个子立方体
    (5). 若发现子立方体所分配到的单位元元素数量不为零且跟父立方体是一样的,则该子立方体停止细分,因为跟据空间分割理论,细分的空间所得到的分配必定较少,若是一样数目,则再怎么切数目还是一样,会造成无穷切割的情形。
    (6). 重复3,直到达到最大递归深度。

3.PCL中源代码测试

"Kdtree"
/*
* kdtree: 
* 是一种分割K维数据空间的数据结构,主要应用于多维空间关键数据的搜索
* (范围搜索 + 最近邻搜索)
*                                           Author: Ian
*/

#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>

#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char** argv)
{

    string inputfile = argv[1];

    pcl::PointCloud<pcl::PointXYZ> xyzCloud;
    pcl::PointCloud<pcl::PointXYZRGBA> rgbCloud;

    pcl::io::loadPCDFile<pcl::PointXYZ> (inputfile, xyzCloud);
    cout<<"input cloud's size ="<<xyzCloud.points.size()<<endl;

    pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
    kdtree.setInputCloud(xyzCloud.makeShared());

    pcl::PointXYZ searchPoint;

//  取点云数据的中间点
    searchPoint = xyzCloud.points[xyzCloud.points.size()/2];

// k nearest neighbor search 
    int K=10;
    std::vector<int> pointIdxNKNSearch(K);
    std::vector<float> pointNKNSquaredDistance(K);

    if(kdtree.nearestKSearch (searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
    {
        std::cout<<"pointIdxNKNSearch.size ="<<pointIdxNKNSearch.size()<<std::endl;

        for (size_t i = 0; i < pointIdxNKNSearch.size(); ++i)
        std::cout << "    "  <<   xyzCloud.points[ pointIdxNKNSearch[i] ].x 
                    << " " << xyzCloud.points[ pointIdxNKNSearch[i] ].y 
                    << " " << xyzCloud.points[ pointIdxNKNSearch[i] ].z 
                    << " (NKN-squared distance: " << pointNKNSquaredDistance[i] << ")" << std::endl;
    }
//  Neighbors within radius search

  std::vector<int> pointIdxRadiusSearch;
  std::vector<float> pointRadiusSquaredDistance;

  float radius = 0.3f;

    if (kdtree.radiusSearch(searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0)
    {
        std::cout<<"pointIdxRadiusSearch.size = "<<pointIdxRadiusSearch.size()<<std::endl;
        for (size_t i = 0; i < pointIdxRadiusSearch.size(); ++i)
        std::cout << "   "  <<   xyzCloud.points[ pointIdxRadiusSearch[i] ].x 
                    << " " << xyzCloud.points[ pointIdxRadiusSearch[i] ].y 
                    << " " << xyzCloud.points[ pointIdxRadiusSearch[i] ].z 
                    << " (Radius-squared distance: " << pointRadiusSquaredDistance[i] << ")" << std::endl;
    }

    return 0;
}

"Octree"
    /*
* Octree --八叉树, 用于快速查询物体在3D场景中的位置,或侦测
*       与其他物体是否有碰撞以及是否在可视范围内。
*                                           Author: Ian 
*/

#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/octree/octree_search.h>

#include <iostream>
#include <vector>

int main(int argc, char**argv)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr xyzCloud(new pcl::PointCloud<pcl::PointXYZ>);

    std::string inputfile = argv[1];
    pcl::io::loadPCDFile<pcl::PointXYZ> (inputfile, *xyzCloud);
    std::cout<<"inputPCD's size ="<<xyzCloud->points.size()<<std::endl;

    float resolution = 0.01f;
    pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree(resolution);

    octree.setInputCloud(xyzCloud);
    octree.addPointsFromInputCloud();

    pcl::PointXYZ searchPoint;
    searchPoint = xyzCloud->points[xyzCloud->points.size()/2];

    std::vector<int> pointIdxVec;

    if(octree.voxelSearch (searchPoint, pointIdxVec))
    {
        std::cout << "Neighbors within voxel search at (" << searchPoint.x 
        << " " << searchPoint.y 
        << " " << searchPoint.z << ")" 
        << std::endl;

        std::cout<<"voxelSearch size = "<<pointIdxVec.size()<<std::endl;

        for (size_t i = 0; i < pointIdxVec.size (); ++i)
            std::cout << "    " << xyzCloud->points[pointIdxVec[i]].x 
                << " " << xyzCloud->points[pointIdxVec[i]].y 
                << " " << xyzCloud->points[pointIdxVec[i]].z << std::endl;
    }

    // K nearest neighbor search

    int K = 10;

    std::vector<int> pointIdxNKNSearch;
    std::vector<float> pointNKNSquaredDistance;

    if(octree.nearestKSearch (searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
    {
        for (size_t i = 0; i < pointIdxNKNSearch.size (); ++i)
        std::cout << "    "  <<   xyzCloud->points[ pointIdxNKNSearch[i] ].x 
                    << " " << xyzCloud->points[ pointIdxNKNSearch[i] ].y 
                    << " " << xyzCloud->points[ pointIdxNKNSearch[i] ].z 
                    << " (NKN-squared distance: " << pointNKNSquaredDistance[i] << ")" << std::endl;
    }

    // Neighbors within radius search

    std::vector<int> pointIdxRadiusSearch;
    std::vector<float> pointRadiusSquaredDistance;

    float radius = 0.3f;

    std::cout << "Neighbors within radius search at (" << searchPoint.x 
        << " " << searchPoint.y 
        << " " << searchPoint.z
        << ") with radius=" << radius << std::endl;


    if (octree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0)
    {
        for (size_t i = 0; i < pointIdxRadiusSearch.size (); ++i)
            std::cout << "    "  <<   xyzCloud->points[ pointIdxRadiusSearch[i] ].x 
                        << " " << xyzCloud->points[ pointIdxRadiusSearch[i] ].y 
                        << " " << xyzCloud->points[ pointIdxRadiusSearch[i] ].z 
                        << " (Radius-squared distance: " << pointRadiusSquaredDistance[i] << ")" << std::endl;
    }


    return 0;
}

4.Octree可视化分析

参考链接

[1]. K-dtree 百度百科

[2]. Octree 百度百科

 

 

标签:std,pcl,KdTree,points,Octree,&&,xyzCloud,include,节点
来源: https://blog.csdn.net/qq_29797957/article/details/96430150