PCL库学习笔记(二)

本文详细介绍了PCL库中点云的搜索与压缩技术,包括KD-tree的K近邻搜索和半径搜索,以及八叉树的体素最近邻搜索、k近邻搜索和半径内最近邻搜索。同时,讨论了点云的压缩方法和无序点云数据变化检测的实现,提供相关代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、点云搜索与压缩

1、KD-tree

KD-tree是一种面向k(k≥2)维空间点数据组织的二叉树结构。在树的根部,所有子项都将根据第一维进行拆分(即,如果第一维坐标小于根,则它将在左子树中;如果大于根,则显然会在 右边的子树)。 树中向下的每个级别都在下一个维度上划分,一旦所有其他级别都用尽后,将返回到第一个维度。 构造k-d树的最有效方法是使用一种分区方法,将中值点放置在根上,具有较小一维值在左子树,较大的值在右子树。 然后,在左右两个子树上都重复此过程,直到要分区的最后一棵树仅由一个元素组成。

在这里插入图片描述
Kd-tree 具体排序理论可参考链接: 点击此处.

K近邻搜索

利用kd-tree实现点云的k近邻搜索(当k为1是就是最近邻点)时,步骤如下:
1、建立kd-tree
2、设置搜索空间
3、输入点云
4、设置搜索中心
5、创建一个整数K以及两个向量
代码

#include <pcl/point_cloud.h>
#include <pcl/kdtree/kdtree_flann.h> //kd-tree依赖的头文件
#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>);
//生成点云
cloud->width =1000;
cloud->height =1;
cloud->points.resize (cloud->width * cloud->height);
for (size_t i=0; i< cloud->points.size (); ++i)
  {
   
cloud->points[i].x =1024.0f* rand () / (RAND_MAX +1.0f);
cloud->points[i].y =1024.0f* rand () / (RAND_MAX +1.0f);
cloud->points[i].z =1024.0f* rand () / (RAND_MAX +1.0f);
  }
 //建立kd-tree
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);//存储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 )//执行搜索,搜索到后返回值大于0
  {
   
for (size_t i=0; i<pointIdxNKNSearch.size (); ++i)
std::cout<<"    "<<   cloud->points[ pointIdxNKNSearch[i] ].x 
<<" "<< cloud->points[pointIdxNKNSearch[i] ].y 
<<" "<< cloud->points[pointIdxNKNSearch[i] ].z 
<<" (squared distance: "<<pointNKNSquaredDistance[i] <<")"<<std::endl;
  }
 return 0;
}

kd-tree半径搜索

利用kd-tree半径搜索时,步骤与k近邻搜索一致,唯一不同是需要创建半径和两个向量
代码

#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));
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<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

聪 ~smart

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值