? 在上一篇文章【點云處理】點云法向量估計及其加速(4)中我們嘗試對pcl自帶的KDTree的k近鄰搜索過程使用OpenMP加速,效果比較明顯,有將近1倍的提速。在這篇文章中我們暫時放棄pcl自帶的KDTree,轉(zhuǎn)而使用另一大殺器nanflann庫提供的KDTree。nanoflann是一個c++11標準庫,用于構(gòu)建具有不同拓撲(R2,R3(點云),SO(2)和SO(3)(2D和3D旋轉(zhuǎn)組))的KD樹。nanoflann 算法對fastann進行了改進,效率以及內(nèi)存使用等方面都進行了優(yōu)化,而且代碼十分輕量級且開源。nanoflann不需要編譯或安裝,你只需要在你的代碼中加入#include
#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();
KDTreeTableAdaptorkdtree(cloud_size, dim, points, 64);
kdtree.index->buildIndex();
std::vector>neighbors_all(cloud_size,std::vector(k));
std::vectorsizes(cloud_size,k);
for (int i=0; iout_ids(k);
std::vectorout_dists_sqr(k);
nanoflann::KNNResultSetresult_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; jflatten_neighbors_all(k * cloud_size);
pcl::gpu::PtrStepps(&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::vectornormals;
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循環(huán)遍歷查找k近鄰索引部分我們先不加"# pragma omp parallel for",編譯運行。
哇,加速效果明顯,8w點云knn時間從400ms降到150ms左右。比pcl自帶KDTree使用上OpenMP并行加速還要快。
要是能利用OpenMP做并行加速,豈不是要起飛??!!加上OpenMP加速試一試。
# pragma omp parallel for
for (int i=0; iout_ids(k);
std::vectorout_dists_sqr(k);
nanoflann::KNNResultSetresult_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
編譯運行,測試結(jié)果如下:
哇,雖然有波動,但常能在50ms左右徘徊,相比曾幾何時的400ms提速了8倍。?多核算力分配也很均衡,完美!
所以,knn加速哪家強,nanoflann+OpenMP當稱王!!!
【參考文獻】
在C++中使用openmp進行多線程編程_線上幽靈的博客-博客_c++ omp
PCL GPU實現(xiàn)計算法線和曲率 - 知乎
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
文章標題:【點云處理】點云法向量估計及其加速(5)-創(chuàng)新互聯(lián)
標題鏈接:http://www.rwnh.cn/article42/cegiec.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設、App開發(fā)、標簽優(yōu)化、手機網(wǎng)站建設、品牌網(wǎng)站制作、外貿(mào)網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)