我来更新了。。
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;