pcl官网中kdtree模块代码示例与详细分析

 学习记录

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

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

int
main ()
{
    /*用于设置随机数生成器的种子。它使用了C/C++的标准库函数。
    srand 是用于设置随机数生成器种子的函数。
    time 函数返回自1970年1月1日以来的秒数,这个值是一个时间戳,代表了当前的日期和时间。
    (NULL) 是一个指向空指针的指针,空指针在C/C++中表示不存在任何值,
    因此 time(NULL) 返回的是程序开始运行时的秒数。
    这段代码的意思是,将随机数生成器的种子设置为程序开始运行时的秒数。
    由于种子是随时间变化的,因此每次运行程序时,随机数生成器的行为都会有所不同。
    这样可以使随机数生成器产生不同的随机数序列,以便在程序中进行随机性的操作。*/
    srand (time (NULL));
    
	/*创建点云指针,pcl::PointCloud<pcl::PointXYZ>::Ptr: 
    这是定义一个指向 pcl::PointCloud<pcl::PointXYZ> 对象的智能指针。
    pcl::PointCloud 是 PCL 中的一个类,用于存储大量的3D点(每个点有X,Y,Z三个坐标)。
    pcl::PointXYZ 是表示单个3D点的类。
	cloud: 这是定义的智能指针变量名。
    new pcl::PointCloud<pcl::PointXYZ>: 这是使用new关键字动态分配内存来创建一个
    新的pcl::PointCloud<pcl::PointXYZ> 对象。
	所以,这段代码的意思是创建一个空的、动态分配的 pcl::PointCloud<pcl::PointXYZ> 对象,
    并将其智能指针赋值给变量 cloud。
    此后,你可以通过这个智能指针来访问或者修改这个点云对象。*/
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

    // Generate pointcloud data,使用随即数据创建并填充pointcloud
    cloud->width = 1000;
    cloud->height = 1;
    cloud->points.resize (cloud->width * cloud->height);

    /*for (std::size_t i = 0; i < cloud->size (); ++i): 
    这是一个for循环,它遍历点云中的每一个点。std::size_t是无符号整数类型,用于计数。
    cloud是一个指向pcl::PointCloud对象的指针,cloud->size()返回点云中的点数。
    (*cloud)[i].x = 1024.0f * rand () / (RAND_MAX + 1.0f);
    这行代码设置点云中第i个点的x坐标为1024.0乘以一个随机数除以(RAND_MAX + 1.0)。
    这确保了结果是在0.0到1024.0之间,生成的是均匀分布的随机数。*/
    for (std::size_t i = 0; i < cloud->size (); ++i)
        {
            (*cloud)[i].x = 1024.0f * rand () / (RAND_MAX + 1.0f);
            (*cloud)[i].y = 1024.0f * rand () / (RAND_MAX + 1.0f);
            (*cloud)[i].z = 1024.0f * rand () / (RAND_MAX + 1.0f);
        }

    /*创建kdtree对象,这段代码是使用点云库PCL(Point Cloud Library)
    中的KdTreeFLANN类创建一个KdTree对象的示例。这行代码声明了一个名为kdtree的变量,
    该变量的类型是pcl::KdTreeFLANN<pcl::PointXYZ>。这意味着它是一个KdTree对象,
    用于处理点云数据中的空间搜索问题。具体来说,这里的模板参数pcl::PointXYZ
    指定了该KdTree对象将用于处理的数据类型为pcl::PointXYZ,这是PCL中表示点云数据点的类型。*/
    pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;

    /*向kdtree中传入数据,即将点云数据设置成kdtree结构,setInputCloud方法用于将一个点云数据集设置到KdTree对象中。
    这个数据集被用来构建KdTree。*/
    kdtree.setInputCloud (cloud);

    /*随机生成一个点,这段代码是使用PCL(Point Cloud Library)库的C++语言示例,
    其中pcl::PointXYZ searchPoint;是声明一个名为searchPoint的pcl::PointXYZ类型的变量。
    pcl::PointXYZ是PCL库中用于表示点云数据中单个点的类。每个点有三个坐标值:X,Y和Z。
    这些坐标定义了点在三维空间中的位置。
    例如,你可能想要存储一个你正在查找的点的坐标,或者你可能想要存储一个你正在使用的基准点的坐标。
    请注意,如果你想在点云数据中查找特定的点,你可能需要使用PCL库中的搜索方法,
    如K近邻搜索(K-nearest neighbor search)。
    在这种情况下,searchPoint可能会被用来作为搜索的输入点,以查找在点云数据中最接近它的点。*/
    pcl::PointXYZ searchPoint;

    /*随机设置该点的坐标值。使用了rand()函数来生成一个随机数,*/
    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 = 10;

    /*k近邻搜索,即搜索该点周围的10个点。
    std::vector<int> 是一个 C++ 标准库容器,用于存储整数类型(int)的元素。
    每个元素在内存中都有一个连续的存储位置,并且可以通过索引访问。pointIdxKNNSearch(K) 
	这个函数名可能意味着它执行 K-最近邻搜索(K-Nearest Neighbor Search)以找到一些点。*/
    std::vector<int> pointIdxKNNSearch(K);

    /*设置搜索距离为10*/
    std::vector<float> pointKNNSquaredDistance(K);

    /*std::cout 是C++标准库中的一个输出流对象,用于将数据输出到控制台。
    <<是一个插入运算符,用于将右侧的数据插入到左侧的输出流中。
    searchPoint.x、searchPoint.y 和 searchPoint.z 是要输出的坐标值,
    它们表示一个三维空间中的点的坐标。K是要搜索的最近邻居的数量。
    std::endl 是一个换行符,用于在输出后添加一个换行符。*/
    std::cout << "K nearest neighbor search at (" << searchPoint.x 
        << " " << searchPoint.y 
        << " " << searchPoint.z
        << ") with K=" << K << std::endl;

    /*开始k近邻搜索,nearestKSearch函数可能是kdtree类的成员函数,
    用于在KD-Tree中查找最近的K个点。这个函数可能返回找到的邻居的数量,
    如果找到了至少一个邻居(返回值大于0),则执行花括号中的代码。
    花括号中的代码是一个for循环,遍历所有找到的邻居,
    并打印出每个邻居的坐标以及它到搜索点的平方距离。
    pointIdxKNNSearch是一个存储找到的邻居的索引的向量,
    pointKNNSquaredDistance是一个存储这些邻居到搜索点的平方距离的向量。
    这两个向量的长度都是K,因为我们要查找的是最近的K个点。
    (*cloud)[ pointIdxKNNSearch[i] ].x, (*cloud)[ pointIdxKNNSearch[i] ].y, 
    和 (*cloud)[ pointIdxKNNSearch[i] ].z 这些表达式可能是用来从数据云中获取每个邻居的坐标的。
    这个数据云可能是一个包含三维坐标的数据集,每个坐标都有一个唯一的索引,
    这些索引被存储在pointIdxKNNSearch向量中。*/
    if ( kdtree.nearestKSearch (searchPoint, K, pointIdxKNNSearch, pointKNNSquaredDistance) > 0 )
    {
        for (std::size_t i = 0; i < pointIdxKNNSearch.size (); ++i)
            std::cout << "    "  <<   (*cloud)[ pointIdxKNNSearch[i] ].x 
                << " " << (*cloud)[ pointIdxKNNSearch[i] ].y 
                << " " << (*cloud)[ pointIdxKNNSearch[i] ].z 
                << " (squared distance: " << pointKNNSquaredDistance[i] << ")" << std::endl;
    }

    // Neighbors within radius search

	/*使用半径搜索条件搜索,声明了两个变量,名为pointIdxRadiusSearch。
    此向量可能用于存储满足某个半径内的点的索引。名为pointRadiusSquaredDistance。
    这个向量可能用于存储与上述的点相关的平方距离。*/
    std::vector<int> pointIdxRadiusSearch;
    std::vector<float> pointRadiusSquaredDistance;

    /*随机生成一个搜索半径,范围是(0,256)*/
    float radius = 256.0f * rand () / (RAND_MAX + 1.0f);

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

	/*开始半径搜索,radiusSearch函数可能是KD-Tree类的成员函数,
    用于在KD-Tree中查找在给定半径内的所有点。
    如果找到了至少一个点(返回值大于0),则执行花括号中的代码。
    花括号中的代码是一个for循环,遍历所有找到的点,并打印出每个点的坐标以及它到搜索点的平方距离。
    pointIdxRadiusSearch是一个存储找到的点的索引的向量,
    pointRadiusSquaredDistance是一个存储这些点到搜索点的平方距离的向量。
    这两个向量的长度是由radiusSearch函数返回的,表示找到的点的数量。
    std::size_t是C++标准库中的一种数据类型,它是一个无符号整型类型,
    通常用于表示大小,如数组的大小,容器的大小等。*/
    if ( kdtree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0 )
    {
        for (std::size_t i = 0; i < pointIdxRadiusSearch.size (); ++i)
            std::cout << "    "  <<   (*cloud)[ pointIdxRadiusSearch[i] ].x 
                << " " << (*cloud)[ pointIdxRadiusSearch[i] ].y 
                << " " << (*cloud)[ pointIdxRadiusSearch[i] ].z 
                << " (squared distance: " << pointRadiusSquaredDistance[i] << ")" << std::endl;
    }


    return 0;
}

