贪婪投影三角化算法是一种对原始点云进行快速三角化的算法,该算法假设曲面光滑,点云密度变化均匀,不能在三角化的同时对曲面进行平滑和孔洞修复。

方法:

(1)将三维点通过法线投影到某一平面

(2)对投影得到的点云作平面内的三角化

(3)根据平面内三位点的拓扑连接关系获得一个三角网格曲面模型

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

该算法适用于采样点云来自表面连续光滑的曲面且点云的密度变化比较均匀的情况

pcl1.8.1+vs2015

#include<iostream>
#include<pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include<pcl/point_types.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/io/obj_io.h>
#include <pcl/surface/gp3.h>
#include <pcl/visualization/pcl_visualizer.h> int main(int argc, char** argv) {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
pcl::PCLPointCloud2 cloud_blob;
//*打开点云文件
if (pcl::io::loadPCDFile("rabbit.pcd", cloud_blob) == -1) {
PCL_ERROR("Couldn't read file rabbit.pcd\n");
return(-1);
}
pcl::fromPCLPointCloud2(cloud_blob, *cloud); //法线估计对象
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
//存储估计的法线
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
//定义kd树指针
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud(cloud);
n.setInputCloud(cloud);
n.setSearchMethod(tree);
n.setKSearch(20);
//估计法线存储到其中
n.compute(*normals);//Concatenate the XYZ and normal fields*
pcl::PointCloud<pcl::PointNormal>::Ptr cloud_width_normals(new pcl::PointCloud<pcl::PointNormal>);
//链接字段
pcl::concatenateFields(*cloud, *normals, *cloud_width_normals); //定义搜索树对象
pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
//点云构建搜索树
tree2->setInputCloud(cloud_width_normals); //定义三角化对象
pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
//存储最终三角化的网络模型
pcl::PolygonMesh triangles;//设置连接点之间的最大距离,(即是三角形最大边长)
gp3.setSearchRadius(200.0f);
//设置各种参数值
gp3.setMu(2.5f);
gp3.setMaximumNearestNeighbors(100);
gp3.setMaximumSurfaceAngle(M_PI_4);
gp3.setMinimumAngle(M_PI / 18);
gp3.setMaximumAngle(2 * M_PI / 3);
gp3.setNormalConsistency(false); //设置搜索方法和输入点云
gp3.setInputCloud(cloud_width_normals);
gp3.setSearchMethod(tree2); //执行重构,结果保存在triangles中
gp3.reconstruct(triangles); //保存网格图
//pcl::io::saveOBJFile("result.obj", triangles);
std::string output_dir = "E:/C/cloud_mesh.ply";
std::string sav = "saved mesh in:";
sav += output_dir;
pcl::console::print_info(sav.c_str());
std::cout << std::endl; pcl::io::savePLYFileBinary(output_dir.c_str(), triangles); // 显示结果图
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("MAP3D MESH"));
////设置背景;
viewer->setBackgroundColor(0, 0, 0);
//设置显示的网格
viewer->addPolygonMesh(triangles, "my");
//viewer->initCameraParameters();
while (!viewer->wasStopped()) {
viewer->spin();
}
std::cout << "success" << std::endl;
return 0;
}

运行结果

说明:

  需要处理的数据比较多,因此需要耐心等一会

  三角化后的文件保存在 E:/C/cloud_mesh.ply,用compareCloud打开

  

