PCL中GreedyProjection三角化算法简介与示例


文章目录

  • 前言
  • 一、PCL点云三角化
    • 1.1 Delaunay三角剖分
    • 1.2 贪婪三角化
  • 二、程序示例
  • 总结


前言

Delaunay三角剖分最初应用于2维领域,而与Greedy三角化算法的结合,使之成为目前在三维重建领域最为基础的算法原理之一,很多学者针对其原理进行改进用以三维点云模型的构建。


一、PCL点云三角化

1.1 Delaunay三角剖分

定义:假设点集中的一条边e(两个端点为a,b),e若满足下列条件,则称之为Delaunay边:存在一个圆经过a,b两点,圆内(圆上最多三点共圆)不含点集中任何其他的点。而Delaunay三角化就是指三角网格均是由Delaunay边组成,并满足最小角最大原则(在点集可能形成的三角剖分中,Delaunay三角剖分所形成的三角形的最小角最大)。

针对以上定义,目前已提出了很多经典的剖分算法,如Lawson算法、Bowyer-Watson算法。以上算法都很有意思,通过点插法实现,具体原理可以查看以下链接。
技术分享:Delaunay三角剖分算法介绍
在这里插入图片描述

1.2 贪婪三角化

PCL中采用将三维点云投影到二维平面的方法来实现三角剖分, 具体采用贪婪三角化算法。
其过程为:
1:计算点云中点的法线,再将点云通过法线投影到二维坐标平面。
2:使用基于Delaunay三角剖分的空间区域增长算法完成平面点集的三角化。
3:根据投影点云的连接关系确定原始三维点云间的拓扑关系,最终得到曲面模型。

PCL中的NormalEstimation和GreedyProjectionTriangulation类实现该计算过程。
源代码:

FFN和SFN是指两个不同方向的边缘邻域集,在connectPoint方法里完成计算。

/** \brief Index of the current query point **/
int R_;std::vector<int> ffn_;
std::vector<int> sfn_;
// Locating FFN and SFN to adapt distance thresholddouble sqr_source_dist = (coords_[R_] - coords_[source_[R_]]).squaredNorm ();double sqr_ffn_dist = (coords_[R_] - coords_[ffn_[R_]]).squaredNorm ();double sqr_sfn_dist = (coords_[R_] - coords_[sfn_[R_]]).squaredNorm ();double max_sqr_fn_dist = (std::max)(sqr_ffn_dist, sqr_sfn_dist);double sqr_dist_threshold = (std::min)(sqr_max_edge, sqr_mu * sqrDists[1]); //sqr_mu * sqr_avg_conn_dist);if (max_sqr_fn_dist > sqrDists[nnn_-1]){if (0 == increase_nnn4fn)PCL_WARN("Not enough neighbors are considered: ffn or sfn out of range! Consider increasing nnn_... Setting R=%d to be BOUNDARY!\n", R_);increase_nnn4fn++;state_[R_] = BOUNDARY;continue;}double max_sqr_fns_dist = (std::max)(sqr_source_dist, max_sqr_fn_dist);if (max_sqr_fns_dist > sqrDists[nnn_-1]){if (0 == increase_nnn4s)PCL_WARN("Not enough neighbors are considered: source of R=%d is out of range! Consider increasing nnn_...\n", R_);increase_nnn4s++;}

计算法线:

// Get the normal estimate at the current point 
const Eigen::Vector3f nc = (*input_)[(*indices_)[R_]].getNormalVector3fMap ();

三角化:

// Triangulatingif (angles_[2].visible == false){if ( !( (angles_[0].index == ffn_[R_] && angles_[1].index == sfn_[R_]) || (angles_[0].index == sfn_[R_] && angles_[1].index == ffn_[R_]) ) ){state_[R_] = BOUNDARY;}else{if ((source_[R_] == angles_[0].index) || (source_[R_] == angles_[1].index))state_[R_] = BOUNDARY;else{if (sqr_max_edge < (coords_[ffn_[R_]] - coords_[sfn_[R_]]).squaredNorm ()){state_[R_] = BOUNDARY;}else{tmp_ = coords_[source_[R_]] - proj_qp_;uvn_s[0] = tmp_.dot(u_);uvn_s[1] = tmp_.dot(v_);double angleS = std::atan2(uvn_s[1], uvn_s[0]);double dif = angles_[1].angle - angles_[0].angle;if ((angles_[0].angle < angleS) && (angleS < angles_[1].angle)){if (dif < 2*M_PI - maximum_angle_)state_[R_] = BOUNDARY;elsecloseTriangle (polygons);}else{if (dif >= maximum_angle_)state_[R_] = BOUNDARY;elsecloseTriangle (polygons);}}}}continue;}

