測量較小的對象時產生一些誤差,直接重建會使曲面不光滑或者有漏洞,為了建立完整的模型需要對表面進行平滑處理和漏洞修復.可通過數據重建來解決這一問題,重采樣算法通過對周圍數據點進行高階多項式插值來重建表面缺少的部分.
由多個掃描配准后得到的數據直接拿來重建可能產生 "雙牆"等重影,即拼接的區域出現重疊的兩個曲面,重采樣算法可以對此問題進行處理.
pcl庫文件中 resampling.cpp代碼文件如下:
1 #include <pcl/point_types.h> 2 #include <pcl/io/pcd_io.h> 3 #include <pcl/kdtree/kdtree_flann.h> 4 #include <pcl/surface/mls.h> //最小二乘平滑處理類定義 5 6 int 7 main (int argc, char** argv) 8 { 9 // Load input file into a PointCloud<T> with an appropriate type 10 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> ()); 11 // Load bun0.pcd -- should be available with the PCL archive in test 12 pcl::io::loadPCDFile("davi.pcd", *cloud); 13 14 // Create a KD-Tree 15 pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>); 16 17 // Output has the PointNormal type in order to store the normals calculated by MLS 18 pcl::PointCloud<pcl::PointNormal> mls_points; 19 20 // Init object (second point type is for the normals, even if unused) 21 pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls; 22 // 設置在最小二乘計算中需要進行法線估計,不需要可跳過 23 mls.setComputeNormals (true); 24 25 // Set parameters 26 mls.setInputCloud (cloud); 27 mls.setPolynomialFit (true); //多項式擬合提高精度,可false 加快速度,或選擇其他來控制平滑過程 28 mls.setSearchMethod (tree); 29 mls.setSearchRadius (3); 30 31 // Reconstruct 32 mls.process (mls_points); 33 34 // Save output 35 pcl::io::savePCDFile ("davi-mls.pcd", mls_points); 36 }
如果法線與處理后原始數據必須在相同PointCloud 對象中,需將這兩個字段連接起來形成新的點雲.
下圖左為原始圖,通過20張不同角度的點雲拼接而成,左邊呈現重影,右圖為處理結果圖,重影消除.