首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

pcl实现Delaunay三角剖分重建网格

  • 23-11-18 01:42
  • 3703
  • 13296
blog.csdn.net

1.下采样
通常点云三角化算法计算量非常大,如果输入大量点云的话,运行时间可能会需要数十分钟甚至数个小时,因此,点云处理的第一步便是下采样。

//下采样
void downsampledPointcloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud)
{
	// 下采样
    pcl::VoxelGrid<PointT> downSampled;  //创建滤波对象
    downSampled.setInputCloud (cloud);            //设置需要过滤的点云给滤波对象
    downSampled.setLeafSize (0.01f, 0.01f, 0.01f);  //设置滤波时创建的体素体积为1cm的立方体
    downSampled.filter (*cloud_downSampled);           //执行滤波处理,存储输出
    pcl::io::savePCDFile ("downsampledPC.pcd", *cloud_downSampled);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.去除离群点(滤波)

//统计滤波
void statisOutlierRemoval(pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud_downSampled)
{
	// 统计滤波
    pcl::StatisticalOutlierRemoval<PointT> statisOutlierRemoval;       //创建滤波器对象
    statisOutlierRemoval.setInputCloud (cloud_downSampled);            //设置待滤波的点云
    statisOutlierRemoval.setMeanK (50);                                //设置在进行统计时考虑查询点临近点数
    statisOutlierRemoval.setStddevMulThresh (3.0);                     //设置判断是否为离群点的阀值:均值+1.0*标准差
    statisOutlierRemoval.filter (*cloud_filtered);                     //滤波结果存储到cloud_filtered
    pcl::io::savePCDFile ("filteredPC.pcd", *cloud_filtered);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3.点云平滑

//重采样平滑点云
void SmoothPointcloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud_in, pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud_out)
{
	// 对点云重采样  
    pcl::search::KdTree<PointT>::Ptr treeSampling (new pcl::search::KdTree<PointT>);// 创建用于最近邻搜索的KD-Tree
    pcl::PointCloud<PointT> mls_point;    //输出MLS
    pcl::MovingLeastSquares<PointT,PointT> mls; // 定义最小二乘实现的对象mls
    mls.setComputeNormals(false);  //设置在最小二乘计算中是否需要存储计算的法线
    mls.setInputCloud(cloud_filtered);         //设置待处理点云
    mls.setPolynomialOrder(2);            // 拟合2阶多项式拟合
    mls.setPolynomialFit(false);     // 设置为false可以 加速 smooth
    mls.setSearchMethod(treeSampling);         // 设置KD-Tree作为搜索方法
    mls.setSearchRadius(0.05);           // 单位m.设置用于拟合的K近邻半径
    mls.process(mls_point);                 //输出
    // 输出重采样结果
    cloud_smoothed = mls_point.makeShared();
    std::cout<<"cloud_smoothed: "<<cloud_smoothed->size() <<std::endl;
    //save cloud_smoothed
    pcl::io::savePCDFileASCII("cloud_smoothed.pcd",*cloud_smoothed);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.点云的法向量计算

//计算法线
pcl::PointCloud<pcl::Normal>::Ptr CalculateNormal(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud_in)
{
	// 法线估计
    pcl::NormalEstimation<PointT,pcl::Normal> normalEstimation;             //创建法线估计的对象
    normalEstimation.setInputCloud(cloud_smoothed);                         //输入点云
    pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>);// 创建用于最近邻搜索的KD-Tree
    normalEstimation.setSearchMethod(tree);
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); // 定义输出的点云法线
    // K近邻确定方法,使用k个最近点,或者确定一个以r为半径的圆内的点集来确定都可以,两者选1即可
    normalEstimation.setKSearch(10);// 使用当前点周围最近的10个点
    //normalEstimation.setRadiusSearch(0.03);            //对于每一个点都用半径为3cm的近邻搜索方式
    normalEstimation.compute(*normals);               //计算法线
    // 输出法线
    std::cout<<"normals: "<<normals->size()<<", "<<"normals fields: "<<pcl::getFieldsList(*normals)<<std::endl;
    pcl::io::savePCDFileASCII("normals.pcd",*normals);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

5.贪心三角化算法得到Mesh

//计算法线
pcl::PointCloud<pcl::Normal>::Ptr CalculateNormal(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud_in)
{
	 // 三角化
    pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;   // 定义三角化对象
    pcl::PolygonMesh triangles; //存储最终三角化的网络模型

    // 设置三角化参数
    gp3.setSearchRadius(0.1);  //设置搜索时的半径,也就是KNN的球半径
    gp3.setMu (2.5);  //设置样本点搜索其近邻点的最远距离为2.5倍(典型值2.5-3),这样使得算法自适应点云密度的变化
    gp3.setMaximumNearestNeighbors (100);    //设置样本点最多可搜索的邻域个数,典型值是50-100

    gp3.setMinimumAngle(M_PI/18); // 设置三角化后得到的三角形内角的最小的角度为10°
    gp3.setMaximumAngle(2*M_PI/3); // 设置三角化后得到的三角形内角的最大角度为120°

    gp3.setMaximumSurfaceAngle(M_PI/4); // 设置某点法线方向偏离样本点法线的最大角度45°,如果超过,连接时不考虑该点
    gp3.setNormalConsistency(false);  //设置该参数为true保证法线朝向一致,设置为false的话不会进行法线一致性检查

    gp3.setInputCloud (cloud_with_normals);     //设置输入点云为有向点云
    gp3.setSearchMethod (tree2);   //设置搜索方式
    gp3.reconstruct (triangles);  //重建提取三角化

    // 显示网格化结果
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
    viewer->setBackgroundColor(0, 0, 0);  //
    viewer->addPolygonMesh(triangles, "wangge");  //
    while (!viewer->wasStopped())
    {
    	viewer->spinOnce(100);
    	boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
    return 1;}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

https://gitee.com/junhaowu/pcl-mesh-reconstruction/tree/master源码

注:本文转载自blog.csdn.net的Ignorant_wu的文章"https://blog.csdn.net/Ignorant_wu/article/details/115030231"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top