学习记录
#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;
}