Bootstrap

PCL点云重建源代码,实现点云的去噪滤波、平滑、采样、重建

#include <pcl/point_types.h>
#include <pcl/io/ply_io.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/surface/mls.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>
#include <pcl/visualization/pcl_visualizer.h>

typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud<PointT> PointCloudT;
typedef pcl::PointNormal NormalT;
typedef pcl::PointCloud<NormalT> PointCloudWithNormals;

int main(int argc, char** argv) {
    // 1. 读取点云数据
    PointCloudT::Ptr cloud(new PointCloudT);
    if (pcl::io::loadPLYFile<PointT>("D:\\Model\\pointcloud.ply", *cloud) == -1) {
        std::cerr << "Error loading point cloud" << std::endl;
        return -1;
    }

    // 2. 预处理 - 去噪
    pcl::StatisticalOutlierRemoval<PointT> sor;
    sor.setInputCloud(cloud);
    sor.setMeanK(50);         // 考虑邻近50个点
    sor.setStddevMulThresh(1.0); // 标准差倍数阈值
    sor.filter(*cloud);

    // 3. 下采样
    pcl::VoxelGrid<PointT> voxel;
    voxel.setInputCloud(cloud);
    voxel.setLeafSize(0.5f, 0.5f, 0.5f); // 根据点云密度调整
    voxel.filter(*cloud);

    // 4. 平滑处理 (移动最小二乘法)
    pcl::MovingLeastSquares<PointT, NormalT> mls;
    pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>);
    mls.setInputCloud(cloud);
    mls.setSearchMethod(tree);
    mls.setSearchRadius(2.0);  // 根据点间距调整
    mls.setComputeNormals(true);

    PointCloudWithNormals::Ptr cloud_smoothed(new PointCloudWithNormals);
    mls.process(*cloud_smoothed);

    // 5. 法线估计(如果MLS未计算)
    pcl::NormalEstimation<PointT, NormalT> ne;
    ne.setInputCloud(cloud);
    ne.setSearchMethod(tree);
    ne.setRadiusSearch(2.0);   // 与MLS半径一致
    ne.compute(*cloud_smoothed);

    // 6. 贪心投影三角化(适合开放边缘)
    pcl::GreedyProjectionTriangulation<NormalT> gp3;
    pcl::PolygonMesh triangles;

    // 设置重建参数
    gp3.setSearchRadius(3.0);      // 搜索半径(点间距的3-5倍)
    gp3.setMu(2.5);               // 最大允许距离乘数
    gp3.setMaximumNearestNeighbors(100); // 最大邻近点数
    gp3.setMaximumSurfaceAngle(M_PI / 2); // 45度
    gp3.setMinimumAngle(M_PI / 18); // 10度
    gp3.setMaximumAngle(2 * M_PI / 3); // 120度
    gp3.setNormalConsistency(true); // 保持法线一致性

    gp3.setInputCloud(cloud_smoothed);
    gp3.reconstruct(triangles);

     7. 后处理 - 网格平滑
    //pcl::MeshSmoothingLaplacianVTK smoother;
    //smoother.setInputMesh(triangles);
    //smoother.setNumIterations(50);  // 平滑迭代次数
    //smoother.process(triangles);

    // 8. 保存结果
    pcl::io::savePLYFile("output_mesh.ply", triangles);

    // 可视化 (可选)
    pcl::visualization::PCLVisualizer viewer("Mesh Viewer");
    viewer.addPolygonMesh(triangles, "mesh");
    while (!viewer.wasStopped()) {
        viewer.spinOnce();
    }

    return 0;
}

;