源码中大量代码关注于三角形的连接问题。
最后调用MeshConstruction类的reconstruct方法进行表面重建。

template <typename PointInT> void
MeshConstruction<PointInT>::reconstruct (std::vector<pcl::Vertices> &polygons)
{if (!initCompute ()){polygons.clear ();return;}// Check if a space search locator was givenif (check_tree_){if (!tree_){if (input_->isOrganized ())tree_.reset (new pcl::search::OrganizedNeighbor<PointInT> ());elsetree_.reset (new pcl::search::KdTree<PointInT> (false));}// Send the surface dataset to the spatial locatortree_->setInputCloud (input_, indices_);}// Set up the output dataset//polygons.clear ();//polygons.reserve (2 * indices_->size ()); /// NOTE: usually the number of triangles is around twice the number of vertices// Perform the actual surface reconstructionperformReconstruction (polygons);deinitCompute ();
}

二、程序示例

//----------------------------------法线计算-----------------------------------pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree1(new pcl::search::KdTree<pcl::PointXYZ>);tree->setInputCloud(cloud);n.setInputCloud(cloud);n.setSearchMethod(tree1);n.setKSearch(20);n.compute(*normals);pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);//连接点云和法线pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);tree2->setInputCloud(cloud_with_normals);pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp;pcl::PolygonMesh triangles;gp.setSearchRadius(0.025);//设置搜索半径,即连接点的最大距离gp.setMu(2.5); //加权因子,对于每个样本点,其映射所选球的半径由mu与离样本点最近点的距离乘积决定,用以解决点云密度不均匀的问题,mu一般取值2.5-3gp.setMaximumNearestNeighbors(600); //最大领域点个数gp.setMaximumSurfaceAngle(M_PI / 4);//临近点的法线和样本点法线的最大偏离角度gp.setMinimumAngle(M_PI / 18); //三角形最小角gp.setMaximumAngle(2 * M_PI / 3);//三角形最大角gp.setNormalConsistency(false); //保证法线朝向一致gp.setInputCloud(cloud_with_normals);gp.setSearchMethod(tree2);   gp.reconstruct(triangles);

在这里插入图片描述

总结

彻底理解三角化的源代码比较困难,缺少相关学习资料,欢迎共同研究,提出意见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/256058.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[设计模式]中介者模式之Events消息传递实现

这篇文章比较短,修改自 写给大家看的设计模式之中介者中的例子中介者模式的定义和目的自不必说, 参考上文即可. 本文针对实现方式做一个补充. 中介者模式增加了一个第三方对象(中介者)来控制两个对象(同事)间的交互. 有助于对彼此通信的解耦, 毕竟他们并不需要关心对方的实现细…

【pyqt5】 读取numpy arrray 显示图片

目录 1、GUI界面&#xff08;QT designer设计&#xff09; 2、逻辑函数&#xff08;回调等&#xff09; 3、显示图片在label上 0&#xff09;直接利用QPixmap显示图像 1&#xff09;显示彩色图 彩色图显示色调不正常——opencv&#xff08;BGR&#xff09;QT(RGB)需要进行…

[Django]SE项目回忆录(二)-注册/登录功能的实现及细节

该项目中提供了注册和登录两部分功能&#xff0c;功能描述如下&#xff1a; 注册&#xff1a; 允许任何用户进行学生身份的注册。 教师用户预先已经保存在数据库中&#xff0c;不允许以游客身份注册新的教师用户。 注册时需要填写的信息包括&#xff1a; - 用户名 - 密码(…

Zip4j开源jar包的简单使用

因为对项目突然要发送压缩加密的邮件附件&#xff0c;所以从网上看了一些资料说Zip4j开源框架比较好使&#xff0c;对中文的支持也比较好&#xff0c;所以从网上找了一个代码案例&#xff01;自己写了一写&#xff0c;现在贴出来&#xff0c;方便以后想用的时候好找 1、 1 pack…

【pyqt5】——入门级模板(ui文件+ui转py文件+逻辑py文件)(消息提示框)

目录 1、ui文件 2、ui转py文件 3、逻辑py文件 4、实例 1&#xff09;ui文件——demo.ui 2&#xff09;ui转py文件——demo.py 3)逻辑py文件——demoLogic.py 4)运行结果 1、ui文件 这个文件是直接通过pyqt5 designer进行设计的&#xff0c;相关配置可见《配置Qt Design…

PCL中点特征描述子PFH、FPFH和VFH简述和示例

文章目录前言一、点特征直方图1.1 PFH1.1.1 法线估计1.1.2 特征计算1.2 FPFH1.3 VFH二、示例2.1 PFH计算2.2 FPFH2.3 VFH前言 点特征直方图是PCL中非常重要的特征描述子&#xff0c;在点云匹配、分割、重建等任务中起到关键作用&#xff0c;可以对刚体变换、点云密度和噪声均有…

