积分图估计法线方法

两种法线估计方法的比较

pcl::NormalEstimationpcl::IntegralImageNormalEstimation是两种常见的法线估计方法,它们的区别主要在于计算法线的方式和适用场景。

  1. pcl::NormalEstimation

    • 计算方式:基于K近邻搜索的方法,通过寻找点云中每个点周围的最近邻点来估计法线。
    • 优点:灵活性高,可以通过调整搜索半径或K值来控制法线估计的精度和稠密度。
    • 缺点:计算复杂度较高,对于大规模点云或需要实时计算的场景可能不太适用。
  2. pcl::IntegralImageNormalEstimation

    • 计算方式:基于积分图的方法,通过计算积分图并利用积分图的性质快速计算法线。
    • 优点:计算速度快,适用于大规模点云或需要实时计算的场景。
    • 缺点:对点云数据有一定的要求,需要有序点云或使用体素格网进行体素化

根据具体应用的需求和点云数据的特点,可以选择合适的法线估计方法。如果需要精细控制法线估计的精度和稠密度,或者处理的点云规模较小,可以选择pcl::NormalEstimation。如果需要快速计算法线且处理的点云规模较大,可以选择pcl::IntegralImageNormalEstimation

 

积分图估算法线方法的参数

setNormalSmoothingSize 方法是用于设置法线平滑的窗口大小的。窗口大小决定了在计算法线时要考虑多少个邻域点的影响。

pcl::IntegralImageNormalEstimation 类中的 setNormalSmoothingSize 方法有以下参数选项:

  • ne.AVERAGE_3D_GRADIENT:使用3D梯度的平均作为法线平滑的窗口大小。这是默认选项。
  • ne.AVERAGE_DEPTH_CHANGE:使用深度变化的平均作为法线平滑的窗口大小。
  • ne.SINGLE_NORMAL:不进行法线平滑,仅使用单个点的法线。

选择哪个平滑窗口大小的选项取决于你的具体应用和需求。

  • 如果你希望在计算法线时考虑更多的邻域点,以获得更平滑的法线结果,可以选择 ne.AVERAGE_3D_GRADIENT。这个选项将使用3D梯度的平均作为法线平滑的窗口大小。

  • 如果你更关注深度变化对法线计算的影响,并希望在计算法线时更加敏感地响应深度变化,可以选择 ne.AVERAGE_DEPTH_CHANGE。这个选项将使用深度变化的平均作为法线平滑的窗口大小。

  • 如果你不需要进行法线平滑,只关注每个点的单个法线,可以选择 ne.SINGLE_NORMAL。这个选项将不进行法线平滑,仅使用单个点的法线。

代码:

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/integral_image_normal.h>
#include <pcl/visualization/cloud_viewer.h>


//---------------------------------------------------------------------------------------------------------
// 积分图估算点云法线
//---------------------------------------------------------------------------------------------------------
int main(){

    // 两个点云数据
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile("/home/jason/file/pcl-learning/data/table_scene_mug_stereo_textured.pcd", *cloud);




    // ------------------------
    // 估计点云的法线
    // -----------------------

    // 用于存储法向量
    pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
    // 创建法一个用于法线估计的对象并计算法线
    pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> ne;

    ne.setNormalSmoothingSize(ne.AVERAGE_3D_GRADIENT); // 使用平均梯度法平滑法线
    ne.setMaxDepthChangeFactor(0.02f); // 设置法线估计时的最大深度变化因子。这个参数控制法线估计的灵敏度,较小的值会使法线会对深度变化更加敏感
    ne.setNormalSmoothingSize(10.0f); // 设置法线估计时的法线平滑尺寸。这个参数控制在估计法线时使用的领域大小。较大的值会考虑更多的领域点,从而平滑法线的方向
    ne.setInputCloud(cloud); // 设置输入点云
    ne.compute(*cloud_normals); // 计算法线


    // -----------------
    // 可视化法线
    // -----------------
    pcl::visualization::PCLVisualizer viewer("PCL Viewer");
    viewer.setBackgroundColor(0.0, 0.0, 0.5);
    viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, cloud_normals, 2, 0.01, "normals"); // 2 表示每隔2个点绘制一个法线,控制法线的密度
                                                                                                       // 0.01 表示法线的长度缩放因子,控制法线的可视化长度
                                                                                                       // 其实这些参数都可以不写,PCL会自动设置,给予一个较好的显示效果
    viewer.addCoordinateSystem(1.0);

    while (!viewer.wasStopped()) {
        viewer.spinOnce();
    }

    return 0;
}

效果

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值