PCL估计点云的表面法向量

用PCL进行点云的表面重建,用贪婪投影三角法进行网格化 从完全不知到弄出结果用了好几天的时间,虽然结果还不是很理想,但也值得纪念一下,总结一下过程中出现的问题。 按照上一篇博客中的算法代码(如下)就可以,问题处在pcd文件上,pcd文件有固定的书写格式,可以按程序生成,也可以自己写,只要格式没问题即可。 接下来就是储存位置问题,pcd文件要和可执行文件即.exe文件放在同一文件夹下。运行程序,即可看到输出结果。 #include #inclu 阅读详情

估计点云表面法向量的方法

  1. 根据点云中点及其邻域信息,构建点云表面mesh网格,然后mesh网格计算曲面法线
  2. 使用近似值直接从点云数据集中推断出曲面法线
    PCL中点云表面法向量的实现是基于后者的,即在给定点云数据集的情况下,直接计算点云中每个点的表面法线。

理论基础

法线确定方法

确定表面上点的法线问题可以通过估计与表面相切的平面的法线问题来近似,从而又可以转化为最小二乘平面拟合估计问题。
因为点云中的点是三维的,要估计的平面是二维的,用三维数据估计二维数据,很容易想到的方法就是降维,而一提起降维,最容易想到的方法就是PCA,关于PCA的理论及代码实现,请参考我的文章PCA(主成分分析)降维原理及其在optdigits以及点云数据集上的python实现

因此,估计表面法线问题被简化为对由待估计点的最近邻生成的协方差矩阵的特征向量和特征值的分析。 更具体地说,对于每个点pi,我们如下构建它的协方差矩阵C:
在这里插入图片描述
其中k是点pi的k个相邻点,这些相邻点可以用最近邻方法确定,也可以指定半径确定,这在文章后面还会讨论到; p_bar表示临近点的3D质心; lamdaj表示协方差矩阵的第j个特征值,vector vj表示协方差矩阵的第j个特征向量。

可以很容易看出,pi和p_bar的shape都是(3,1),所以协方差矩阵C的shape是(3,3)
要从一组点中估计协方差矩阵,在PCL中实现方式为:

  // Placeholder for the 3x3 covariance matrix at each surface patch
  Eigen::Matrix3f covariance_matrix;
  // 16-bytes aligned placeholder for the XYZ centroid of a surface patch
  Eigen::Vector4f xyz_centroid;

  // Estimate the XYZ centroid
  compute3DCentroid (cloud, xyz_centroid);

  // Compute the 3x3 covariance matrix
  computeCovarianceMatrix (cloud, xyz_centroid, covariance_matrix);

法线方向确定

PCA可以很好的实现降维,找到切平面,但是并不能确定切平面的法线方向。
解决这一问题的方法是引入一个视点约束,假设引入一个视点vp,为了使所有法线vector ni始终朝向视点的一面,它们需要满足如下不等式约束:
在这里插入图片描述
若要在PCL中手动重新定向给定法线,可以用如下代码:

flipNormalTowardsViewpoint (const PointT &point, float vp_x, float vp_y, float vp_z, Eigen::Vector4f &normal);

选择合适的邻域尺度

如前所述,某一点的法线估计离不开其邻域点的约束。但是,给定点云数据,要确定某一点的邻域点集,需要确定合理的k(通过pcl::Feature::setKSearch给出)或r(通过pcl::Feature:: setRadiusSearch)给出,从而使得法线估计取得理想的效果,这就是邻域尺度问题。

该问题极其重要,是默认参数点特征估计的限制因素。为了更好地说明这个问题,下图比较了合理的尺度与偏大尺度的效果。左图是合理尺度的表面法线估计结果,可以看到,算法估计的表面法线分别与两个平面大致垂直,并且在整个桌子上可以看到小边缘。右图是偏大尺度的表面法线估计结果,因为比例尺度偏大,邻近点集覆盖了更多来自相邻表面的点,估计的法线变得失真,在两个平坦表面的边缘处表面法线出现明显旋转,并且边缘出现模糊、很多细节被抑制。
在这里插入图片描述在这里插入图片描述
尺度因子的选择需要根据应用程序所需的详细程度来确定。 简单地说,如果杯子的手柄和圆柱形部分之间的边缘处的法线很重要,则比例因子需要足够小以捕获那些细节,否则设置成较大比例因子比较合适。

