一、MLS基礎
mls算法本質上和最小二乘一樣,是一種擬合數據的算法。區別在于mls是局部的,即通過系數向量和基函數分別對數據中不同位置的節點區域進行擬合,需要計算出全部節點域的擬合函數的參數。而傳統的最小二乘是全局的,采用所有的數據進行最小化平方和,不能過濾掉噪聲點。
對于二維數據點,其擬合公式如下:
其中:
w為權函數,一般采用三次樣條曲線,如果權函數為常量,則為一般的加權最小二乘算法。
n表示為包含在權函數w支持域中的節點數。
p(x)表示基函數,對于不同的數據維度和需要擬合的目標可以選擇不同階數的基函數。
a(x)表示系數向量,我們最后就需要計算出a向量的值。
u表示在x處的取值。
J表示在節點x位置的模型函數。
計算流程可以分為三步:
1,對J函數求導,得到一個線性方程組。
2,對線性方程組計算,求得a向量的值。
3,重建節點x附近的擬合函數,計算出擬合函數。
具體原理部分設計的數學計算太多,參看鏈接。
原理部分參考:
移動最小二乘法MLS(Moving Lest Squares)簡要介紹
無網格法與Matlab程序設計(7)——移動最小二乘(MLS)形函數
對于三維數據點,計算步驟相似:
1,計算局部K鄰域范圍內的的超平面,超平面的法向量即為該處的的法線。
2,進行最小二乘擬合,最終得到擬合面的點坐標。
二、示例
mls算法目前廣泛應用于三維模型的法線計算,上采樣,曲面平滑。
2.1 法線計算
PCL中可以先進行曲面重建,再根據曲面計算法線。
pcl::search::KdTree<pcl::PointXYZ>::Ptr kd_tree(new pcl::search::KdTree<pcl::PointXYZ>);//法線pcl::PointCloud<pcl::PointNormal>::Ptr normal(new pcl::PointCloud<pcl::PointNormal>);//實例化移動最小二乘類pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls;mls.setInputCloud(cloud);mls.setComputeNormals(true); mls.setPolynomialFit(true); mls.setPolynomialOrder(2); //設置多項式階數 mls.setSearchMethod(kd_tree); mls.setSearchRadius(0.05); //設置kdtree搜索半徑mls.setNumberOfThreads(4); mls.process(*normal); //使用mls方法計算法線并進行曲面重建
2.2 上采樣
PCL中上采樣方法是通過計算鄰域內擬合MLS局部曲面,然后根據曲面計算法線和點云間的插值坐標,最后將插值坐標映射到輸入點云內。
算法原理部分非常復雜。。想研究的直接去看論文。
PCL提供了三種采樣方式。
SAMPLE_LOCAL_PLANE:每個輸入點的局部平面將使用 upsampling_radius_ (半徑)和 upsampling_step_ (移動步長)參數以圓形方式采樣。
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree;
UpSample.setSearchMethod(tree);
UpSample.setSearchRadius(0.1);
//移動最小二乘
UpSample.setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ>::SAMPLE_LOCAL_PLANE);
UpSample.setUpsamplingRadius(0.04);
UpSample.setUpsamplingStepSize(0.02);
UpSample.process(*CloudUp);