pcl八叉树(octree)搜索与kdtree搜索耗时比较

25 篇文章 17 订阅

我来更新了。。

kdtree能实现半径搜索和k近邻搜索,octree除了能实现半径搜索和k近邻搜索外,还可以实现体素搜索,通过两组点云数据,设置不同的半径,k值,体素大小进行耗时比较分析。

直接上结论:

(1)无论点云数量多少,半径大小,k近邻大小,kdtree的半径搜索和k近邻搜索耗时均优于octree,所以半径搜索或者k近邻搜索优先使用kdtree
(2)octree体素搜索相对于近邻搜索确实快
(3)显然的结论:其他条件一定,体素边长越小越耗时(耗时差异并不很明显)。其他条件一定,近邻搜索的半径越大或者k越大,越耗时(耗时差异明显)。
以下为测试代码和实验结果:
ps:我只做了四组实验,严格意义上算不是特别严谨(主要是懒),有别的发现欢迎留言交流

talk is cheap ,there is the codes

#include "pch.h"
#include <iostream>
#include<pcl/point_cloud.h>
#include<pcl/io/pcd_io.h>
#include<pcl/octree/octree.h>
#include<pcl/kdtree/kdtree.h>
#include<pcl/kdtree/kdtree_flann.h>
#include<ctime>

int main()
{
	
	//auto start = std::clock();
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	std::string file_name("part216offgroundpoints");//点云文件名
	pcl::io::loadPCDFile<pcl::PointXYZ>(file_name+".pcd", *cloud);
	std::cerr << "点云数量:" << cloud->points.size() << std::endl;
	float radius = 0.1;//搜索半径和体素边长设为一样
	int k = 10;
	std::cerr << "半径r=" << radius << std::endl << "近邻数k=" << k << std::endl;

	pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr kdtree(new pcl::KdTreeFLANN<pcl::PointXYZ>);
	kdtree->setInputCloud(cloud);
	pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree(radius);
	octree.setInputCloud(cloud);
	octree.addPointsFromInputCloud();

	auto start = std::clock();
	for (auto &i : *cloud)
	{
		std::vector<int>  oc_indices(0, 0);
		
		octree.voxelSearch(i, oc_indices);
	}
	auto end_1 = std::clock();
	std::cerr << "octree体素搜索耗时" << std::difftime(end_1, start)<<"ms" << std::endl;
	for (auto &i : *cloud)
	{
		std::vector<int>  oc_indices(0, 0);
		std::vector<float> oc_dists(0, 0.0);
		octree.radiusSearch(i,radius, oc_indices,oc_dists);
	}
	auto end_2 = std::clock();
	std::cerr << "octree半径近邻搜索耗时" << std::difftime(end_2, end_1) << "ms" << std::endl;
	for (auto &i : *cloud)
	{
		std::vector<int> kd_indices(0, 0);
		std::vector<float>kd_dists(0, 0.0);
		kdtree->radiusSearch(i, radius, kd_indices, kd_dists);
	}
	auto end_3 = std::clock();
	std::cerr << "kdtree半径搜索耗时" << std::difftime(end_3, end_2) << "ms" << std::endl;
	int s = 0;
	for (auto &i : *cloud)
	{
		std::vector<int>  oc_indices(0, 0);
		std::vector<float> oc_dists(0, 0.0);
		octree.nearestKSearch(i, k, oc_indices, oc_dists);
		s++;
	}
	std::cerr << s << std::endl;
	auto end_4 = std::clock();
	std::cerr << "octreeK近邻搜索耗时" << std::difftime(end_4, end_3) << "ms" << std::endl;

	for (auto &i : *cloud)
	{
		std::vector<int>  oc_indices(0, 0);
		std::vector<float> oc_dists(0, 0.0);
		kdtree->nearestKSearch(i, k, oc_indices, oc_dists);
	}
	auto end_5 = std::clock();
	std::cerr << "kdtreeK近邻搜索耗时" << std::difftime(end_5, end_4) << "ms" << std::endl;
    std::cout << "Hello World!\n"; 
}
	int cloud->points.size()=3646;
	float radius = 0.05;//cm
	int k = 10;

实验结果:
在这里插入图片描述

	int cloud->points.size()=3646;
	float radius = 0.1;
	int k = 15;

在这里插入图片描述

	int cloud->points.size()=22372;
	float radius = 0.05;//cm
	int k = 10;

在这里插入图片描述

	int cloud->points.size()=22372;
	float radius = 0.1;//cm
	int k = 15;

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值