参考:
https://mp.weixin.qq.com/s/GFDWOudJ08In6jFyrZ7hhg
https://mp.weixin.qq.com/s/FfHkVY-lmlOSf4jKoZqjEA

通过之前的两篇文章,从得到点云,到对点云的下采样,去离群点。接着就是对点云的平滑,计算法线,最后生成Mesh。

点云平滑

平滑也是滤波的一种,让点云看起来稍微光滑一些。存在一些不规则数据,很难用前面提到过的统计分析等滤波方法消除,就需要平滑来处理和修复漏洞。
平滑操作在配准之后。
我使用的平滑的方法是重采样,实质上是移动最小二乘(MLS)。
主要的类是 pcl::MovingLeastSquares ,用它进行重采样操作。
参数啥的我其实还是不会调,还是用的别人的东西。

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

KdTree我理解为方便管理点云中的点的一个结构,通过这个二叉树可以方便的找到我们所要的某个点。
KDTree参考: https://blog.csdn.net/fandq1223/article/details/53176098
setSearchRadius 搜索某个点周围5cm处的所有点,用二阶多项式拟合这些点。

平滑点云之后,开始下一步操作:

点云的法向量计算

由于计算点云的法向量而不是Mesh的法向量,因此比较麻烦。目前是两种重建算法,使用曲面重建的方法 和 使用近似值直接从点云中推断法线。
由于刚刚接触,参考资料中使用的是后一种方法,从该点最近邻计算的协方差矩阵的特征向量和特征值的分析,直接调用PCL封装好的函数即可。
pcl::NormalEstimation 估计法线的类

//计算法线
pcl::PointCloud<pcl::Normal>::Ptr CalculateNormal(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud_in)
{// 法线估计pcl::StopWatch time;std::cout << "begin compute normal.... " << std::endl;pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal> normalEstimation;                    //创建法线估计的对象normalEstimation.setInputCloud(cloud_in);                                    //输入点云pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZRGB>);          // 创建用于最近邻搜索的KD-TreenormalEstimation.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 << "success compute normal,time(s):  "<< time.getTimeSeconds() << std::endl;return normals;
}

这个函数是我写的函数,接受输入点云Ptr,返回法向量Ptr。normalEstimation.setKSearch(10) 这个参数对于法向量的估计影响还是比较大的,不能太大,也不能太小。

之后在计算好了法向量,就可以得到Mesh了。

贪心三角化算法得到Mesh

点云构成三角网格的流程。Mesh存储的信息为:顶点索引,边索引,面片索引。
目前网格生成分为两大类算法,插值法(通过原始数据点得到)和逼近法(用分片线性曲面逼近原始点集)。
pcl::GreedyProjectionTriangulation 贪心三角化算法计算Mesh,使用贪心投影三角化对有向点云进行三角化,它更适用于采样点云来自表面连续光滑的曲面,并且点云的密度变化比较均匀的情况。
流程(参考资料上很详细,PCL都封装好了):

  1. 先将点云根据法向量投影到某个二维平面上(为某一个样本三角面片);
  2. 对该平面内的投影后的点云做三角化(基于Delaunay三角剖分 )得到投影后的点的拓扑连接关系
  3. 得到拓扑连接之后各三维点的拓扑链接就出来了,得到了Mesh。

在平滑之后要处理掉 InvalidPoints 否则无法进行Mesh。


#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/mls.h> //最小二乘 重采样平滑
#include <pcl/surface/poisson.h>  //泊松重建
#include <pcl/geometry/polygon_mesh.h> //MESH
#include <pcl/surface/gp3.h>  //贪心三角形//贪心三角化算法得到Mesh
pcl::PolygonMesh greedy_traingle_GenerateMesh(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_in, pcl::PointCloud<pcl::Normal>::Ptr normals)
{   pcl::StopWatch time;std::cout << "begin  mesh..." << std::endl;pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZRGB>());SmoothPointcloud(cloud_in, cloud_out);EraseInvalidPoints(cloud_out);// 将点云位姿、颜色、法线信息连接到一起pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointXYZRGBNormal>);pcl::concatenateFields(*cloud_in, *normals, *cloud_with_normals);//定义搜索树对象pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointXYZRGBNormal>);tree2->setInputCloud(cloud_with_normals);// 三角化pcl::GreedyProjectionTriangulation<pcl::PointXYZRGBNormal> gp3;   // 定义三角化对象pcl::PolygonMesh triangles; //存储最终三角化的网络模型// 设置三角化参数gp3.setSearchRadius(0.1);  //设置搜索时的半径,也就是KNN的球半径gp3.setMu(2.5);  //设置样本点搜索其近邻点的最远距离为2.5倍(典型值2.5-3),这样使得算法自适应点云密度的变化gp3.setMaximumNearestNeighbors(100);    //设置样本点最多可搜索的邻域个数,典型值是50-100gp3.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);  //重建提取三角化cloud_with_normals->width = cloud_with_normals->height = 0;std::cout << "success traingles, time(s) "<< time.getTimeSeconds() << std::endl;return triangles;
}

pcl::concatenateFields 的两个输入点云的大小一定要是一样的(点云个数),否则在处理的时候会报错。