PCL贪婪投影三角化算法的更多相关文章

  1. Delaunay三角化算法

    参考:<平面域中的Delaunay三角算法>

  2. 用canvas 实现个图片三角化(LOW POLY)效果

    之前无意中看到Ovilia 用threejs做了个LOW POLY,也就是图片平面三角化的效果,觉得很惊艳,然后就自己花了点时间尝试了一下. 我是没怎么用过threejs,所以就直接用canvas的2 ...

  3. 三角化---深度滤波器---单目稠密重建(高翔slam---十三讲)

    一.三角化 [1]三角化得到空间点的三维信息(深度值) (1)三角化的提出 三角化最早由高斯提出,并应用于测量学中.简单来讲就是:在不同的位置观测同一个三维点P(x, y, z),已知在不同位置处观察 ...

  4. 多视几何——三角化求解3D空间点坐标

    VINS-Mono / VINS-Fusion中triangulatePoint()函数通过三角化求解空间点坐标,代码所体现的数学描述不是很直观,查找资料,发现参考文献[1]对这个问题进行详细解释,记 ...

  5. FPGA加三移位算法:硬件逻辑实现二进制转BCD码

    本文设计方式采用明德扬至简设计法.利用FPGA来完成显示功能不是个很理想的方式,当显示任务比较复杂,要通过各种算法显示波形或者特定图形时,当然要用单片机通过C语言完成这类流程控制复杂,又对时序要求不高 ...

  6. 三目算法、if/else,switch/case运用

    //输入学生的成绩,判断考试是否及格,及格6大于等于0 //第一种写法:三目运算 大多用于单独判断是否满足某个条件 import java.util.Scanner; public class Hel ...

  7. [CGAL]带岛多边形三角化

    CGAL带岛多边形三角化,并输出(*.ply)格式的模型 模型输出的关键是节点和索引 #include <CGAL/Triangulation_vertex_base_with_id_2.h&g ...

  8. K:找寻数组中第n大的数组元素的三个算法

    相关介绍:  给定一个数组,找出该数组中第n大的元素的值.其中,1<=n<=length.例如,给定一个数组A={2,3,6,5,7,9,8,1,4},当n=1时,返回9.解决该问题的算法 ...

  9. Schur 三角化定理的推论

    将学习到什么 从 Schur 的酉三角化定理可以收获一批结果,在这一部分介绍重要的几个.   迹与行列式 相似矩阵具有相同的特征多项式, 从特征多项式一节中, 我们又知道,相似矩阵的迹以及行列式都是相 ...

随机推荐

  1. Java中的map的遍历方法

    public static void main(String[] args) { Map<String, String> map = new HashMap<String, Stri ...

  2. Linux端口转发工具rinetd

    介绍:Rinetd是为在一个Unix和Linux操作系统中为重定向传输控制协议(TCP)连接的一个工具.Rinetd是单一过程的服务器,它处理任何数量的连接到在配置文件etc/rinetd中指定的地址 ...

  3. 002_Visual Studio (gnuplot)显示数组波形

    视频教程:https://v.qq.com/x/page/e3039v4j6zs.html 资料下载:https://download.csdn.net/download/xiaoguoge11/12 ...

  4. 洛谷 P3958 奶酪 题解

    思路: 先看哪两个点能互通,再广搜寻找下一步,如果到达高度h就输出Yes,如果所有路径都找过都不能到达高度h就输出No. #include<bits/stdc++.h> using nam ...

  5. python 字符串方法整理

    Python字符串方法 1.大小写转换 1.1 lower.upper lower():小写 upper():大写 1.2 title.capitalize S.title():字符串中所有单词首字母 ...

  6. 微信小程序基本语法

    渲染 .js page ({ data :{ memo:'hello world' } }) .wxml <view>{{memo}}</view> 绑定id .js page ...

  7. mysql ,limit 的使用

    //offset参数指定要返回的第一行的偏移量.第一行的偏移量为0,第二行的偏移量为1.count指定要返回的最大行数.LIMIT offset,count; mysql> select * f ...

  8. Git删除某个文件夹或整个仓库

    删除仓库: 进入仓库,选择settting: 拉到最下面,有个Danger Zone,里面有删除仓库选项: 输入仓库名称,即可删除: 删除某个文件:删除文件和文件夹只能用命令行删除. 如果直接git ...

  9. 服务器收不到支付宝notify_url异步回调请求的问题排查

    小背景 最近在调整支付宝支付的功能时发现,不能够正常接收支付宝付款成功之后的回调通知了,从代码到配置最后到服务器配置都排查了一遍,最终发现问题原因竟然是因为我们的回调地址notify_url是http ...

  10. mybatis or的用法

    @Test public void test3(){ CaseSmallListExample caseSmallListExample = new CaseSmallListExample(); c ...