使用積分影象的法向量估計(Normal Estimation Using Integral Images)
阿新 • • 發佈:2018-11-12
在本教程中,我們將學習如何使用積分影象計算組織點雲的法線。
#程式碼
首先,用你最喜歡的編輯器建立一個檔案,名為normal_estimation_using_integral_images.cpp
,並在其中放置以下內容:
#include <pcl/io/io.h> #include <pcl/io/pcd_io.h> #include <pcl/features/integral_image_normal.h> #include <pcl/visualization/cloud_viewer.h> int main () { // load point cloud pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile ("table_scene_mug_stereo_textured.pcd", *cloud); // estimate normals 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); // visualize normals pcl::visualization::PCLVisualizer viewer("PCL Viewer"); viewer.setBackgroundColor (0.0, 0.0, 0.5); viewer.addPointCloudNormals<pcl::PointXYZ,pcl::Normal>(cloud, normals); while (!viewer.wasStopped ()) { viewer.spinOnce (); } return 0; }
#說明
現在,讓我們逐一分解程式碼。在第一部分中,我們從一個檔案中載入一個點雲:
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile ("table_scene_mug_stereo_textured.pcd", *cloud);
在第二部分中,我們為法向量估計建立一個物件並計演算法線:
// estimate normals 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);
以下法向量估計方法可用:
enum NormalEstimationMethod
{
COVARIANCE_MATRIX,
AVERAGE_3D_GRADIENT,
AVERAGE_DEPTH_CHANGE
};
COVARIANCE_MATRIX模式建立9個積分影象,以從其本地鄰域的協方差矩陣計算特定點的法線。AVERAGE_3D_GRADIENT模式建立6個積分影象來計算水平和垂直3D梯度的平滑版本,並使用這兩個梯度之間的叉積計演算法線。AVERAGE_DEPTH_CHANGE模式只建立一個積分影象,並根據平均深度變化計演算法線。
在最後一部分,我們將點雲和相應的法線進行視覺化:
// visualize normals
pcl::visualization::PCLVisualizer viewer("PCL Viewer");
viewer.setBackgroundColor (0.0, 0.0, 0.5);
viewer.addPointCloudNormals<pcl::PointXYZ,pcl::Normal>(cloud, normals);
while (!viewer.wasStopped ())
{
viewer.spinOnce ();
}