PCL估计表面法线代码实现

估算输入数据集中所有点的曲面法线:

#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>

{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

  ... read, pass in or create a point cloud ...

  // Create the normal estimation class, and pass the input dataset to it
  pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
  ne.setInputCloud (cloud);

  // Create an empty kdtree representation, and pass it to the normal estimation object.
  // Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
  pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
  ne.setSearchMethod (tree);

  // Output datasets
  pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);

  // Use all neighbors in a sphere of radius 3cm
  ne.setRadiusSearch (0.03);

  // Compute the features
  ne.compute (*cloud_normals);

  // cloud_normals->points.size () should have the same size as the input cloud->points.size ()*
}

ne.compute()方法实际上完成了以下的工作:

for each point p in cloud P

  1. get the nearest neighbors of p

  2. compute the surface normal n of p

  3. check if n is consistently oriented towards the viewpoint and flip otherwise

默认的视点坐标是(0,0,0),可以通过如下代码指定:

setViewPoint (float vpx, float vpy, float vpz);

如果只需要计算某一个单点的法线,可以用下面的代码:

computePointNormal (const pcl::PointCloud<PointInT> &cloud, const std::vector<int> &indices, Eigen::Vector4f &plane_parameters, float &curvature);

其中cloud是包含点的输入点云,indices表示来自点云的k-最近邻集合,plane_parameters和curvature表示法线估计的输出,plane_parameters保存法线(nx,ny,nz)的前3个坐标,第四个坐标是D = nc = p_plane(这里是质心)+ p。 输出表面curvature被估计为协方差矩阵的特征值之间的关系,如下所示:
在这里插入图片描述

用OpenMP加速法线估计

PCL提供了表面法线估计的加速实现,基于OpenMP使用多核/多线程来加速计算。 该类的名称是pcl :: NormalEstimationOMP,其API与单线程pcl :: NormalEstimation 100%兼容。 在具有8个内核的系统上,一般计算时间可以加快6-8倍。
示例代码:

#include <pcl/point_types.h>
#include <pcl/features/normal_3d_omp.h>

{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

  ... read, pass in or create a point cloud ...

  // Create the normal estimation class, and pass the input dataset to it
  pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
  ne.setNumberOfThreads(12);  // 手动设置线程数,否则提示错误
  ne.setInputCloud (cloud);

  // Create an empty kdtree representation, and pass it to the normal estimation object.
  // Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
  pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
  ne.setSearchMethod (tree);

  // Output datasets
  pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);

  // Use all neighbors in a sphere of radius 3cm
  ne.setRadiusSearch (0.03);

  // Compute the features
  ne.compute (*cloud_normals);

  // cloud_normals->points.size () should have the same size as the input cloud->points.size ()*
}

参考资料

Estimating Surface Normals in a PointCloud

点云库pcl从入门到精通 第十章 点云库pcl从入门到精通第十章 阅读详情

相关推荐

PCL 计算点云法向量并显示【2026最新版】

PCL计算法向量并显示,用OMP进行计算加速以及法线定向的深层次理解、操作。博客长期更新,本文最近更新时间为:2026年1月28日。

点云侠的博客 32万+

点云相关学习总结一——估计一个点云的表面法线

表面法线是几何体表面的重要属性,在很多领域都有大量应用,例如:在进行光照渲染时产生符合可视习惯的效果时需要表面法线信息才能正常进行,对于一个已知的几何体表面,根据垂直于点表面的矢量,因此推断表面某一点的法线方向通常比较简单。然而,由于我们获取的点云数据集在真实物体的表面表现为一组定点样本,这样就会有两种解决方法: 使用曲面重建技术,从获取的点云数据集中得到采样点对应的曲面,然后从曲面模型中计算表

ZhangZX的专栏 1万+

