欢迎点云相关产学研的学者和团体加入我们。
本小节我们将学习如何使用积分图(integral images)计算一个有序点云的法线,注意该方法只适用于有序点云。
首先,在PCL(Point Cloud Learning)中国协助发行的书[1]提供光盘的第12章例2文件夹中,打开名为normal_estimation_using_integral_images.cpp的代码文件,同文件夹下可以找到相关的测试点云文件table_scene_mug_stereo_textured.pcd,此测试示例要求点云文件为有序点云。
现在,让我们把打开的源代码分开来解析。在第一部分中我们从文件中加载了一个点云存储在点云对象,以备后续作为法线估计对象的输入。
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile ("table_scene_mug_stereo_textured.pcd", *cloud);
在第二部分中,定义了存储估计法线的点类型指针,并为创建了一个积分图法线估计的对象ne,设置对象计算时需要的参数,例如估计方法、点云等。
pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
ne.setNormalEstimationMethod (ne.AVERAGE_3D_GRADIENT); //设置估计方法
ne.setMaxDepthChangeFactor(0.02f); //最大深度变化系数
ne.setNormalSmoothingSize(10.0f); //优化法线方向时考虑邻域大小
ne.setInputCloud(cloud); //输入点云,必须为有序点云
ne.compute(*normals); //执行法线估计存储结果到normals
以下是可使用的法线估计方法:
enum NormalEstimationMethod
{
COVARIANCE_MATRIX,
AVERAGE_3D_GRADIENT,
AVERAGE_DEPTH_CHANGE
};
COVARIANCE_MATRIX模式从具体某个点的局部邻域的协方差矩阵创建9个积分图,来计算这个点的法线。AVERAGE_3D_GRADIENT模式创建了6个积分图来计算水平和垂直方向的平滑后的三维梯度,并使用两个梯度间的向量积计算法线。AVERAGE_DEPTH_CHANGE模式只创建了一个单一的积分图,并从平均深度变化计算法线。
利用光盘提供的CMakeLists.txt文件,在cmake中建立工程文件,并生成相应的可执行文件,生成执行文件后,就可以运行了,在cmd中键入命令:
...>normal_estimation_using_integral_images.exe
运行结果如图1所示,法线方向基本一致朝向视点,视图视点朝向场景中的桌面,桌面上的杯子处出现平行于桌面的法线,而桌面上的点集的法线都垂直于桌面并指向点云本身获取时的视点,利用此方法进行法线估计只适用于有序点云,对于无序点云就只能采用其他方法。
图1 积分图法线估计示例结果
敬请关注PCL(Point Cloud Learning)中国更多的点云库PCL(Point Cloud Library)相关官方教程。
参考文献:
1.朱德海、郭浩、苏伟.点云库PCL学习教程(ISBN 978-7-5124-0954-5)北京航空航天出版社 2012-10