积分图像是对有序点云的发现的估计的一种方法。该算法把点云作为一个深度图像,并创建一定的矩形区域来计算法线,考虑到相邻像素关系,而无需建立树形查询结构。因此,它是非常有效的。
代码展示:
#include<string>
#include<iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/point_types.h>
#include<pcl/features/integral_image_normal.h>
#include<pcl/visualization/pcl_visualizer.h>
using namespace std;
int main()
{
//加载点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile ("table_scene_mug_stereo_textured.pcd", *cloud);
//估计法线
pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
// 法线估计方法:
// COVARIANCE_MATRIX:从具体某个点的局部邻域的协方差矩阵创建9个积分图,来计算这个点的法线。
// AVERAGE_DEPTH_CHANGE:创建了6个积分图来计算水平和垂直方向的平滑后的三维梯度,并使用两个梯度间的向量积计算法线。
// SIMPLE_3D_GRADIENT: 只创建了一个单一的积分图,并从平均深度变化计算法线。
ne.setNormalEstimationMethod (ne.AVERAGE_3D_GRADIENT);
// 设置最大深度变化系数
ne.setMaxDepthChangeFactor(0.02f);
// 设置优化法线方向时考虑邻域大小
ne.setNormalSmoothingSize(10.0f);
// 设置输入点云,必须为有序点云
ne.setInputCloud(cloud);
// 执行法线估计存储结果到normals
ne.compute(*normals);
//法线可视化
pcl::visualization::PCLVisualizer viewer("viewer");
viewer.setBackgroundColor (0.0, 0.0, 0.5);
viewer.addPointCloudNormals<pcl::PointXYZ,pcl::Normal>(cloud, normals);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_tr_color_h(cloud, 255, 255, 0);
viewer.addPointCloud(cloud, cloud_tr_color_h, "raw_cloud");
while (!viewer.wasStopped ())
{
viewer.spinOnce ();
}
return 0;
}
效果展示:
点云文件下载地址:table_scene_mug_stereo_textured.pcd