【点云NormalEstimation】python-pcl:法向量估计并存储

1. 估算PointCloud的表面法线(Surface Normals) 2. 打印点云的法向量结果; 3. 存储点云的法向量结果;

qq_40985985的博客 4565

python-pcl计算点云法向量

import pcl import pcl.pcl_visualization def main(): cloud = pcl.load('filename.pcd') # load the pcd file ne = cloud.make_NormalEstimation() # instance the NormalEstimation ne.set_KSearch(20) # set the KNN search range of NormalEstimation normals = ne

SH_13的博客 3296

点云表面法向量的估计

点云表面法向量是一种重要几何表面特性,在计算机图像学中有很广的应用,例如在进行光照渲染和其他可视化效果时确定一个合理的光源位置。通过已知的确定几何表面来估计表面法向量通常并没有什么难度。但通过一组实际获取的真实表面点云数据来进行相应的法向量估计,通常有两种方案: 使用表面重建技术,针对获取的点运数据集,从网格化后的重建表面上估计法向量。 直接从点云数据中估计法向量。 直接从点云数据中获取法向量的...

点云PCL 3182

医疗成像中的点云处理:PCL库算法及其应用详解

在医学成像中,点云处理常用于3D重建、骨骼或器官的形状分析,以及术前规划和手术导航。PCL(Point Cloud Library)是一种广泛使用的开源库,提供了丰富的点云处理算法,适用于医疗图像的点云数据处理。

LiRongLu_的博客 742

PCL之估计整个点云表面法向量

代码展示: #include <string> #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/features/normal_3d.h> //法线估计类头文件 #include <pcl/visualization/cloud_viewer.h> using namespace std; typ

ancy的博客 699

PCL 计算点云中任意一个点的法向量【2026最新版】

PCL 计算点云数据中任意一个点的法向量,博客长期更新,本文最近更新时间为:2026年7月1日。

点云侠的博客 2518

PCL——点云特征描述与提取

>

kkmd66的博客 1930

hoppe移动立方体三维重建算法

Hoppe算法的基本思想是将点云视为隐式曲面的采样点,然后通过一系列操作重建该隐式曲面。具体步骤包括法向量估计、隐函数构造和表面提取。

twnkie的博客 808

CloudCompare&PCL点云法向量平滑

然而,在实际应用中,点云数据通常包含噪声和不完整的信息,这对于后续的分析和处理会带来一定的困难。其中,法向量是点云分析中常用的信息之一,它描述了点云表面在每个位置的方向。当然,除了上述介绍的方法外,还有其他许多点云处理技术和工具可以尝试,以满足不同应用场景的需求。在点云处理中,法向量平滑是一项重要的任务,它可以减少点云数据中的噪声,并让点云表面更加平滑。其中,radius参数指定了用于估计每个点的法向量的邻域半径。此外,还可以结合其他的点云处理算法和技术来进一步优化点云数据的质量和准确性。

HackMasterX的博客 531

pcl::Feature 类输入数据的传入方法和四种应用模式

pcl::Feature 类输入数据的传入方法和四种应用模式pcl::Feature类 有两种输入数据的方法,共对应四种应用模式:两种输入数据的方法对应的四种应用模式在法向量估计中的应用举例参考资料 pcl::Feature类 有两种输入数据的方法,共对应四种应用模式: 两种输入数据的方法 一个完整的点云数据集,通过setInputCloud (PointCloudConstPtr &)...

wolfcsharp的博客 1266

利用相邻点的法向量估计一个点的主曲率【2024最新版】

Curvature Estimation of 3D Point Cloud Surfaces Through the Fitting of Normal Section Curvatures,博客长期更新,本文最近更新时间为2024年11月20日。

点云侠的博客 39万+

估计一个点云的表面法线

估计一个点云的表面法线

Scarlett的博客 621

pca_normal_normal_点云_pca_点云主成分分析_法向量计算_

点云主成分分析和法向量计算的python源代码,可下载直接应用

凌欧通用FOC框架解析(5.程序环流程)