运行结果

 点的坐标和半径大小都是随机产生的,所以每次的运行结果会有不同。

附上不带注释的完整代码

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

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

int
main ()
{
    srand (time (NULL));

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

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

    for (std::size_t i = 0; i < cloud->size (); ++i)
        {
            (*cloud)[i].x = 1024.0f * rand () / (RAND_MAX + 1.0f);
            (*cloud)[i].y = 1024.0f * rand () / (RAND_MAX + 1.0f);
            (*cloud)[i].z = 1024.0f * rand () / (RAND_MAX + 1.0f);
        }
    pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;

    kdtree.setInputCloud (cloud);

    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 = 10;

    std::vector<int> pointIdxKNNSearch(K);
    std::vector<float> pointKNNSquaredDistance(K);

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

    if ( kdtree.nearestKSearch (searchPoint, K, pointIdxKNNSearch, pointKNNSquaredDistance) > 0 )
    {
        for (std::size_t i = 0; i < pointIdxKNNSearch.size (); ++i)
            std::cout << "    "  <<   (*cloud)[ pointIdxKNNSearch[i] ].x
                << " " << (*cloud)[ pointIdxKNNSearch[i] ].y
                << " " << (*cloud)[ pointIdxKNNSearch[i] ].z
                << " (squared distance: " << pointKNNSquaredDistance[i] << ")" << std::endl;
    }

    // Neighbors within radius search

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

    float radius = 256.0f * rand () / (RAND_MAX + 1.0f);

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


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


    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值