首先PCL定义了搜索的基类pcl::search::Search<PointInT>

  1. template<typename PointT>
  2. class Search

其子类包括:KD树,八叉树,FLANN快速搜索,暴力搜索(brute force),有序点云搜索。

The pcl_search library provides methods for searching for nearest neighbors using different data structures, including:

  • kd-trees (via libpcl_kdtree);
  • octrees (via libpcl_octree);
  • brute force;
  • specialized search for organized datasets.

search类都定义了两种最常见的近邻搜索模式:k近邻搜索,球状固定距离半径近邻搜索。

  1. virtual int nearestKSearch (const PointT &point, int k, std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const = ;
  2.  
  3. virtual int radiusSearch (const PointT& point, double radius, std::vector<int>& k_indices, std::vector<float>& k_sqr_distances, unsigned int max_nn = ) const = ;

还有一种比较有用的方式是:圆柱固定距离半径搜索,即在XOY平面的投影距离,目前没有看到PCL中的专门的实现方式,可以通过一种折中的方法解决octree。

还有就是通过累积地图实现的投影到XOY平面内的简单搜索。

Weinmann, M., et al. (2015). "Semantic point cloud interpretation based on optimal neighborhoods, relevant features and efficient classifiers." ISPRS Journal of Photogrammetry and Remote Sensing 105: 286-304.

在feature模块中大量使用了近邻搜索的东西。近邻搜索是很多点云计算的基础功能。

示例

如下调用了点云KD树近邻搜索实现了8个基于特征值的点云特征计算:

  1. QString filePly = dlg.txtPath->text();
  2. std::wstring pszRoomFile1 = filePly.toStdWString();
  3. char buffer[];
  4. size_t ret = wcstombs(buffer, pszRoomFile1.c_str(), sizeof(buffer));
  5. const char * pszShapeFile = buffer;
  6. char * file_name = (char*)pszShapeFile;
  7. pcl::PointCloud<pcl::PointXYZ>::Ptr input_(new pcl::PointCloud<pcl::PointXYZ>);
  8. /*------------读取PLY文件-------------*/
  9. if (pcl::io::loadPLYFile<pcl::PointXYZ>(file_name, *input_) == -) //* load the file
  10. {
  11. PCL_ERROR("Couldn't read file test_pcd.pcd \n");
  12. QMessageBox::information(NULL, "Title", "Content", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
  13. }
  14. double search_radius_ = dlg.sb_scale2->value();
  15. int k_=;
  16. double search_parameter_ = 0.0;
  17. /*------------构造索引-------------*/
  18. boost::shared_ptr <std::vector<int> > indices_;
  19. if (!indices_)
  20. {
  21. indices_.reset(new std::vector<int>);
  22. try
  23. {
  24. indices_->resize(input_->points.size());
  25. }
  26. catch (const std::bad_alloc&)
  27. {
  28. PCL_ERROR("[initCompute] Failed to allocate %lu indices.\n", input_->points.size());
  29. }
  30. for (size_t i = ; i < indices_->size(); ++i) { (*indices_)[i] = static_cast<int>(i); }
  31. }
  32. std::vector<int> nn_indices(k_);
  33. std::vector<float> nn_dists(k_);
  34. /*---------------构造KD树-------------*/
  35. //pcl::search::Search<pcl::PointXYZ>::Ptr tree = boost::shared_ptr<pcl::search::Search<pcl::PointXYZ> >(new pcl::search::KdTree<pcl::PointXYZ>);
  36. pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
  37. tree->setInputCloud(input_);
  38. SearchMethodSurface search_method_surface_;
  39. if (search_radius_ != 0.0)
  40. {
  41. search_parameter_ = search_radius_;
  42. int (pcl::search::Search<pcl::PointXYZ>::*radiusSearchSurface)(const PointCloudIn &cloud, int index, double radius,
  43. std::vector<int> &k_indices, std::vector<float> &k_distances,
  44. unsigned int max_nn) const = &pcl::search::Search<pcl::PointXYZ>::radiusSearch;
  45. search_method_surface_ = boost::bind(radiusSearchSurface, boost::ref(tree), _1, _2, _3, _4, _5, );
  46. }
  47. else
  48. {
  49. search_parameter_ = k_;
  50. int (pcl::search::Search<pcl::PointXYZ>::*nearestKSearchSurface)(const PointCloudIn &cloud, int index, int k, std::vector<int> &k_indices,
  51. std::vector<float> &k_distances) const = &pcl::search::Search<pcl::PointXYZ>::nearestKSearch;
  52. search_method_surface_ = boost::bind(nearestKSearchSurface, boost::ref(tree), _1, _2, _3, _4, _5);
  53. }
  54. pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
  55. PointCloudOut& output = *cloud_normals;
  56. AxPointCloudOut output_pts;
  57. if (input_->size() < )
  58. {
  59. return;
  60. }
  61. else/*--------------计算特征值和特征向量-------------*/
  62. {
  63. output_pts.resize(input_->size());
  64. //output_pts.reserve(input_->size(), (new AxPoint()));
  65. #ifdef _OPENMP
  66. #pragma omp parallel for shared (output_pts) private (nn_indices, nn_dists) num_threads(threads_)
  67. #endif
  68. // Iterating over the entire index vector
  69. for (int idx = ; idx < static_cast<int> (indices_->size()); ++idx)
  70. {
  71. if (search_method_surface_(*input_, (*indices_)[idx], search_parameter_, nn_indices, nn_dists) == )
  72. {
  73. output.points[idx].normal[] = output.points[idx].normal[] = output.points[idx].normal[] = output.points[idx].curvature = std::numeric_limits<float>::quiet_NaN();
  74.  
  75. output.is_dense = false;
  76. continue;
  77. }
  78.  
  79. EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
  80. // 16-bytes aligned placeholder for the XYZ centroid of a surface patch
  81. Eigen::Vector4f xyz_centroid;
  82.  
  83. if (pcl::computeMeanAndCovarianceMatrix(*input_, nn_indices, covariance_matrix, xyz_centroid) == )
  84. {
  85. continue;
  86. }
  87.  
  88. EIGEN_ALIGN16 Eigen::Matrix3f eigen_vector3;
  89. EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
  90. //计算特征值和特征向量
  91. pcl::eigen33(covariance_matrix, eigen_vector3, eigen_values);
  92. double eig_val1 = eigen_values[];
  93. double eig_val2 = eigen_values[];
  94. double eig_val3 = eigen_values[];
  95.  
  96. output_pts[idx].x = input_->at((*indices_)[idx]).x;
  97. output_pts[idx].y = input_->at((*indices_)[idx]).y;
  98. output_pts[idx].z = input_->at((*indices_)[idx]).z;
  99. output_pts[idx].eig_val1 = eig_val1;
  100. output_pts[idx].eig_val2 = eig_val2;
  101. output_pts[idx].eig_val3 = eig_val3;
  102. }
  103. QString savefilePly = filePly.replace(".ply",".txt");
  104. std::wstring psaveFile1 = savefilePly.toStdWString();
  105. char buffer[];
  106. size_t ret = wcstombs(buffer, psaveFile1.c_str(), sizeof(buffer));
  107. const char * psavetxtFile = buffer;
  108. char * file_name_2 = (char*)psavetxtFile;
  109. FILE* saveFeaturePointCloud = fopen(file_name_2, "w");
  110. for (int i = ; i < output_pts.size(); i++)
  111. {
  112. float x = output_pts[i].x;
  113. float y = output_pts[i].y;
  114. float z = output_pts[i].z;
  115.  
  116. //注意:eig_val1最小
  117. float eig_val1 = output_pts[i].eig_val1;
  118. float eig_val2 = output_pts[i].eig_val2;
  119. float eig_val3 = output_pts[i].eig_val3;
  120. float eig_sum = eig_val1 + eig_val2 + eig_val3;
  121.  
  122. float e1 = , e2 = , e3 = ;
  123. float Linearity = ;
  124. float Planarity = ;
  125. float Scattering = ;
  126. float Omnivariance = ;
  127. float Anisotropy = ;
  128. float EigenEntropy = ;
  129. float changeOfcurvature = ;
  130. if (eig_sum != )
  131. {
  132. e1 = eig_val3 / eig_sum;
  133. e2 = eig_val2 / eig_sum;
  134. e3 = eig_val1 / eig_sum;
  135. Linearity = (e1 - e2) / e1;
  136. Planarity = (e2 - e3) / e1;
  137. Scattering = e3 / e1;
  138. Omnivariance = pow(e1*e2*e3, / );
  139. Anisotropy = (e1 - e3) / e1;
  140. EigenEntropy = -(e1*log(e1) + e2*log(e2) + e3*log(e3));
  141. //计算曲率变化
  142. changeOfcurvature = fabsf(e1 / (e1 + e2 + e3));
  143. }
  144. else
  145. changeOfcurvature = ;
  146. //x,y,z,e1,e2,e3,
  147. //Linearity,Planarity,Scattering,Omnivariance,Anisotropy,
  148. //Eigenentropy,Sum of eigenvalues,Change of curvature
  149. fprintf(saveFeaturePointCloud, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", x, y, z, eig_val1, eig_val2, eig_val3,
  150. Linearity, Planarity, Scattering, Omnivariance, Anisotropy, EigenEntropy, eig_sum, changeOfcurvature);
  151. }
  152. fclose(saveFeaturePointCloud);
  153. }

PCL近邻搜索相关的类的更多相关文章

  1. 【Elasticsearch 7 探索之路】(五)搜索相关 Search-API

    本节主要讲解 Elasticsearch 的 搜索相关功能 Search-API,讲解什么是 URL Search 和 Request Body Search 的语法,对常用的语法都会一一进行详细介绍 ...

  2. Hibernate 系列 04 - Hibernate 配置相关的类

    引导目录: Hibernate 系列教程 目录 前言: 通过上一篇的增删改查小练习之后,咱们大概已经掌握了Hibernate的基本用法. 我们发现,在调用Hibernate API的过程中,虽然Hib ...

  3. linux 搜索相关命令(2)

    文件搜索相关命令 1:locate命令 需要 yum install mlocate locate 文件名 在后台数据库中按文件名搜索,搜索速度更快 /var/lib/mlocate #locate命 ...

  4. jsonp模拟获取百度搜索相关词汇

    随便写了个jsonp模拟百度搜索相关词汇的小demo,帮助新手理解jsonp的用法. <!DOCTYPE html><html lang="en">< ...

  5. SWIFT 通过字符串创建相关的类

    import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: ...

  6. 模拟在内存中的数据库DataSet相关的类

    这篇连着上一篇DataReader相关类. 下面两段话是在msdn官网摘下来:       .NET Framework 数据提供程序是专门为数据操作以及快速.只进.只读访问数据而设计的组件.Conn ...

  7. 前端html 中jQuery实现对文本的搜索并把搜索相关内容显示出来

    做项目的时候有这么一个需求,客户信息显示出来后我要搜索查找相关的客户,并把相关的客户信息全部显示出来,因为一个客户全部信息我写在一个div里面  所以显示的时候就是显示整个div.先看看实现的效果: ...

  8. android中与SQLite数据库相关的类

    为什么要在应用程序中使用数据库?数据库最主要的用途就是作为数据的存储容器,另外,由于可以很方便的将应用程序中的数据结构(比如C语言中的结构体)转化成数据库的表,这样我们就可以通过操作数据库来替代写一堆 ...

  9. bootstrap 强调相关的类

    .text-muted:提示,使用浅灰色(#999) .text-primary:主要,使用蓝色(#428bca) .text-success:成功,使用浅绿色(#3c763d) .text-info ...

随机推荐

  1. java----JDOM解析XML

    JDOM: 与DOM类似,基于树形结构 效率比DOM快 下载: http://www.jdom.org/dist/binary/jdom-2.0.6.zip 导包导java中的工程目录 jdom-2. ...

  2. bzoj 2780

    后缀自动机的应用 首先我们观察到:如果一个询问串的答案不为0,那么这个串一定是至少一个模式串的子串 如果只有一个模式串,那么这个问题可以简单地用什么东西解决掉(比如普通后缀自动机) 而这里有很多模式串 ...

  3. jQuery第七章插件的编写和使用

    1.本章目标 编写jquery插件 2.插件 也称为扩展,是一种按照一定的规范的应用程序接口编写出来的程序 插件的目标是给已有的一系列函数做一个封装,以便在其他的地方复用,方便维护和开发效率 3.jq ...

  4. IntelliJ IDEA 使提示不区分大小写

    File ==> Settings ==> Editor ==> General ==> Code Completion 第一行 Match case 将默认勾选去掉

  5. python运算符——算数运算符

    加减乘除比较简单这里不多赘述了,print(2 +-*/ 3),唯一需要注意的就是整除运算,符号是“//”,整除运算取的是整数部分,而不是四舍五入哦! print(5 / 2)    这个运行的结果是 ...

  6. 潭州课堂25班:Ph201805201 tornado 项目 第九课 深入应用 WebSockets(课堂笔记)

    tornado 相关说明 在 handler 中创建一个  chat.py 文件,用来处理聊天室 在 templates 模板文件夹下创建 room.html 文件,是个聊天室 做好服务器的准备

  7. Leetcode 记录(201~300)

    实习面试前再完成100题,争取能匀速解释清楚题 204. Count Primes 素数筛 class Solution { public: int countPrimes(int n) { ) ; ...

  8. python学习笔记1-python相关应用套件

    完整的数据分析套件 统计科学计算 Numpy,Scipy,statsmodels 深度学习 TensorFlow,MXNET 结构化数据处理与分析 Pandas 大数据处理 PySpark 数据探索编 ...

  9. 数据仓库中的Inmon与Kimball架构

    对于数据仓库体系结构的最佳问题,始终存在许多不同的看法,甚至有人把Inmon和Kimball之争称之为数据仓库界的“宗教战争”,那么本文就通过对两位提倡的数据仓库体系和市场流行的另一种体系做简单描述和 ...

  10. JS基础学习3

    1.控制语句 (1)if控制语句 if-else基本格式 if (表达式){ 语句1; ...... }else{ 语句2; ..... } 功能说明 如果表达式的值为true则执行语句1, 否则执行 ...