PCL点云库:Kd树

  Kd树按空间划分生成叶子节点,各个叶子节点里存放点数据,其可以按半径搜索或邻区搜索。PCL中的Kd tree的基础数据结构使用了FLANN以便可以快速的进行邻区搜索。FLANN is a library for performing fast approximate nearest neighbor searches in high dimensional spaces。下面是一个最基本的例子,只寻找一个最近点:

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

#include <iostream>
#include <vector>
#include <ctime>


int main (int argc, char** argv)
{
    srand (time (NULL));  //seeds rand() with the system time 

    time_t begin,end;
    begin = clock();  //开始计时
    //-------------------------------------------------------------------------------
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

    // Generate pointcloud data
    cloud->width = 400000;
    cloud->height = 1;
    cloud->points.resize (cloud->width * cloud->height);

    // fills a PointCloud with random data
    for (size_t i = 0; i < cloud->points.size (); ++i)
    {
        cloud->points[i].x = 1024.0f * rand () / (RAND_MAX + 1.0f);
        cloud->points[i].y = 1024.0f * rand () / (RAND_MAX + 1.0f);
        cloud->points[i].z = 1024.0f * rand () / (RAND_MAX + 1.0f);
    }

    // creates kdtree object
    pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;

    // sets our randomly created cloud as the input
    kdtree.setInputCloud (cloud);

    //create a “searchPoint” which is assigned random coordinates
    pcl::PointXYZ searchPoint;

    searchPoint.x = 1024.0f * rand () / (RAND_MAX + 1.0f);
    searchPoint.y = 1024.0f * rand () / (RAND_MAX + 1.0f);
    searchPoint.z = 1024.0f * rand () / (RAND_MAX + 1.0f);


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

    std::cout << "K nearest neighbor search at (" << searchPoint.x 
        << " " << searchPoint.y 
        << " " << searchPoint.z
        << ") with K=" << K << std::endl;

    /***********************************************************************************************
    template<typename PointT> 
    virtual int pcl::KdTree< PointT >::nearestKSearch  ( const PointT &  p_q,  
                                                        int  k,  
                                                        std::vector< int > &  k_indices,  
                                                        std::vector< float > &  k_sqr_distances  
                                                        )  const [pure virtual] 

    Search for k-nearest neighbors for the given query point. 
    Parameters:
        [in] the given query point 
        [in] k the number of neighbors to search for  
        [out] the resultant indices of the neighboring points
        [out] the resultant squared distances to the neighboring points
    Returns:
        number of neighbors found 
    ********************************************************************************************/
    if ( kdtree.nearestKSearch (searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) > 0 )
    {
        for (size_t i = 0; i < pointIdxNKNSearch.size (); ++i)
            std::cout << "    "  <<   cloud->points[ pointIdxNKNSearch[i] ].x 
            << " " << cloud->points[ pointIdxNKNSearch[i] ].y 
            << " " << cloud->points[ pointIdxNKNSearch[i] ].z 
            << " (squared distance: " << pointNKNSquaredDistance[i] << ")" << std::endl;
    }
    //--------------------------------------------------------------------------------------------
    end = clock();  //结束计时
    double Times =  double(end - begin) / CLOCKS_PER_SEC; //将clock()函数的结果转化为以秒为单位的量

    std::cout<<"time: "<<Times<<"s"<<std::endl;

    return 0;
}

  生成四十万个随机点,release版本下测试0.3s左右找到最近点,这比之前自己写的Kd树不知快到哪里去了。当然自己写只是为了更好的理解其中的原理,真要用的时候还得靠别人的轮子...

 

参考:

How to use a KdTree to search

Module kdtree

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: pcl点云是一个用于处理点云数据的开源。它提供了各种功能,包括对点云进行排序。在pcl中,可以通过点的某个属性来对点云进行排序。 排序点云的常见方法之一是依据点的坐标。可以通过pcl::PointCloud类的points成员来访问点云中的点,并使用std::sort函数对points数组进行排序。例如,可以根据点的x坐标将点云进行排序: ``` pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 将点云数据读入到cloud中... // 按照x坐标对点云进行排序 std::sort(cloud->points.begin(), cloud->points.end(), [](const pcl::PointXYZ& a, const pcl::PointXYZ& b) { return a.x < b.x; }); ``` 上述代码中,我们使用了lambda表达式来定义排序函数,使得点按照x坐标递增的方式进行排序。通过将排序函数作为第三个参数传递给std::sort函数,我们可以对点云按照x坐标进行排序。 除了按照坐标进行排序外,还可以根据点的其他属性进行排序,例如颜色或法向量等。只需要修改lambda表达式中的排序规则即可。 总之,pcl点云提供多种方法用于对点云进行排序。通过选择适当的排序规则,可以对点云数据进行有效的排序操作。 ### 回答2: PCL(点云)是一个流行的开源,用于对点云进行处理和分析。它包含了多种功能,其中之一就是对点云进行排序。 点云排序是将点云数据按照一定的顺序重新排列的过程。这种排序可以基于点云的某个属性进行,比如坐标、颜色或法线。通过对点云进行排序,可以使得点云数据更有组织性,便于进一步的分析和处理。 PCL中提供了多种点云排序算法,例如KD Tree(k-最近邻搜索)和Octree(八叉树)。这些算法根据点云数据的特点进行优化,能够高效地对大规模的点云进行排序。 使用PCL对点云进行排序的步骤如下: 1. 首先,将点云数据加载到PCL的数据结构中,可以使用PCL的PointCloud类来表示点云。 2. 接下来,选择适当的排序算法,并创建相应的排序对象。比如,使用KDTree进行排序,可以创建一个KdTreeFLANN对象。 3. 将点云数据传入排序对象中,使用sort()等方法对点云进行排序。 4. 排序完成后,可以根据需要获取已排序的点云数据,比如通过调用getSortedResults()方法获取排序结果。 通过PCL对点云进行排序,可以以一种可靠且高效的方式对大规模的点云数据进行处理。这对于点云分析、三维建模等领域非常有用。同时,PCL还提供了丰富的点云处理功能,包括滤波、分割、配准等,可以进一步完善点云处理的流程。 ### 回答3: pcl点云点云进行排序的方法有多种。一种常用的方法是基于点的某个属性值进行排序,例如点的坐标、法向量、颜色等属性。通过设定排序的准则,可以将点云按照这些属性值进行升序或降序排列。 对于点的坐标排序,可以使用pcl::PointCloud类中的points成员变量,它是一个std::vector,存储了点云中的所有点。可以通过自定义排序函数,传递给std::sort函数来对点进行排序。例如,可以根据点的X坐标进行排序,调用std::sort函数进行升序排列。 对于其他属性值的排序,可以通过自定义排序函数来实现。根据具体需求,可以对点的法向量、颜色等属性进行排序。需要注意的是,在自定义排序函数时,要根据属性值的类型,使用相应的比较运算符进行比较操作,确保正确的排序结果。 除了上述方法之外,pcl点云还提供了一些排序算法函数,例如pcl::KdTreeFLANN类中的nearestKSearch函数,将根据点与目标点最近邻的距离进行排序。 总之,pcl点云通过自定义排序函数和提供的排序算法函数,可以便捷地对点云进行排序。通过设定排序的准则,可以按照点的坐标、法向量、颜色等属性对点云进行升序或降序排列,满足不同应用的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值