文章目录
前言
点云处理中,法向量是一个很重要的参数,这里分析下pcl计算法向量的源码,加深对原理的理解。大概原理和流程可以参考这篇博文。
一、应用实例
#include <pcl/features/normal_3d_omp.h>//使用OMP需要添加的头文件
pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> n;//OMP加速
//pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
//建立kdtree来进行近邻点集搜索
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
n.setNumberOfThreads(10);//设置openMP的线程数
n.setViewPoint(0, 0, 0);//设置视点,默认为(0,0,0)
n.setInputCloud(cloud);
n.setSearchMethod(tree);
if(is_radius)
n.setRadiusSearch(radius);//半径搜素
else
n.setKSearch(sum);//点云法向计算时,需要所搜的近邻点大小
n.compute(*normals);//开始进行法向计
二、NormalEstimationOMP类
在NormalEstimationOMP类中,核心函数是computeFeature。
三、computeFeature函数
该函数有两个个需要注意的地方:
- for循环的多线程运行——#pragma omp parallel for;
- 置nan值——std::numeric_limits::quiet_NaN ();
//模板函数
template <typename PointInT, typename PointOutT> void
pcl::NormalEstimationOMP<PointInT, PointOutT>::computeFeature (PointCloudOut &output)
{
// Allocate enough space to hold the results
// \note This resize is irrelevant for a radiusSearch ().
std::vector<int> nn_indices (k_);
std::vector<float> nn_dists (k_);
output.is_dense = true;
// Save a few cycles by not checking every point for NaN/Inf values if the cloud is set to dense
if (input_->is_dense)
{
#ifdef _OPENMP
#pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(threads_)
#endif
// Iterating over the entire index vector
for (int idx = 0; idx < static_cast<int> (indices_->size ()); ++idx)
{
//如果找不到近邻点,则将参数置为nan值
//这里还是用到了kdtree,kdtree在pcl源码里的使用率非常高
if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
{
output.points[idx].normal[0] = output.points[idx].normal[1] = output.points[idx].normal[2] = output.points[idx].curvature = std::numeric_limits<float>::<