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得到点属性维度
  • 需要注意的是 这是一个抽象类,真正使用时需要自己写子类继承重写
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用PCL库进行云处理时,可以使用KD树(KDTree)来加速云的搜索和查询操作。下面是一个使用PCL库中的KDTree进行云索引查找的C++代码示例: ```cpp #include <pcl/kdtree/kdtree.h> #include <pcl/point_cloud.h> #include <pcl/point_types.h> int main() { // 创建一个PointCloud对象 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 假设已经从某处获取到了云数据,并填充到cloud中 // 创建一个KDTree对象 pcl::KdTreeFLANN<pcl::PointXYZ> kdtree; // 将云数据填充到KDTree中 kdtree.setInputCloud(cloud); // 假设要查找的的坐标为(p_x, p_y, p_z) float p_x = 1.0; float p_y = 2.0; float p_z = 3.0; // 定义一个pcl::PointXYZ对象来表示要查找的 pcl::PointXYZ search_point; search_point.x = p_x; search_point.y = p_y; search_point.z = p_z; // 定义一个整数变量来存储最近邻的索引 int nearest_index; // 定义一个浮数变量来存储最近邻与查找之间的距离 float nearest_distance; // 使用KDTree进行最近邻搜索 kdtree.nearestKSearch(search_point, 1, nearest_index, nearest_distance); // 输出最近邻的索引和距离 std::cout << "Nearest neighbor index: " << nearest_index << std::endl; std::cout << "Nearest neighbor distance: " << nearest_distance << std::endl; return 0; } ``` 在上面的代码中,我们首先创建了一个PointCloud对象 `cloud` 来存储云数据。接下来,创建了一个KDTree对象 `kdtree`,并将云数据填充到KDTree中。然后,定义了要查找的的坐标,并将其赋值给 `pcl::PointXYZ` 对象 `search_point`。接着,定义了一个整数变量 `nearest_index` 来存储最近邻的索引,以及一个浮数变量 `nearest_distance` 来存储最近邻与查找之间的距离。最后,使用KDTree的 `nearestKSearch` 函数进行最近邻搜索,并输出最近邻的索引和距离。 请注意,上述代码仅给出了使用KDTree进行最近邻搜索的示例,并不包含完整的云读取和填充过程。在实际使用中,你需要根据自己的需求读取和处理云数据,并将其填充到PointCloud对象中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值