【PCL-4】点云平滑处理--移动最小二乘算法(MLS)

在测量较小的数据时会产生一些误差,这些误差所造成的不规则数据如果直接拿来曲面重建的话,会使得重建的曲面不光滑或者有漏洞,可以采用对数据重采样来解决这样问题,通过对周围的数据点进行高阶多项式插值来重建表面缺少的部分。

示例代码:

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>  //kd-tree搜索对象的类定义的头文件
#include <pcl/surface/mls.h>        //最小二乘法平滑处理类定义头文件

int main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
	pcl::io::loadPCDFile("E://TY//camport3-master//cylinder.pcd", *cloud);

	// 创建 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;

	// 定义最小二乘实现的对象mls
	pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls;

	mls.setComputeNormals(true);  //设置在最小二乘计算中需要进行法线估计

	// Set parameters
	mls.setInputCloud(cloud);
	mls.setPolynomialFit(true); //设置false,可以加速平滑
	mls.setSearchMethod(tree);
	mls.setSearchRadius(35.0); //单位m,设置用于拟合的K近邻半径

	// Reconstruct
	mls.process(mls_points); //输出

	// Save output
	pcl::io::savePCDFile("E://TY//camport3-master//bun0-mls2.pcd", mls_points);
}

注:调整etSearchRadius(35.0)参数值,确定搜索半径,在此半径里进行表面映射和曲面拟合,半径越小拟合后曲面的失真度越小,反之可能出现过拟合的现象。

参考链接 PCL: Surface模块之Moving Least Squares(移动最小二乘法)_movingleastsquares_云初的博客-优快云博客

总结:

点云数据模型构建处理流程:

### 移动最小二乘法用于点云平滑处理 #### 理论基础 移动最小二乘法(Moving Least Squares, MLS)是一种局部逼近技术,广泛应用于计算机图形学、计算几何等领域。该方法通过构建一系列局部多项式模型来近似原始数据集,从而达到平滑的效果[^1]。 #### 实现过程 对于每一个待处理的目标点,在其邻域内选取一定数量的样本点构成子集;然后基于这些样本点建立一个低阶多项式方程组,并利用加权最小二乘准则求解最优系数向量;最终得到的新位置即为目标点经过MLS变换后的坐标值。此过程中权重函数的选择至关重要,它决定了不同距离上邻居节点的影响程度[^2]。 #### 参数配置 在实际操作中,可以通过调整`polynomial_order`参数指定拟合使用的最高次幂,默认情况下推荐采用二次项(`setPolynomialOrder(2)`),因为过高的次数可能会增加不必要的复杂度并延长运算时间而不一定能带来更好的视觉效果[^3]。 ```cpp // 设置多项式的阶数为2 mls.setPolynomialOrder(2); ``` #### 应用实例 为了更好地展示MLS算法的具体应用方式,下面给出一段简单的C++代码片段作为示范: ```cpp #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/filters/mls.h> int main(int argc, char** argv){ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 加载输入文件 if (pcl::io::loadPCDFile<pcl::PointXYZ>("input.pcd", *cloud) == -1){ PCL_ERROR ("Couldn't read file input.pcd \n"); return (-1); } // 创建MLSSurface对象 pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>()); pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls; mls.setInputCloud(cloud); mls.setSearchMethod(tree); // 设定搜索半径 float radius = 0.03f; mls setSearchRadius(radius); // 使用标准正交基底进行重建 mls process(true); // 输出结果至新文件 pcl::PointCloud<pcl::PointNormal>::Ptr mls_points(mls.getOutput()); pcl::io::savePCDFileASCII("output.pcd",*mls_points); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值