本文学习了一种快速寻找无序点云的邻近点方法,就是构造KD树。用树这种数据结构,能够忽略掉许多点的比较,提高搜索速度。原理部分这篇博客讲的非常详细:
KNN算法与Kd树
以下是在阅读完博主博文之后,自己仿照写的一个寻找最近点算法。代码还是要自己多写,粘贴复制一时爽,用的时候就会痛苦万分,不断去找文件和文件夹。
两点说明:
1、如果设置的目标点为待搜索点云中的点,则搜索到的邻近点包含其本身;
2、以下为寻找K个最近点,还有一种是寻找一定范围类的邻近点,大家对比分析;
#include<pcl/point_cloud.h>
#include<pcl/kdtree/kdtree_flann.h>
#include<vector>
#include<iostream>
#include<ctime>
int main()
{
srand(time(NULL));
time_t begin, end;
begin = clock();
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
cloud->height = 1;
cloud->width = 100000;
cloud->is_dense = true;
cloud->resize(cloud->width*cloud->height);
for (int i = 0; i < cloud->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);
}
// creats kdtree object
pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
//set input point cloud
kdtree.setInputCloud(cloud);
// set target point
pcl::PointXYZ target;
target.x = 1024.0f*rand() / (RAND_MAX + 1.0f);
target.y = 1024.0f*rand() / (RAND_MAX + 1.0f);
target.z = 1024.0f*rand() / (RAND_MAX + 1.0f);
// set kdtree search
int K = 10;
std::vector<int> pointIdxNKNSearch(K);
std::vector<float> pointNKNSquaredDistance(K);
std::cout << "K nearset neighbor search at (" <<
target.x << " " << target.y << " " << target.z <<
"), with K = " << K << std::endl;
if (kdtree.nearestKSearch(target, K, pointIdxNKNSearch, pointNKNSquaredDistance) > 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;
}
end = clock();
double time = (end - begin) * 1000 / CLOCKS_PER_SEC;
std::cout << "time: " << time << "ms" << std::endl;
return 0;
}
在半径范围内的搜索方式:
double radius;
if (kdtree.radiusSearch(searchpoint, radius, Idx, Distance) > 0) {
for (size_t i = 0; i < Idx.size(); i++) {
cout << cloud->points[Idx[i]].x << " " <<
cloud->points[Idx[i]].y << " " <<
cloud->points[Idx[i]].z << " " <<
Distance[i] << endl;
}
}