PCL教程指南-如何使用KdTree寻找最邻近点
作者:互联网
PCL教程指南-如何使用KdTree寻找最邻近点
- 官方原文档
- KdTree原理官方文档详解,简单概括 利用二叉树结构在高维度的应用,按各维度中相近的数据组织,用于查找邻近点
- 对原文档代码解读,并扩展其他内容
#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));
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
// 生成1000个点的点云数据
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);
}
//FLANN 快速近似近邻算法库实现的KdTree
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邻近搜索个数
int K = 10;
//保存邻近点索引
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;
//最邻近查找,返回邻近点数
if ( kdtree.nearestKSearch (searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) > 0 )
{
for (std::size_t i = 0; i < pointIdxNKNSearch.size (); ++i)
std::cout << " " << (*cloud)[ pointIdxNKNSearch[i] ].x
<< " " << (*cloud)[ pointIdxNKNSearch[i] ].y
<< " " << (*cloud)[ pointIdxNKNSearch[i] ].z
<< " (squared distance: " << pointNKNSquaredDistance[i] << ")" << std::endl;
}
// 半径内邻近查找,与K邻近区别在于 对象点规定半径内寻找而不是设置个数
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;
}
-
其中
pcl::KdTreeFLANN<pcl::PointXYZ>
基于FLANN库实现的KDTree除了可以搜索点还能搜索特征pcl::KdTreeFLANN<FeatureT>
一般用于寻找匹配点对 -
其他操作方法中使用到KDtree的时候,通常使用搜索模块封装的Kdtree类即
pcl::search::KdTree< PointT, Tree >
,用于在Kdtree结构中执行搜索方法,此类与FLANN实现的Kdtree类均继承了pcl::Kdtree
,另外搜索模块封装的Kdtree还继承了搜索类pcl::search::Search< PointT >
,这也是其与FLANN库实现的Kdtree的区别。使用方面基本一致,只是实现方式不同,FLANN目的更多是单独使用时加速。 -
关于KdTree相关内容有两个常用方法
方法 | 作用 |
---|---|
void pcl::getApproximateIndices (const typename pcl::PointCloud< PointT >::ConstPtr &cloud_in, const typename pcl::PointCloud< PointT >::ConstPtr &cloud_ref, std::vector< int > &indices) | 基于KdTree实现的一个直接近似搜索原点云在参考点云上的索引(#include <pcl/kdtree/io.h>) |
void setPointRepresentation (const PointRepresentationConstPtr &point_representation) | 此为KdTree类中方法,用于设置一个点表示指针,PointRepresentation也是一个类作用是将点结构按比例输出为向量或数组,在这里作用是转换点为K-D向量 |
补充:
pcl::PointRepresentation< PointT >
:点表示类,常用方法有
void vectorize (const PointT &p, OutputType &out) const
点结构矢量化,例如将pointXYZ转换为vector<3,1>void setRescaleValues (const float *rescale_array)
设置缩放比例,可以在转换时缩放int getNumberOfDimensions () const
得到点属性维度- 需要注意的是 这是一个抽象类,真正使用时需要自己写子类继承重写
标签:std,rand,教程,const,PCL,KdTree,pcl,cloud 来源: https://blog.csdn.net/qq_41795143/article/details/112384075