结构体:电流内环.这是一个结构体函数占空比13.

weixin_43756295的博客 2937

【PCL自学:Feature1】点云特征估计(持续更新)

一、Feature库 点云特征估计简述及代码解析   本文介绍了PCL中的三维点特征估计方法,并为对PCL:: feature类的内部结构感兴趣的用户或开发人员提供了指南。查看官方源文档请点击这里   点的特征估计 在 特征点搜索、点云配准、点云分割、三维物体识别等领域中常用,所谓的特征包括点云法向、曲率等,常用于点云预处理阶段当中。本文仅简要概述特征估计的原理,详细的点云特征估计论文请点击这里获取 名词:点的特征估计   3D映射系统概念中定义的 点 是相对于给定的原点,并使用它们的笛卡尔坐标x、y、z.

斯坦福的兔子的博客 3311

[Arcgis插件分享]--在线地图、地图配色

插件介绍:MapOnline在线地图插件是一套由北京茗禾科技有限公司研发的基于ArcGIS的插件工具,用户通过注册“数据禾”网站,即可使用MapOnline实现各种在线地图资源的集成加载,以及网站共享资源的免费下载。包括:谷歌地图、谷歌地球(无偏)、高德地图、天地图(无偏)、搜搜地图、必应地图(无偏)、OSM地图(无偏)、Esri影像(无偏),以及自定义切片的加载。⑤在Arcmap操作窗口上方的菜单栏右键,调用「MapOnlinev1.2.4」②双击安装文件夹内的「MapOnline.esriAddIn」

weixin_59101151的博客 5771

【PCL】(十四)PCL的Feature类接收输入的方式

一旦设置,任何特征估计类都将尝试估计给定输入云中指定索引的每个点的特征。这是PCL中最常用的情况,用户输入单个PointCloud数据,并期望在云中的所有点上估计某个特征。:设置输入的点云数据 (必须的设置), 任何特征估计类都将尝试估计给定输入云中每个点的特征。时,最有用的例子是估计点云的关键点或下采样版本的特征。中给定的曲面将用于获得输入点的最近邻点,而不是输入云本身;以下代码估计点云前10%的点的法线,KNN搜索平面为原始点云。的索引不是给定的索引向量的一部分,因此,仅估计。指定的点云子集估计特征。

weixin_44378835的博客 1100

Wireshark抓包分析:如何从HTTP流量中快速定位黑客攻击痕迹(附pcap文件)

本文通过Wireshark实战,详细解析了如何从HTTP流量中快速定位黑客攻击痕迹。文章提供了核心过滤策略,并重点剖析了如何识别SQL注入攻击的流量特征、揭露WebShell的隐蔽通信以及追踪攻击者在横向移动中的行为,帮助安全人员系统性地从pcap文件中还原完整攻击链。

sprite的博客 1010

Android 14 (AOSP) 源码架构深度解析与开发者指南

Android14源码的仓库指南信息

保持专注,保持热爱 1188

pcl计算点云法向量并显示

利用最小二乘法估计样点表面法向,并显示 #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/kdtree/kdtree_flann.h> #include <pcl/features/normal_3d.h> #include <pcl/surface/gp3.h> #include <pcl/visualization/pcl_visualizer.h&

爱哭鬼 515

数学建模Matlab算法,第七章 对策论

对策论作为研究竞争与决策的数学理论,从零和对策到非常数和对策,为分析各类博弈问题提供了系统框架。其核心要素包括局中人、策略集和赢得函数,通过稳定解、Nash平衡点等概念揭示竞争规律。该理论广泛应用于经济、军事、政治等领域,不仅提供具体分析工具,更改变了决策思维方式,强调在互动中实现理性选择。对策论既揭示了竞争本质,也凸显合作价值,为解决社会矛盾、促进共赢发展提供了重要启示,在全球化背景下将发挥更大作用。

unber的博客 113
上一篇: pcl::Feature 类输入数据的传入方法和四种应用模式
下一篇: PCL使用积分图像估计点云的表面法线
Leo-Ma
博客等级 码龄11年 1701粉丝 124原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值