【点云处理】点云法向量估计及其加速(5)
创始人
2024-02-18 18:13:10
0

        在上一篇文章【点云处理】点云法向量估计及其加速(4)中我们尝试对pcl自带的KDTree的k近邻搜索过程使用OpenMP加速,效果比较明显,有将近1倍的提速。在这篇文章中我们暂时放弃pcl自带的KDTree,转而使用另一大杀器nanflann库提供的KDTree。nanoflann是一个c++11标准库,用于构建具有不同拓扑(R2,R3(点云),SO(2)和SO(3)(2D和3D旋转组))的KD树。nanoflann 算法对fastann进行了改进,效率以及内存使用等方面都进行了优化,而且代码十分轻量级且开源。nanoflann不需要编译或安装,你只需要在你的代码中加入#include 即可方便快捷地使用它。好了,下面使用nanoflann对我们的代码进行改写。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "KDTreeTableAdaptor.h"int main(int argc, char** argv) {ros::init(argc, argv, "n_lidar_gpu_normal");ros::NodeHandle node;pcl::PointCloud::Ptr cloud(new pcl::PointCloud);const boost::function&)> callback =[&](sensor_msgs::PointCloud2::ConstPtr msg_pc_ptr) {pcl::fromROSMsg(*msg_pc_ptr, *cloud);size_t cloud_size = cloud->size();int dim=3,k=10; float* points = new float[cloud_size*dim];for (int i=0; ipoints[i].x;p[1] = cloud->points[i].y;p[2] = cloud->points[i].z;}auto t1 = std::chrono::steady_clock::now();KDTreeTableAdaptor  kdtree(cloud_size, dim, points, 64);std::vector> neighbors_all(cloud_size,std::vector(k));std::vector sizes(cloud_size,k);for (int i=0; i out_ids(k);std::vector out_dists_sqr(k);nanoflann::KNNResultSet result_set(k);result_set.init(&out_ids[0], &out_dists_sqr[0]);kdtree.index->findNeighbors(result_set, &points[i*dim], nanoflann::SearchParams(k));for (int j=0; j flatten_neighbors_all(k * cloud_size);pcl::gpu::PtrStep ps(&flatten_neighbors_all[0], k * pcl::gpu::PtrStep::elem_size);for (size_t i=0; ipoints);gpu_neighbor_indices.upload(flatten_neighbors_all, sizes, k);pcl::gpu::NormalEstimation::Normals gpu_normals;pcl::gpu::NormalEstimation::computeNormals(gpu_cloud, gpu_neighbor_indices, gpu_normals);pcl::gpu::NormalEstimation::flipNormalTowardsViewpoint(gpu_cloud, 0.f, 0.f, 0.f, gpu_normals);auto t3 = std::chrono::steady_clock::now();auto compute_normal_time = std::chrono::duration(t3 - t2);std::vector normals;gpu_normals.download(normals);auto t4 = std::chrono::steady_clock::now();auto knn_time = std::chrono::duration(t2-t1);auto total_time = std::chrono::duration(t4-t1);spdlog::info("cloud size:{:d}, knn_time:{:.3f} ms,compute_normal_time:{:.3f} ms, total_time:{:.3f} ms", cloud->size(), knn_time.count(), compute_normal_time.count(), total_time.count());};ros::Subscriber pc_sub = node.subscribe("/BackLidar/lslidar_point_cloud", 1, callback);ros::spin();return 0;
}

对于for循环遍历查找k近邻索引部分我们先不加"# pragma omp parallel for",编译运行。

  哇,加速效果明显,8w点云knn时间从400ms降到150ms左右。比pcl自带KDTree使用上OpenMP并行加速还要快。

要是能利用OpenMP做并行加速,岂不是要起飞??!!加上OpenMP加速试一试。

# pragma omp parallel forfor (int i=0; i out_ids(k);std::vector out_dists_sqr(k);nanoflann::KNNResultSet result_set(k);result_set.init(&out_ids[0], &out_dists_sqr[0]);kdtree.index->findNeighbors(result_set, &points[i*dim], nanoflann::SearchParams(k));for (int j=0; j

 编译运行,测试结果如下:

哇,虽然有波动,但常能在50ms左右徘徊,相比曾几何时的400ms提速了8倍。 多核算力分配也很均衡,完美!

 所以,knn加速哪家强,nanoflann+OpenMP当称王!!!

【参考文献】

在C++中使用openmp进行多线程编程_线上幽灵的博客-CSDN博客_c++ omp

PCL GPU实现计算法线和曲率 - 知乎

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...