估計點雲中的表面法線


翻譯自:http://www.pointclouds.org/documentation/tutorials/normal_estimation.php#normal-estimation

線是幾何表面的重要屬性,並且在諸如計算機圖形應用的許多領域中被大量使用,以應用產生陰影和其他視覺效果的正確光源。

給定幾何表面,通常在表面上的某個點處推斷法線的方向作為垂直於該點的表面的向量通常是繁瑣的。 但是,由於我們獲取了代表真實表面點雲數據集上的一組點樣本,因此有兩種方法:

  使用表面網格划分技術從獲取的點雲數據集中獲取下伏曲面,然后從網格中計算曲面法線;
  使用近似值直接從點雲數據集推斷出曲面法線。
本教程將針對后者,即給定點雲數據集,直接計算雲中每個點的曲面法線。

 

理論基礎
雖然存在許多不同的常規估計方法,但我們將專注於本教程的方法是最簡單的方法之一,其公式如下。 確定表面上的點的法線的問題可以近似轉化成估計與表面相切的平面的法線的問題,這又成為最小二乘平面擬合估計問題。

因此,用於估計表面法線的解決方案被簡化為對從查詢點的最近鄰居創建的協方差矩陣的特征向量和特征值(或PCA-主成分分析)的分析。 更具體地,對於每個點 ,我們如下組裝協方差矩陣

其中k是在  的鄰域中考慮的點鄰居的數量, 表示最近鄰居的3D質心, 是協方差矩陣的第j個特征值,並且 是第j個本征向量。

要從PCL中的一組點估計協方差矩陣,您可以使用:

 // Placeholder for the 3x3 covariance matrix at each surface patch
  Eigen::Matrix3f covariance_matrix;
  // 16-bytes aligned placeholder for the XYZ centroid of a surface patch
  Eigen::Vector4f xyz_centroid;

  // Estimate the XYZ centroid
  compute3DCentroid (cloud, xyz_centroid);

  // Compute the 3x3 covariance matrix
  computeCovarianceMatrix (cloud, xyz_centroid, covariance_matrix);

 

估計法線:

#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>

{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

  ... read, pass in or create a point cloud ...

  // Create the normal estimation class, and pass the input dataset to it
  pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
  ne.setInputCloud (cloud);

  // Create an empty kdtree representation, and pass it to the normal estimation object.
  // Its content will be filled inside the object, based on the given input dataset (as no other search surface is given).
  pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
  ne.setSearchMethod (tree);

  // Output datasets
  pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);

  // Use all neighbors in a sphere of radius 3cm
  ne.setRadiusSearch (0.03);

  // Compute the features
  ne.compute (*cloud_normals);

  // cloud_normals->points.size () should have the same size as the input cloud->points.size ()*
}

 

如果您的數據集是有組織的(例如,使用TOF相機,立體相機等獲取 - 也就是說,它具有寬度和高度),為了獲得更快的結果,可以使用積分圖像來估計法線。

 

利用積分圖像估計法線,代碼如下:(用 VS2015 pro 運行時出現報錯,顯示為內存出錯。。。)

 #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;
     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM