测量较小的对象时产生一些误差,直接重建会使曲面不光滑或者有漏洞,为了建立完整的模型需要对表面进行平滑处理和漏洞修复.可通过数据重建来解决这一问题,重采样算法通过对周围数据点进行高阶多项式插值来重建表面缺少的部分.
由多个扫描配准后得到的数据直接拿来重建可能产生 "双墙"等重影,即拼接的区域出现重叠的两个曲面,重采样算法可以对此问题进行处理.
pcl库文件中 resampling.cpp代码文件如下:
#include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/kdtree/kdtree_flann.h> #include <pcl/surface/mls.h> //最小二乘平滑处理类定义 int main (int argc, char** argv) { // Load input file into a PointCloud<T> with an appropriate type pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> ()); // Load bun0.pcd -- should be available with the PCL archive in test pcl::io::loadPCDFile("davi.pcd", *cloud); // Create a KD-Tree pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>); // Output has the PointNormal type in order to store the normals calculated by MLS pcl::PointCloud<pcl::PointNormal> mls_points; // Init object (second point type is for the normals, even if unused) pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls; // 设置在最小二乘计算中需要进行法线估计,不需要可跳过 mls.setComputeNormals (true); // Set parameters mls.setInputCloud (cloud); mls.setPolynomialFit (true); //多项式拟合提高精度,可false 加快速度,或选择其他来控制平滑过程 mls.setSearchMethod (tree); mls.setSearchRadius (3); // Reconstruct mls.process (mls_points); // Save output pcl::io::savePCDFile ("davi-mls.pcd", mls_points); }
如果法线与处理后原始数据必须在相同PointCloud 对象中,需将这两个字段连接起来形成新的点云.
下图左为原始图,通过20张不同角度的点云拼接而成,左边呈现重影,右图为处理结果图,重影消除.