PCL 积分图法线估计(Feature_IntegralImageNormal)

注意:本方法速度虽然快,但只适用于有序点云!!!

1.原理

积分图法线估计,即将点云看做一个有深度的图像(包含坐标xy和深度z)。在从点云起始位置开始生成一个平滑窗口,然后按照点云顺序(该方法必须作用于有序点云),该窗口不停平滑后移,不停获取每个窗口内点云的所有相邻点,并以此进行法线计算。

(1)从有序点云起始点P开始,生成点云窗口(也就是取P周围一定范围内的点云)。

(2)获取该窗口中的所有点云点,按照一定规则进行积分图法线计算(规则在PCL中以参数确定,本文关键函数处会讲解,如果想了解具体原理,可以看下文)。

积分图的计算

(3)窗口不停的平滑移动,遍历计算完所有点云点的法向量。

简易版理解如下图:

假设红线是点云的顺序,黄色框即是所谓窗口。

该黄色窗口从起始位置开始,一直移动计算每个窗口中的法向量,直到计算到最后。

2.使用场景

相较于normal_3d,积分图计算法向量

优点:速度快(使用窗口,不使用kd树进行邻近搜索)、可以进行实时计算

缺点:需要使用有序点云

使用场景囿于有序点云,实际上使用除了实时激光雷达扫下来的点云,用处较少。

3.注意事项

注意要使用有序点云

4.关键函数

(1)积分图法线估计方法

COVARIANCE_MATRIX:邻域的协方差矩阵中创建9个积分图去计算一个点的法线。

AVERAGE_3D_GRADIENT:创建了6个积分图去计算3D梯度里面垂直和水平方向的光滑部分,同时利用两个梯度的又积来计算法线

AVERAGE_DEPTH_CHANGE:创建一个单一的积分图,从平均深度的变化中来计算法线。。

SINGLE_NORMAL:不进行法线平滑,仅计算单个点的法线。

setNormalEstimationMethod()

(2)处理边界的策略

BORDER_POLICY_IGNORE:忽略边界处理。

BORDER_POLICY_MIRROR:镜像边界处理。

setBorderPolicy()

(3)设置法向量的视点

setViewPoint()

(4)计算对象边界的深度变化阈值

setMaxDepthChangeFactor()

(5)平滑法线的区域大小(窗口大小)

setNormalSmoothingSize()

5.代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/features/integral_image_normal.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>

int main()
{
    /****************积分图法线估计********************/
    // 原始点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile("D:/code/csdn/data/milk_cartoon_all_small_clorox.pcd", *cloud);   // 加载原始点云数据
	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);

    // 积分图法线估计
	pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> feature;
	feature.setNormalEstimationMethod(feature.AVERAGE_3D_GRADIENT);					// 估计方法
	feature.setBorderPolicy(feature.BORDER_POLICY_MIRROR);							// 处理边界的策略
	feature.setViewPoint(0, 0, 0);													// 设置法向量的视点
	feature.setMaxDepthChangeFactor(0.02f);											// 计算对象边界的深度变化阈值
	feature.setNormalSmoothingSize(10.0f);											// 窗口大小/邻域大小
	feature.setInputCloud(cloud);													// 只能处理有序点云
	feature.compute(*normals);

	/****************展示********************/
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer(""));
	viewer->setBackgroundColor(0, 0, 0);
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color(cloud, 0, 225, 0);
	viewer->addPointCloud<pcl::PointXYZ>(cloud, color, "sample cloud");									// 添加点云
	viewer->addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 20, 0.02, "normals");		// 添加点云法向量
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

	return 0;
}

6.结果展示

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值