题图就是计算出来的法线和激光点云咯

PCL的CUDA代码的确好但是没有教程,鄙人抛砖引玉,丢一篇如何使用PCL计算点云的曲率和法线的GPU样例上来。由于本人使用了cv库对曲率进行了可视化,所以带有CV的头文件,如果不需要可视化,CV是可以不配置的。

#include <iostream>
#include <fstream>
#include <string>
#include <iostream>
#include <cstdlib>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/core/hal/interface.h>
#include <opencv2/imgproc/imgproc.hpp>
#include<pcl/features/normal_3d.h>
#include<pcl/features/principal_curvatures.h>
#include<pcl/gpu/features/features.hpp>
bool getModelCurvatures(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,int k, vector<PCURVATURE>& tempCV)
{

	if (cloud->size()==0)
	{
		return false;
	}

	pcl::gpu::NormalEstimation::PointCloud gpuCloud;
	
	pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr kdtree(new pcl::KdTreeFLANN<pcl::PointXYZ>);
	kdtree->setInputCloud(cloud);

	size_t cloud_size = cloud->points.size();

	std::vector<float> dists;
	std::vector<std::vector<int>> neighbors_all;
	std::vector<int> sizes;
	neighbors_all.resize(cloud_size);
	sizes.resize(cloud_size);
#pragma omp parallel for
	for (int64 i = 0; i < cloud_size; ++i)
	{
		kdtree->nearestKSearch(cloud->points[i], k, neighbors_all[i], dists);
		sizes[i]=(int)neighbors_all[i].size();
	}
	int max_nn_size = *max_element(sizes.begin(), sizes.end());
	vector<int> temp_neighbors_all(max_nn_size * cloud->size());
	pcl::gpu::PtrStep<int> ps(&temp_neighbors_all[0], max_nn_size * pcl::gpu::PtrStep<int>::elem_size);
	for (size_t i = 0; i < cloud->size(); ++i)
		std::copy(neighbors_all[i].begin(), neighbors_all[i].end(), ps.ptr(i));

	pcl::gpu::NeighborIndices indices;
	gpuCloud.upload(cloud->points);
	indices.upload(temp_neighbors_all, sizes, max_nn_size);

	pcl::gpu::NormalEstimation::Normals normals;
	pcl::gpu::NormalEstimation::computeNormals(gpuCloud, indices, normals);
	pcl::gpu::NormalEstimation::flipNormalTowardsViewpoint(gpuCloud, 0.f, 0.f, 0.f, normals);
	
	vector<pcl::PointXYZ> downloaded;
	normals.download(downloaded);
	tempCV.resize(downloaded.size());
	for (size_t i = 0; i < downloaded.size(); ++i)
	{

		tempCV[i].index = i;
		tempCV[i].curvature = downloaded[i].data[3];
	}
	return true;
}

这个函数显而易见是用来计算曲率的,对大量点云,曲率计算效果会强很多,同时该函数会计算法线,在点数2千万时,在release下计算法线和曲率需要一个小时,通过使用GPU可以降到20秒。

今天的更新有点短,丢几张铁路的曲率图作为结束吧

81d551575dc833d558e36c18e40410ec.png

31f2a956e77c3ae08c71c761ae3795a2.png

38f4c6cff988b32c5979a5f8ee869b44.png

d693659fb0b443945ac330c01f8465a0.png

15a0081716061de3e74ad669744c74dd.png

1e17fd0ae164e1c22dd091e1f6676d16.png

91bbd0c73590b1065b9d861528b9c312.png

6ab79cf8d085974ff5f49c7392b8bf1a.png

0574596d841dcbf9652c8ac5e3f94a6e.png

b7715054ebfa455acac584f9a46a2b58.png

6ede03d291ab69bd0ab2be2f54c2065e.png
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