工程代码:简单地测试了k-d树的最近邻搜索功能
#include<pcl/point_cloud.h>
#include<pcl/kdtree/kdtree_flann.h>
#include<iostream>
#include<vector>
#include<ctime>
using namespace std;
int
main(int argc, char** argv)
{
//使用系统时间做随机数种子
srand(time(NULL));
//创建一个PointXYZ类型点云指针
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
//初始化点云数据
cloud->width = 1000;//宽为1000
cloud->height = 1;//高为1,说明为无序点云
cloud->points.resize(cloud->width * cloud->height);
//使用随机数填充数据
for (size_t i = 0; i < cloud->size(); ++i)
{
//PointCloud类中对[]操作符进行了重载,返回的是对points的引用
// (*cloud)[i].x 等同于 cloud->points[i].x
(*cloud)[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树对象
pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
//设置点云输入,将在cloud中搜索
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;
vector<int> pointIdxNKNSearch(K);
vector<float> pointNKNSquaredDistance(K);
cout << "K nearest neighbor search at (" << searchPoint.x
<< " " << searchPoint.y
<< " " << searchPoint.z
<< ") with K = " << K << endl;
if (kdtree.nearestKSearch(searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
{
for (size_t i = 0; i < pointIdxNKNSearch.size(); ++i)
{
cout << " " << cloud->points[pointIdxNKNSearch[i]].x
<< " " << cloud->points[pointIdxNKNSearch[i]].x
<< " " << cloud->points[pointIdxNKNSearch[i]].z
<< "( squared distance: " << pointNKNSquaredDistance[i] << " )";
}
}
//基于半径的邻域搜索
//搜索结果保存在两个数组中,一个是下标,一个是距离
vector<int> pointIdxRadiusSearch;
vector<float> pointRadiusSquaredDistance;
//设置搜索半径,随机值
float radius = 256.0f* rand() / (RAND_MAX + 1.0f);
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]].x
<< " " << cloud->points[pointIdxRadiusSearch[i]].z
<< "( squared distance: " << pointRadiusSquaredDistance[i] << " )";
}
}
return 0;
}
但出现了如下错误:
error C3861: “pop_t”: 找不到标识符
解决办法
打开pcl 1.8.1\3rdparty\flann\include\flann\algorithms\dist.h文件:
错误定位在了523行:
result = lut(reinterpret_cast<const unsigned char*> (a), reinterpret_cast<const unsigned char*> (b), size * sizeof(pop_t));
原来是在当前作用域中找不到pop_t数据类型的定义,从上文代码中,将相关的定义复制到当前作用域中即可:
typedef unsigned long long pop_t;
重新编译,问题解决。