該算法比直接基於SVD的算法慢,可是對法向進行了統一。算法
#include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/features/normal_3d.h> #include <pcl/kdtree/kdtree_flann.h> #include <pcl/surface/mls.h> #include <pcl/console/time.h> #include <pcl/visualization/cloud_viewer.h> #include <pcl/visualization/pcl_visualizer.h> //包含基本可視化類 #include <boost/thread/thread.hpp> #include <pcl/point_cloud.h> using namespace std; typedef pcl::PointXYZ point; typedef pcl::PointCloud<point> pointcloud; int main (int argc,char **argv) { pointcloud::Ptr cloud (new pointcloud); pcl::io::loadPCDFile(argv[1],*cloud); cout<<"points size is:"<<cloud->size()<<endl; pcl::search::KdTree<point>::Ptr tree (new pcl::search::KdTree<point>); //建立存儲的mls對象 pcl::PointCloud<pcl::PointNormal> mls_points; // pcl::PointCloud<point> mls_points; //建立mls對象 pcl::MovingLeastSquares<point,pcl::PointNormal> mls; // pcl::MovingLeastSquares<point,point> mls; mls.setComputeNormals(true); mls.setInputCloud(cloud); mls.setPolynomialFit(true); //設置爲true則在平滑過程當中採用多項式擬合來提升精度 mls.setPolynomialOrder(2); //MLS擬合的階數,默認是2 mls.setSearchMethod(tree); mls.setSearchRadius(5.1); //搜索半徑 mls.process(mls_points); pcl::PointCloud<pcl::PointNormal>::Ptr mls_points_normal (new pcl::PointCloud<pcl::PointNormal>); mls_points_normal = mls_points.makeShared(); cout<<"mls poits size is: "<<mls_points.size()<<endl; boost::shared_ptr<pcl::visualization::PCLVisualizer> view(new pcl::visualization::PCLVisualizer ("test")); view->setBackgroundColor(0.0,0,0); pcl::visualization::PointCloudColorHandlerCustom<pcl::PointNormal> v(mls_points_normal,0,250,0); view->addPointCloud<pcl::PointNormal>(mls_points_normal,v,"sample"); view->addPointCloudNormals<pcl::PointNormal>(mls_points_normal,10,10,"normal"); view->addCoordinateSystem(1.0); //創建空間直角座標系 view->spin(); // Save output pcl::io::savePCDFile ("mid-mls.pcd", mls_points); }
第一幅圖片爲基於MLS計算的法向,並進行了統一。
第二幅圖片爲SVD計算,法向具備二異性。segmentfault