PCL 曲面重建 贪婪三角

一、简单原理介绍

       将三维的点通过法向量投影到某一个平面,然后对投影得到的点云做平面内的三角化,从而得到个点的连接关系。

       在平面区域三角化的过程中用到了基于Delauney 的空间区域生长算法,这个方法通过选取一个样本三角片作为初始曲面,不断扩张曲面边界,最后形成一张完整的三角网格曲面,最后根据投影的点云连接关系确定各原始三维点之间的拓补连接,所得到的三角网格就是重建得到的曲面模型。

 该方法使用于 点云密度均匀,不能在算讲话的同时对曲面进行平滑和孔洞的修复。

 

二、步骤

1、求点云的法向量

2、将点云和其1计算的法向量放一起

3、使用法向量做曲面重建

4、显示 

三、显示

 


#if 1 //   曲面重建  - 贪婪三角
using namespace std;
int main()
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);			//待滤波点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);	//滤波后点云

    ///读入点云数据
    cout << "->正在读入点云..." << endl;
    pcl::PCDReader reader;
    reader.read("1.pcd", *cloud);
    cout << "\t\t<读入点云信息>\n" << *cloud << endl;


    //   由于贪婪三角是基于点的法向量的,因此我们需要开始的时候就要进行求法向量的操作
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
    pcl::PointCloud<pcl::Normal>::Ptr  normals(new  pcl::PointCloud<pcl::Normal>());
    // 我用要使用kd tree 来做法向量
    pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>());
    kdtree->setInputCloud(cloud);
    n.setInputCloud(cloud);
    n.setSearchMethod(kdtree);  // 在计算法向量的时候使用kdtree 作为方法
    n.setKSearch(20);  // k
    n.compute(*normals);  // 我们计算出了 法向量和曲率

    //我们要把点云和法向量都放到一起,因此我们需要对这个点云添加一个维度,这样才能做曲面重建
    pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);
    pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);  // concat 就是将xyz和normal 组合到一起


    //   再次创建一个kd tree 用来做曲面重建
    pcl::search::KdTree<pcl::PointNormal>::Ptr  kdtree_rec(new pcl::search::KdTree<pcl::PointNormal>());
    // 这里我们需要处理的是xyz +_normal 的点云和上面的点云的是不一样的
    kdtree_rec->setInputCloud(cloud_with_normals);


   // ===========================自此我们三角化的条件已经都准备好了,下面我们开始三角化=====================================
    pcl::GreedyProjectionTriangulation<pcl::PointNormal> gpt;    //  贪婪三角对象
    pcl::PolygonMesh triangles;  // 存储最终三件化的网格模型,
   
    // 三维曲面重建 ,设置参数
    gpt.setSearchRadius(0.025); // 设置搜索半径,也就是k -临近的球半径
    // 设置样本点到最近邻域距离的乘积系数mu 来获每个样本点的最大搜索距离,这样是的算法自适应点云密度的变化   ,简单理解就是一个系数的问题,也就是说当使用半径来找
    // 周围的点的时候,半径范围里面没有找到点,那么我们会启用radius *  gpt.setMu(2.5);  作为最远距离来找点(一定要看书,网上有的解释是错的这个系数在【2.5,3】
    gpt.setMu(2.5); 

    gpt.setMaximumNearestNeighbors(100);   // 设置样本点最多可以设置搜索的领域数目
    gpt.setMaximumSurfaceAngle(M_PI / 4);     //连接的时候最大的角度,当某点法线相当于采样点的法线偏离角度超过这个最大角度的时候,连接不考虑这个点
    gpt.setMinimumAngle(M_PI /18);  // 设置三角化后三角形的最小角度
    gpt.setMaximumAngle(2*M_PI/3); 

    // 设置法向量的朝向是不是要一致,true 表示一致,false表示不一样
    gpt.setNormalConsistency(false);

    // 开始三维曲面重建
    gpt.setInputCloud(cloud_with_normals);
    gpt.setSearchMethod(kdtree_rec);
    gpt.reconstruct(triangles);



    // std::cout << triangles;
     // Additional vertex information
    std::vector<int> parts = gpt.getPartIDs();                  //获取ID字段
    std::vector<int> states = gpt.getPointStates();             //获取点状态

    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
    ///*-----视口1-----*/
    //int v1(0);
    //viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); //设置第一个视口在X轴、Y轴的最小值、最大值,取值在0-1之间
    //viewer->setBackgroundColor(0, 0, 0, v1); //设置背景颜色,0-1,默认黑色(0,0,0)
    //viewer->addText("befor_filtered", 10, 10, "v1_text", v1);
    //viewer->addPointCloud<pcl::PointXYZ>(cloud, "befor_filtered_cloud", v1);

    ///*-----视口2-----*/
    //int v2(0);
    //viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
    //viewer->setBackgroundColor(0.3, 0.3, 0.3, v2);
    //viewer->addText("after_filtered", 10, 10, "v2_text", v2);
    //viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered, "after_filtered_cloud", v2);

    ///*-----设置相关属性-----*/
    //viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "befor_filtered_cloud", v1);
    //viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "befor_filtered_cloud", v1);

    //viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "after_filtered_cloud", v2);
    //viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "after_filtered_cloud", v2);

    可视化
    

    viewer->setBackgroundColor (0, 0, 0);
    viewer->addPolygonMesh(triangles,"mytriangles");

   // viewer->addCoordinateSystem (1.0);
    viewer->initCameraParameters ();
     // 主循环
    while (!viewer->wasStopped ())
    {
      viewer->spinOnce (100);
      boost::this_thread::sleep (boost::posix_time::microseconds (100000));
    }

    // Finish
    return (0);
}

#endif

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本人之前的毕业设计是基于点云数据的曲面重建,主要使用了PCL(Point Cloud Library)来实现。在该毕业设计中,我对PCL库进行了深入研究,并通过C++代码编写了一个可视化工具来展示曲面重建的效果。 曲面重建是将原始点云数据转化为几何体表面的过程,该技术广泛应用于计算机辅助设计、虚拟现实、三维打印等领域。本人的毕业设计主要是针对工业领域的测量数据进行曲面重建,其中包括了测量数据的处理与分析、曲面重建算法的深入研究以及可视化工具的设计和实现。在研究过程中,我主要使用了PCL库中的多种曲面重建算法,如Greedy Triangulation、Poisson Reconstruction、Marching Cubes等等,从而达到了不同程度的曲面重建效果。 在可视化工具的设计中,我使用了Qt进行界面设计和OpenCV进行图像处理,并通过OpenGL来呈现曲面重建结果。通过该工具,用户可以加载点云数据、选择不同的曲面重建算法、调整算法参数和查看曲面重建结果。该工具不仅可视化效果好,而且具有很高的交互性和易用性,用户可以很方便地对曲面重建进行操作和控制。 总体而言,通过本人的毕业设计,我对PCL库和曲面重建技术有了深入的了解,并取得了一定的研究成果。我相信这些研究成果对于工业领域的测量和模型制作有着重要的应用和推广价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值