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

template<typename PointT>
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近邻搜索,球状固定距离半径近邻搜索。

virtual int nearestKSearch (const PointT &point, int k, std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const = ;

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个基于特征值的点云特征计算:

     QString filePly = dlg.txtPath->text();
std::wstring pszRoomFile1 = filePly.toStdWString();
char buffer[];
size_t ret = wcstombs(buffer, pszRoomFile1.c_str(), sizeof(buffer));
const char * pszShapeFile = buffer;
char * file_name = (char*)pszShapeFile;
pcl::PointCloud<pcl::PointXYZ>::Ptr input_(new pcl::PointCloud<pcl::PointXYZ>);
/*------------读取PLY文件-------------*/
if (pcl::io::loadPLYFile<pcl::PointXYZ>(file_name, *input_) == -) //* load the file
{
PCL_ERROR("Couldn't read file test_pcd.pcd \n");
QMessageBox::information(NULL, "Title", "Content", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
}
double search_radius_ = dlg.sb_scale2->value();
int k_=;
double search_parameter_ = 0.0;
/*------------构造索引-------------*/
boost::shared_ptr <std::vector<int> > indices_;
if (!indices_)
{
indices_.reset(new std::vector<int>);
try
{
indices_->resize(input_->points.size());
}
catch (const std::bad_alloc&)
{
PCL_ERROR("[initCompute] Failed to allocate %lu indices.\n", input_->points.size());
}
for (size_t i = ; i < indices_->size(); ++i) { (*indices_)[i] = static_cast<int>(i); }
}
std::vector<int> nn_indices(k_);
std::vector<float> nn_dists(k_);
/*---------------构造KD树-------------*/
//pcl::search::Search<pcl::PointXYZ>::Ptr tree = boost::shared_ptr<pcl::search::Search<pcl::PointXYZ> >(new pcl::search::KdTree<pcl::PointXYZ>);
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud(input_);
SearchMethodSurface search_method_surface_;
if (search_radius_ != 0.0)
{
search_parameter_ = search_radius_;
int (pcl::search::Search<pcl::PointXYZ>::*radiusSearchSurface)(const PointCloudIn &cloud, int index, double radius,
std::vector<int> &k_indices, std::vector<float> &k_distances,
unsigned int max_nn) const = &pcl::search::Search<pcl::PointXYZ>::radiusSearch;
search_method_surface_ = boost::bind(radiusSearchSurface, boost::ref(tree), _1, _2, _3, _4, _5, );
}
else
{
search_parameter_ = k_;
int (pcl::search::Search<pcl::PointXYZ>::*nearestKSearchSurface)(const PointCloudIn &cloud, int index, int k, std::vector<int> &k_indices,
std::vector<float> &k_distances) const = &pcl::search::Search<pcl::PointXYZ>::nearestKSearch;
search_method_surface_ = boost::bind(nearestKSearchSurface, boost::ref(tree), _1, _2, _3, _4, _5);
}
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
PointCloudOut& output = *cloud_normals;
AxPointCloudOut output_pts;
if (input_->size() < )
{
return;
}
else/*--------------计算特征值和特征向量-------------*/
{
output_pts.resize(input_->size());
//output_pts.reserve(input_->size(), (new AxPoint()));
#ifdef _OPENMP
#pragma omp parallel for shared (output_pts) private (nn_indices, nn_dists) num_threads(threads_)
#endif
// Iterating over the entire index vector
for (int idx = ; idx < static_cast<int> (indices_->size()); ++idx)
{
if (search_method_surface_(*input_, (*indices_)[idx], search_parameter_, nn_indices, nn_dists) == )
{
output.points[idx].normal[] = output.points[idx].normal[] = output.points[idx].normal[] = output.points[idx].curvature = std::numeric_limits<float>::quiet_NaN(); output.is_dense = false;
continue;
} EIGEN_ALIGN16 Eigen::Matrix3f covariance_matrix;
// 16-bytes aligned placeholder for the XYZ centroid of a surface patch
Eigen::Vector4f xyz_centroid; if (pcl::computeMeanAndCovarianceMatrix(*input_, nn_indices, covariance_matrix, xyz_centroid) == )
{
continue;
} EIGEN_ALIGN16 Eigen::Matrix3f eigen_vector3;
EIGEN_ALIGN16 Eigen::Vector3f eigen_values;
//计算特征值和特征向量
pcl::eigen33(covariance_matrix, eigen_vector3, eigen_values);
double eig_val1 = eigen_values[];
double eig_val2 = eigen_values[];
double eig_val3 = eigen_values[]; output_pts[idx].x = input_->at((*indices_)[idx]).x;
output_pts[idx].y = input_->at((*indices_)[idx]).y;
output_pts[idx].z = input_->at((*indices_)[idx]).z;
output_pts[idx].eig_val1 = eig_val1;
output_pts[idx].eig_val2 = eig_val2;
output_pts[idx].eig_val3 = eig_val3;
}
QString savefilePly = filePly.replace(".ply",".txt");
std::wstring psaveFile1 = savefilePly.toStdWString();
char buffer[];
size_t ret = wcstombs(buffer, psaveFile1.c_str(), sizeof(buffer));
const char * psavetxtFile = buffer;
char * file_name_2 = (char*)psavetxtFile;
FILE* saveFeaturePointCloud = fopen(file_name_2, "w");
for (int i = ; i < output_pts.size(); i++)
{
float x = output_pts[i].x;
float y = output_pts[i].y;
float z = output_pts[i].z; //注意:eig_val1最小
float eig_val1 = output_pts[i].eig_val1;
float eig_val2 = output_pts[i].eig_val2;
float eig_val3 = output_pts[i].eig_val3;
float eig_sum = eig_val1 + eig_val2 + eig_val3; float e1 = , e2 = , e3 = ;
float Linearity = ;
float Planarity = ;
float Scattering = ;
float Omnivariance = ;
float Anisotropy = ;
float EigenEntropy = ;
float changeOfcurvature = ;
if (eig_sum != )
{
e1 = eig_val3 / eig_sum;
e2 = eig_val2 / eig_sum;
e3 = eig_val1 / eig_sum;
Linearity = (e1 - e2) / e1;
Planarity = (e2 - e3) / e1;
Scattering = e3 / e1;
Omnivariance = pow(e1*e2*e3, / );
Anisotropy = (e1 - e3) / e1;
EigenEntropy = -(e1*log(e1) + e2*log(e2) + e3*log(e3));
//计算曲率变化
changeOfcurvature = fabsf(e1 / (e1 + e2 + e3));
}
else
changeOfcurvature = ;
//x,y,z,e1,e2,e3,
//Linearity,Planarity,Scattering,Omnivariance,Anisotropy,
//Eigenentropy,Sum of eigenvalues,Change of curvature
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,
Linearity, Planarity, Scattering, Omnivariance, Anisotropy, EigenEntropy, eig_sum, changeOfcurvature);
}
fclose(saveFeaturePointCloud);
}

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. Vue使用watch监听一个对象中的属性

    问题描述 Vue提供了一个watch方法可以让使用者去监听某些data内的数据变动,触发相应的方法,比如 queryData: { name: '', creator: '', selectedSta ...

  2. C#学习-子类的初始化顺序

    使用了继承之后,当我们初始化一个子类时,除了会调用子类的构造函数外,同时也会调用基类的构造函数. 子类的初始化顺序如下: (1)初始化类的实例字段: (2)调用基类的构造函数: (3)调用子类的构造函 ...

  3. 快速搭建MQTT服务器(MQTTnet和Apache Apollo)

    前言 MQTT协议是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分,http://mqtt.org/. MQTT is a machine-to-machine (M2M)/" ...

  4. SparkCore| 算子

    RDD RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象.代码中是一个抽象类,它代表一个弹性的.不可变.可分区.里面的元素可并行 ...

  5. CodeForces 721C Journey(拓扑排序+DP)

    <题目链接> 题目大意:一个DAG图有n个点,m条边,走过每条边都会花费一定的时间,问你在不超过T时间的条件下,从1到n点最多能够经过几个节点. 解题分析:对这个有向图,我们进行拓扑排序, ...

  6. SQLServer 2014 内存优化表

    内存优化表是 SQLServer 2014 的新功能,它是可以将表放在内存中,这会明显提升DML性能.关于内存优化表,更多可参考两位大侠的文章:SQL Server 2014新特性探秘(1)-内存数据 ...

  7. KaliLinuxNetHunter教程实施刷机解锁Bootloader

    KaliLinuxNetHunter教程实施刷机解锁Bootloader 当用户将前面的工作都准备完成后,即可开始刷机.其中,整个刷机过程分为三个步骤,分别是解锁Bootloader.刷入第三方Rec ...

  8. BZOJ.4299.Codechef FRBSUM(主席树)

    题目链接 记mx为最大的满足1~mx都能组成的数. 考虑当前能构成1~v中的所有数,再加入一个数x,若x>v+1,则mx=v,x不会产生影响:否则x<=v+1,则新的mx=x+v. 对于区 ...

  9. css3 @keyframes、transform详解与实例

    一.transform 和@keyframes动画的区别: @keyframes动画是循环的,而transform 只执行一遍. 二.@keyframes CSS3中添加的新属性animation是用 ...

  10. Python 面试中可能会被问到的30个问题

    第一家公司问的题目 1 简述解释型和编译型编程语言? 解释型语言编写的程序不需要编译,在执行的时候,专门有一个解释器能够将VB语言翻译成机器语言,每个语句都是执行的时候才翻译.这样解释型语言每执行一次 ...