#include<pcl/point_types.h>#include<pcl/kdtree/kdtree_flann.h>#include<pcl/common/transforms.h>#include<Eigen/Eigenvalues>
using namespace std;
using namespace pcl;
using namespace Eigen;
核心代码
voidpcaNormal(const PointCloud<PointXYZ>::Ptr& cloud,constint& k_neighbors, PointCloud<Normal>::Ptr& normals)//cloud为所求取的点云,k_neighbors为输入的Kd树的k值,normals为点云法向量{//1.构建kd树索引
KdTreeFLANN<PointXYZ>::Ptr kdtree(new KdTreeFLANN<PointXYZ>);
kdtree->setInputCloud(cloud);//2. 法向量实例化,若输入为空指针,则进行空间分配,若输入法向量非空,则使其为大小为0if(normals ==NULL)
normals = PointCloud<Normal>::Ptr(new PointCloud<Normal>);if(!normals->empty())
normals->resize(0);//3.对输入点云中的每个点进行遍历,对于每个点,使用PCA求取法向量for(constauto& point :*cloud){//3.1 初始化两个向量,用来记录K邻近点的编号以及距离平方
PointXYZ searchPoint = point;
vector<int>KNNIndices(k_neighbors);
vector<float>KNNSquareDistance(k_neighbors);//3.2 对K领域进行PCA分解,计算法向量if(kdtree->nearestKSearch(searchPoint, k_neighbors, KNNIndices, KNNSquareDistance)>0){//如果上面的值大于0,则搜索成功
PointCloud<PointXYZ>::Ptr neighborPoints(new PointCloud<PointXYZ>);//提取现在点的邻近点至neighborPoints中
pcl::copyPointCloud(*cloud, KNNIndices,*neighborPoints);
Eigen::Vector4f pcaCentroid;
Eigen::Matrix3f covariance;
Eigen::Matrix3f eigenVectorsPCA;
Eigen::Vector3f eigenValuesPCA;compute3DCentroid(*neighborPoints, pcaCentroid);//计算重心computeCovarianceMatrixNormalized(*neighborPoints, pcaCentroid, covariance);//compute the covariance matrix of point cloud
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f>eigen_solver(covariance, Eigen::ComputeEigenvectors);//define an eigen solver
eigenVectorsPCA = eigen_solver.eigenvectors();//compute eigen vectors
eigenValuesPCA = eigen_solver.eigenvalues();//compute eigen values;
Normal normal(eigenVectorsPCA(0),eigenVectorsPCA(1),eigenVectorsPCA(2));
normals->push_back(normal);}else
normals->push_back(Normal());}}