ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

PCL教程指南-如何使用KdTree寻找最邻近点

2021-01-09 12:32:32  阅读:686  来源: 互联网

标签:std rand 教程 const PCL KdTree pcl cloud


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有