点云到Mesh的流程大概就是:
下采样,滤波,平滑,法向量,Mesh

Mesh的效果和点云质量相关。我这里用的是RGB点云,Mesh里面就自带颜色的,因此没有Texture也可以看到颜色(否则还得自己做Texture,UV啥的都不会),如果要导入Unity,就得改一下输出格式和Shader。

这些流程不是最好的,可以做优化,等我学的多一些了。。。应该会做一下吧

PCL——从点云到网格(三)点云到Mesh相关推荐

  1. 深入小程序云开发之云函数 第三部分 云函数经验谈

    以下是我总结的要点: A. 云函数的文件组织 开发环境: 1. 假如你的项目根目录下project.config.json配置了: "cloudfunctionRoot": &qu ...

  2. 阿里云进阶课程三——基于云服务器构建微信公众号管理系统

    基于阿里云服务器构建微信公众号管理系统 准备工作 阿里云服务器镜像配置 FileZilla和终端工具安装 下载微擎压缩包 微擎的安装和配置 在云服务器上配置微擎文件 设置数据库信息 云服务器上安装微擎 ...

  3. 阿里云服务网格ASM集成SLS告警

    简介:随着微服务的流行,微服务的架构也在不断的发展演进,Spring Cloud 与 Dubbo为代表的微服务开发框架也得到了普及和落地:在云原生时代,无侵入的服务网格(Service Mesh)开始 ...

  4. 云上“两地三中心”,中小企业都用得起的多保险灾备方案

    在云时代,大部分中小型企业都奔跑在云上或是服务器托管公司.任何规模的数据中心服务中断都会让你的企业踩雷.据统计,80%的数据中心服务中断都是由服务器硬件造成的. 据万博智云不完全统计: 2021年3月 ...

  5. PCL点云使用贪婪三角化进行曲面重构

    一.PCL点云平滑和法线估计 题目:https://mp.weixin.qq.com/s?__biz=MzIxOTczOTM4NA==&mid=2247486705&idx=1& ...

  6. PCL——从点云到网格(一)利用OpenNI2和深度相机生成点云

    最近做毕设,学习了一下PCL的使用(C++).这几篇博客就记录一下自己做毕设的时候利用深度相机得到点云,最后生成Mesh的过程.效果应该不是最好的,但是先把流程记录下来,自己下次看的时候就知道大体流程 ...

  7. PCL点云处理之点云质心的三种计算方法(七十六)

    PCL点云处理之点云质心的三种计算方法(七十六) 一.质心? 二.算法实验 1.代码 2.效果 一.质心? 就计算某块点云坐标均值,可以调库,也可以自己算,easy 二.算法实验 1.代码 代码如下( ...

  8. 从零开始一起学习SLAM | 点云到网格的进化

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 小白:师兄,师兄,你在<从零开始一起学习SLAM | 给点云 ...

  9. CloudCompare:三维点云(网格)编辑和处理工具

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 本文来源:公众号@点云PCL,原文:CloudCompare的介绍 CloudCompare是一个三维 ...

最新文章

  1. Linux统计行数命令wc(转)
  2. javascript 通过键获取值
  3. git 撤销提交的文件
  4. 高层管理者对于大数据的6个误解
  5. 网站程序员的程序员成长之路大概分几个阶段 和未来的发展
  6. HDU-3729 二分匹配 匈牙利算法
  7. Mybatis源码阅读(一):Mybatis初始化1.1 解析properties、settings
  8. e0312 不存在用户定义的_更加灵活的参数校验,Spring-boot自定义参数校验注解
  9. 本周论文推荐 -- 对抗生成网络、知识图谱补全、对话系统、文本生成
  10. We Recommend a Singular Value Decomposition
  11. Combobox MVVM绑定并设置选中
  12. Java设计模式系列之迭代器模式
  13. DropDownList的AppendDataBoundItems属性
  14. VS2013过期激活,VS2013激活,vs2013序列号,VS2013密钥,VS013产品密匙
  15. 可以放游戏网站云服务器,游戏网站选择哪个云服务器好?游戏服务器配置方案?...
  16. 【自动驾驶】华为车BU介绍(2021-11-23晚直播记录)
  17. 保存下载图片(taro h5)
  18. 2008年8月6号,晴,今天天气已经变热了。少壮不努力,老大徒悲伤。 —— 汉乐府古辞《长歌行》
  19. 北科计算机研究生导师推荐,北京科技大学计算机与通信工程学院-【喜报】我院班晓娟老师荣获第三届“研师亦友——我最喜爱的导师”称号...
  20. mysql直方图_MySQL · 特性分析 · 直方图的实现与分析

热门文章

  1. 手把手带你制作WIFI智能开关.走进物联网-ESP8266学习日记(三)
  2. excel组合汇总_Excel汇总20150525
  3. 闲聊程序员的那些事儿
  4. 周娟56.com(我乐网)CEO访谈
  5. 拿几千块钱炒股有意义吗?
  6. 互联网早报:抖音内测“学习”入口:加码知识视频内容创作
  7. cocoscreator,RenderTexture实现残影效果
  8. Modbus扫描工具
  9. 帝国插件-最全帝国插件中心免费下载
  10. 新品上市调查方案-研究方案设计