BZOJ 1005: [HNOI2008]明明的烦恼

BZOJ 1005: [HNOI2008]明明的烦恼 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在 任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N(0 < N < 1000), 接下来N行,第i1行给出第i个节点的度…

Apache Directory 指令

<Directory> 指令 语法&#xff1a;<Directory directory-path> ... </Directory> <Directory>和</Directory>用于封装一组指令&#xff0c;使之仅对某个目录及其子目录生效。任何可以在"directory"作用域中使用的指令都可以使用。Dir…

来一个炫酷的导航条

本文分享一个带动画效果的中英文切换导航条。 鼠标放上去试一下&#xff1a; INDEX 首页 BBS 社区 HOME 我 1.用CSS3实现 效果看上去复杂&#xff0c;其实我们先来做出一个样式&#xff0c;就很简单了。如下&#xff1a; 代码&#xff1a; <nav><ul class"list…

基于C++的opencv中Mat矩阵运算方法总结

文章目录前言一、Mat运算种类1.1 代数运算1.2 类型转换前言 Mat类是目前opencv最为常用的图像数据格式&#xff0c;其优点在于无需手动开辟内存空间和实时释放&#xff0c;针对此类的各种运算方法有很多&#xff0c;本文按照各种运算方法的种类进行简单的总结和示例。 一、Mat…

【pyqt5】——信号与槽

一、简单Demo 简单使用信号和槽&#xff08;之前常用的使用方式&#xff09;&#xff1a; class DemoWin(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):self.resize(400, 250)self.btn QPushButton("发送信号", self)# 发送…

JSON - 简介

JSON - 简介 JSON实例 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body> <h2>JavaScript 创建 JSON 对象</h2> <p> 网站名称: <spa…

mysql慢日志管理

一、日志切割 原理&#xff1a; 1、cp一个慢日志备份 2、清空原理的慢日志 3、写成脚本&#xff0c;每天一切&#xff0c;这样就ok啦 二、查找日志中的慢日志 1、做了日志切割&#xff08;慢日志文件就小了&#xff09; 2、查找某个时间的慢日志 日志时间格式&#xff1a; # Ti…

【深度学习】mask_rcnn训练自己的数据集以及模型使用(实践结合GitHub项目)

根据requirements - 开源项目默认的.txt进行库安装 环境&#xff1a;WIN10 Anoconda Pycharm python3.6.2 mask_rcnn基本流程1、训练 1)labelme进行目标物体标记&#xff0c;生成json文件&#xff0c;含点坐标、以及各个物体的标签label; json文件的格式&#xff1a;&…

EXCEL小技巧:如何统计非空单元格

http://club.excelhome.net/thread-1187271-1-1.html 下面教大家如果用函数统计非空单元格的数量 首先我们来介绍几个统计函数&#xff1a; 1.COUNT(value1,value2,...) 统计包含数字的单元格个数 2.COUNTA(value1,value2,...) 统计非空单元格的个数 3.COUNTBLANK(range&…

easyui 页签

昨天开始搭后台框架&#xff0c;到晚上的时候遇到了一个现在觉得挺可笑但是当时一直很纠结很纠结的问题&#xff0c;这个问题刚刚解决出来&#xff0c;把它拿出来说说&#xff0c;让自己长点儿记性&#xff0c;希望大家不要犯我这个错误啊 在backstage.jsp页面中我写了一个方法…

未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序。

报错信息&#xff1a; 解决方案&#xff1a; 1、“设置应用程序池默认属性”/“常规”/”启用32位应用程序”&#xff0c;设置为 true。 如下图所示&#xff1a;&#xff08;已测试&#xff0c;好使&#xff09; 方法二&#xff1a;生成->配置管理器->平台->点击Any C…

UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figur

“UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure”在利用mask_rcnn进行物体检测的时候出现的问题&#xff0c;主要是因为matplotlib的使用格式不对 可以检查者两个地方&#xff1a; 1、visualize.py中 import mat…

008. 限制上传文件的大小

第一种方法: 利用web.config的配置文件项, 进行设置; 前端aspx示例: <% Page Language"C#" AutoEventWireup"true" CodeFile"sendOutEmail.aspx.cs" Inherits"sendOutEmail" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHT…

查询实例及其代码

一、 设有一数据库&#xff0c;包括四个表&#xff1a;学生表&#xff08;Student&#xff09;、课程表&#xff08;Course&#xff09;、成绩表&#xff08;Score&#xff09;以及教师信息表&#xff08;Teacher&#xff09;。四个表的结构分别如表1-1的表&#xf…