ch05——kd-treeK最近邻检索

ch05——kd-tree

点云数据处理中最核心的问题就是建立离散点的拓扑关系,实现基于邻域关系的快速查找。kd-tree与八叉树在3D点云数据组织中应用较为广泛。
1.kd-tree原理介绍参考链接——https://cloud.tencent.com/developer/news/212042
2.模块类介绍
基于FLANN进行快速最近邻检索,最近邻检索在匹配、特征描述子计算、邻域特征提取中是非常基础的核心操作。kd-tree模块利用三个类与两个函数实现了对点云的高效管理和检索,依赖于pcl_common模块。具体模块类详见官网介绍。
3.代码

#include <pcl/point_cloud.h>
#include <pcl/kdtree/kdtree_flann.h>//返回多于0个k近邻,则执行
#include <iostream>
using namespace std;
using namespace pcl;
#include <vector>
#include <ctime>
int main() {
	srand((unsigned int) time(null));//初始化随机种子
	PointCloud<PointXYZ>::Ptr cloud(new PointCloud<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);//[0,1024]
		cloud->points[i].y = 1024.0f*rand() / (RAND_MAX+1.0f);
		cloud->points[i].z = 1024.0f*rand() / (RAND_MAX+1.0f);
	}
	//创建kd-tree对象
	KdTreeFLANN<PointXYZ> kdtree;
	kdtree.setInputCloud(cloud);//设置搜索空间
	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;//设置近邻个数为10
	vector<int>pointidxnknsearch(k);//存储查询点近邻索引
	vector<float>pointnknsquareistance(k);//存储近邻点对应距离平方
	cout<<"k nearest neighbor search at("<<searchpoint.x <<" "<<
		searchpoint.y<<" "<<searchpoint.z<<")with k="<<k<<endl;
	//返回多于0个k近邻,则执行
	if (kdtree.nearestKSearch(searchpoint,k, pointidxnknsearch, pointnknsquareistance)>0)
	{
	    //打印各个近邻点
		for (size_t i = 0; i < pointidxnknsearch.size(); i++)
		{
			cout << " " << cloud->points[pointidxnknsearch[i]].x << " " <<
				cloud->points[pointidxnknsearch[i]].y << " " <<
				cloud->points[pointidxnknsearch[i]].z << "(squared distance:" <<
				pointnknsquareistance[i] << ")" << endl;
		}
	}
	//在某一半径r内搜索
	vector<int>pointidxradiussearch;//存储近邻索引
	vector<float>pointradiussquareddistance;//存储近邻对应距离平方
	//设置半径
	float radius = 256.0f*rand() / (RAND_MAX+1.0f);//[0, 255]
	cout << "neighbors within radius search at(" << searchpoint.x << " " <<
		searchpoint.y << " " << searchpoint.z << ")with radius=" << radius << endl;
	if (kdtree.radiusSearch(searchpoint, radius, pointidxradiussearch, pointradiussquareddistance) > 0)
	{   //打印各个近邻点
		for(size_t i = 0; i < pointidxradiussearch.size(); i++)
		{
			cout << " " << cloud->points[pointidxradiussearch[i]].x << " " <<
				cloud->points[pointidxradiussearch[i]].y << " " <<
				cloud->points[pointidxradiussearch[i]].z << "(squared distance:" <<
				pointradiussquareddistance[i] << ")" << endl;
		}
	}
	return 0;
}

4.显示
在这里插入图片描述

参与评论 您还未登录,请先 登录 后发表或查看评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

CV-点云

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值