法线空间采样
NormalSpaceSampling即:法线空间采样,它在法向量空间内均匀随机抽样,使所选点之间的法线分布尽可能大,结果表现为地物特征变化大的地方剩余点较多,变化小的地方剩余点稀少,可有效保持地物特征。实现方法如下:
1、首先计算每个点的K领域,然后计算点到领域点的法线夹角值,以此来近似达到曲率的效果并提高计算效率,因为曲率越大的地方,夹角值越大。
2、设置一个角度阈值,当点的领域夹角值大于阈值时被认为是特征明显的区域,其余区域为不明显区域。
3、对明显和不明显区域进行均匀采样,采样数分别为U_(1-V)和U_V,U是目标采样数,V是均匀采样性。
// 创建基于邻域的法向估计类对象
// // 基于omp并行加速,需配置开启OpenMP
// pcl::NormalEstimationOMP< pcl::PointXYZ, pcl::Normal > ne;
// ne.setNumberOfThreads(10);
pcl::NormalEstimation< pcl::PointXYZ, pcl::Normal > ne;
// 创建一个空的kdtree对象,并把它传递给法线估计对象,
// 用于创建基于输入点云数据的邻域搜索kdtree
pcl::search::KdTree< pcl::PointXYZ >::Ptr
tree(new pcl::search::KdTree< pcl::PointXYZ >());
// 传入待估计法线的点云数据,智能指针
ne.setInputCloud(cloud_src);
// 传入kdtree对象,智能指针
ne.setSearchMethod(tree);
// 设置邻域搜索半径
ne.setRadiusSearch(0.1f); // 设置半径时,要考虑到点云空间间距
// // 也可以设置最近邻点个数
// ne.setKSearch(25);
// 设置视点源点,用于调整点云法向(指向视点),默认(0,0,0)
ne.setViewPoint(0,0,0);
// 计算法线数据
ne.compute(*cloud_normals);
// 通过concatenateFields函数将point和normal组合起来形成PointNormal点云数据
pcl::PointCloud< pcl::PointNormal >::Ptr
cloud_with_normal(new pcl::PointCloud< pcl::PointNormal >());
pcl::PointCloud< pcl::PointNormal >::Ptr
cloud_with_normal_sampled(new pcl::PointCloud< pcl::PointNormal >());
pcl::concatenateFields(*cloud_src, *cloud_normals, *cloud_with_normal);
// 创建法向空间采样(模板)类对象
pcl::NormalSpaceSampling< pcl::PointNormal, pcl::Normal > nss;
// 设置xyz三个法向空间的分类组数,此处设置为一致,根据具体场景可以调整
const int kBinNum = 8;
nss.setBins(kBinNum, kBinNum, kBinNum);
// 如果传入的是有序点云,此处可以尝试设置为true
nss.setKeepOrganized(false);
// 设置随机种子,这样可以保证同样的输入可以得到同样的结果,便于debug分析
nss.setSeed(200); // random seed
// 传入待采样的点云数据
nss.setInputCloud(cloud_with_normal);
// 传入用于采样分析的法线数据,需与传入点云数据一一对应
nss.setNormals(cloud_normals);
// 设置采样总数,即目标点云的总数据量
const float kSampleRatio = 0.1f;
nss.setSample(cloud_with_normal- >size()*kSampleRatio);
// 执行采样并带出采样结果
nss.filter(*cloud_with_normal_sampled);
全部0条评论
快来发表一下你的评论吧 !