您现在的位置是:首页 >技术教程 >Ubuntu2204环境下Pcl1.14中GPU/CUDA网站首页技术教程
Ubuntu2204环境下Pcl1.14中GPU/CUDA
简介Ubuntu2204环境下Pcl1.14中GPU/CUDA
pcl_gpu_test.cpp
#include <chrono>
#include <random>
#include <omp.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/surface/poisson.h>
#include <pcl/gpu/features/features.hpp>
#include <pcl/gpu/containers/device_array.h>
#include <pcl/visualization/pcl_visualizer.h>
pcl::PointCloud<pcl::PointNormal>::Ptr generateBallCloud(int numPoints,float radius){
pcl::PointCloud<pcl::PointNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointNormal>);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(-1.0,1.0);
for(int i = 0; i < numPoints; ++i){
float theta = 2 * M_PI * dis(gen);
float phi = acos(dis(gen));
float r = radius * std::cbrt(dis(gen) + 1);
pcl::PointNormal point;
point.x = r * sin(phi) * cos(theta);
point.y = r * sin(phi) * sin(theta);
point.z = r * cos(phi);
float norm = sqrt(point.x * point.x + point.y * point.y + point.z * point.z);
point.normal_x = point.x / norm;
point.normal_y = point.y / norm;
point.normal_z = point.z / norm;
cloud->points.push_back(point);
}
cloud->width = cloud->points.size();
cloud->height = 1;
return cloud;
}
void compute_poisson_mesh(pcl::PointCloud<pcl::PointNormal>::Ptr cloud_normals,pcl::PolygonMesh& mesh,int depth){
int default_depth = depth;
int default_solver_divide = 8;
int default_iso_divide = 8;
float default_point_weight = 4.0f;
pcl::search::KdTree<pcl::PointNormal>::Ptr tree(new pcl::search::KdTree<pcl::PointNormal>);
tree->setInputCloud(cloud_normals);
pcl::Poisson<pcl::PointNormal> poisson;
poisson.setSearchMethod(tree);
poisson.setDepth(default_depth);
poisson.setSolverDivide(default_solver_divide);
poisson.setIsoDivide(default_iso_divide);
poisson.setPointWeight(default_point_weight);
poisson.setInputCloud(cloud_normals);
poisson.reconstruct(mesh);
}
int main(){
const int numPoints = 100000;
const float radius = 10.0;
const int depth = 8;
pcl::PointCloud<pcl::PointNormal>::Ptr cloud_pointnormal = generateBallCloud(numPoints,radius);
std::cout << "Generated point cloud with " << cloud_pointnormal->size() << " points." << std::endl;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
for(const auto& pt : cloud_pointnormal->points){
cloud->points.push_back(pcl::PointXYZ(pt.x,pt.y,pt.z));
}
pcl::PolygonMesh mesh;
compute_poisson_mesh(cloud_pointnormal,mesh,6);
pcl::visualization::PCLVisualizer viewer = pcl::visualization::PCLVisualizer("Normal Viewer");
viewer.addPolygonMesh(mesh,"mesh");
viewer.addPointCloudNormals<pcl::PointNormal>(cloud_pointnormal,10,0.05,"cloud_pointnormal");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH,10,"cloud_pointnormal");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR,1,0,0,"cloud_pointnormal");
viewer.spin();
auto start_time_gpu = omp_get_wtime();
pcl::gpu::DeviceArray<pcl::PointXYZ> cloud_device;
cloud_device.upload(cloud->points);
pcl::gpu::NormalEstimation ne_gpu;
ne_gpu.setInputCloud(cloud_device);
const float search_radius = radius * 0.03f;
const int max_neighbors = 30;
ne_gpu.setRadiusSearch(search_radius,max_neighbors);
pcl::gpu::DeviceArray<pcl::PointXYZ> normals_device;
ne_gpu.compute(normals_device);
std::vector<pcl::PointXYZ> normals_host;
normals_device.download(normals_host);
std::cout << "gpu time: " << omp_get_wtime() - start_time_gpu << std::endl;
auto start_time_cpu = omp_get_wtime();
pcl::PointCloud<pcl::Normal>::Ptr cloud_normal_out(new pcl::PointCloud<pcl::Normal>);
pcl::NormalEstimation<pcl::PointXYZ,pcl::Normal> ne_cpu;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
ne_cpu.setSearchMethod(tree);
ne_cpu.setInputCloud(cloud);
ne_cpu.setKSearch(20);
ne_cpu.compute(*cloud_normal_out);
std::cout << "cpu time: " << omp_get_wtime() - start_time_cpu << std::endl;
pcl::PointCloud<pcl::PointNormal>::Ptr cloud_normal_out_gpu(new pcl::PointCloud<pcl::PointNormal>);
cloud_normal_out_gpu->resize(normals_host.size());
for(size_t i = 0; i < normals_host.size(); ++i){
cloud_normal_out_gpu->points[i].x = cloud->points[i].x;
cloud_normal_out_gpu->points[i].y = cloud->points[i].y;
cloud_normal_out_gpu->points[i].z = cloud->points[i].z;
cloud_normal_out_gpu->points[i].normal_x = normals_host[i].x;
cloud_normal_out_gpu->points[i].normal_y = normals_host[i].y;
cloud_normal_out_gpu->points[i].normal_z = normals_host[i].z;
cloud_normal_out_gpu->points[i].curvature = 0;
}
pcl::visualization::PCLVisualizer viewer2 = pcl::visualization::PCLVisualizer("Normal Viewer");
viewer2.addPolygonMesh(mesh,"mesh");
viewer2.addPointCloudNormals<pcl::PointNormal>(cloud_normal_out_gpu,10,0.05,"cloud_normal_out_gpu");
viewer2.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH,10,"cloud_normal_out_gpu");
viewer2.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR,1,0,0,"cloud_normal_out_gpu");
viewer2.spin();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(pcl_gpu_test)
find_package(PCL 1.14 REQUIRED)
find_package(VTK REQUIRED)
find_package(CUDA REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(pcl_gpu_test pcl_gpu_test.cpp)
target_link_libraries(pcl_gpu_test ${PCL_LIBRARIES} ${VYK_LIBRARIES})
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。