文章目录

  • 1. B样条曲线
  • 2. B样条曲面
  • 3. 多个B样条曲面的全局优化

1. B样条曲线

基于点距离最小化的三维B样条曲线拟合:
fitting_curve_pdm.h
fitting_curve_pdm.cpp

主要函数:

1)求点xixixi在节点向量的哪个区间:

        /** \brief Find the element in which the parameter xi lies.* \param[in] xi value in parameter domain of the B-Spline curve.* \param[in] elements the vector of elements of the curve.* \return index of the element with respect to elements. */static intfindElement (double xi, const std::vector<double> &elements);

2)通过每两个节点间插入中间节点修正曲线:

/** \brief Refines curve by inserting a knot in the middle of each element. */voidrefine ();

3)根据约束条件,给定系统方程组:

/** \brief Assemble the system of equations for fitting* - for large point-clouds this is time consuming.* - should be done once before refinement to initialize the starting points for point inversion. */voidassemble (const Parameter &parameter);

4)求解系统方程组,可以选择使用Eigen或UmfPack:

/** \brief Solve system of equations using Eigen or UmfPack (can be defined in on_nurbs.cmake),* and updates B-Spline curve if a solution can be obtained. */voidsolve (double damp = 1.0);

5)更新曲线:

/** \brief Update curve according to the current system of equations.* \param[in] damp damping factor from one iteration to the other. */voidupdateCurve (double damp);

6)使用边界点构成的圆或者PCA初始化曲线:

/** \brief Initialize a closed B-Spline curve using the bounding circle of the point-cloud.* \param[in] order polynomial order of the curve.* \param[in] data 3D point-cloud* \return B-Spline curve. */static ON_NurbsCurveinitNurbsCurve2D (int order, const vector_vec2d &data);/** \brief Initialize a closed B-Spline curve using the eigenvalues as elliptic parameters (z=0).* \param[in] order polynomial order of the curve.* \param[in] data 3D point-cloud* \return B-Spline curve. */static ON_NurbsCurveinitNurbsCurvePCA (int order, const vector_vec3d &data, int ncps = 0, double rf = 1.0);

7)点反演,给定一个点pt,使用牛顿法、L2范数,求取曲线上最近的点:

 /** \brief Inverse mapping / point inversion: Given a point pt, this function finds the closest* point on the B-Spline curve using Newtons method and point-distance (L2-, Euclidean norm).* \param[in] nurbs the B-Spline curve.* \param[in] pt the point to which the closest point on the curve will be computed.* \param[in] hint the starting point in parametric domain (warning: may lead to convergence at local minima).* \param[in] error the distance between the point pt and p after convergence.* \param[in] p closest point on curve.* \param[in] t the tangent vector at point p.* \param[in] maxSteps maximum number of iterations.* \param[in] accuracy convergence criteria: if error is lower than accuracy the function returns* \return closest point on curve in parametric domain.*/static doubleinverseMapping (const ON_NurbsCurve &nurbs, const Eigen::Vector3d &pt, const double &hint, double &error,Eigen::Vector3d &p, Eigen::Vector3d &t, int maxSteps = 100, double accuracy = 1e-6,bool quiet = true);

总结:

PCL中B样条曲线拟合的思路是,对初始化的曲线,通过不断插入中间节点来修正曲线,每次求解过程通过点线距离约束,构造矩阵方程组,求解得到控制点,不断迭代修正,对于稠密点云,求解线性方程组的过程较慢,导致拟合速度较慢,使用UmfPack可加快求解速度。

2. B样条曲面

主要用到pdm、sdm两种距离度量:
fitting_surface_pdm.h、fitting_surface_pdm.cpp

fitting_surface_sdm.h、fitting_surface_sdm.cpp

主要函数:
1)得到某个维度上的节点向量:

/** \brief Get the elements of a B-Spline surface.*/static std::vector<double>getElementVector (const ON_NurbsSurface &nurbs, int dim);

2)初始化曲面,可以使用4个角点、PCA或者PCA+边界点:

/** \brief Initializing a B-Spline surface using 4 corners */static ON_NurbsSurfaceinitNurbs4Corners (int order, ON_3dPoint ll, ON_3dPoint lr, ON_3dPoint ur, ON_3dPoint ul);/** \brief Initializing a B-Spline surface using principal-component-analysis and eigen values */static ON_NurbsSurfaceinitNurbsPCA (int order, NurbsDataSurface *data, Eigen::Vector3d z = Eigen::Vector3d (0.0, 0.0, 1.0));/** \brief Initializing a B-Spline surface using principal-component-analysis and bounding box of points */static ON_NurbsSurfaceinitNurbsPCABoundingBox (int order, NurbsDataSurface *data, Eigen::Vector3d z = Eigen::Vector3d (0.0, 0.0, 1.0));

3)给定一个点pt,使用牛顿法,pdm距离或者sdm距离求解曲面上的最近一点:

      /** \brief Inverse mapping / point inversion: Given a point pt, this function finds the closest* point on the B-Spline surface using Newtons method and point-distance (L2-, Euclidean norm).* \param[in] nurbs the B-Spline surface.* \param[in] pt the point to which the closest point on the surface will be computed.* \param[in] hint the starting point in parametric domain (warning: may lead to convergence at local minima).* \param[in] error the distance between the point pt and p after convergence.* \param[in] p closest point on surface.* \param[in] tu the tangent vector at point p in u-direction.* \param[in] tv the tangent vector at point p in v-direction.* \param[in] maxSteps maximum number of iterations.* \param[in] accuracy convergence criteria: if error is lower than accuracy the function returns* \return closest point on surface in parametric domain.*/static Eigen::Vector2dinverseMapping (const ON_NurbsSurface &nurbs, const Eigen::Vector3d &pt, const Eigen::Vector2d &hint,double &error, Eigen::Vector3d &p, Eigen::Vector3d &tu, Eigen::Vector3d &tv, int maxSteps = 100,double accuracy = 1e-6, bool quiet = true);static Eigen::Vector2dinverseMapping (const ON_NurbsSurface &nurbs, const Eigen::Vector3d &pt, const Eigen::Vector2d &hint,Eigen::Vector3d &p, int maxSteps, double accuracy, bool quiet);

4)给定一个点pt,使用牛顿法,pdm距离或者sdm距离求解曲面边界上的最近一点:

 /** \brief Inverse mapping / point inversion: Given a point pt, this function finds the closest* point on the boundary of the B-Spline surface using Newtons method and point-distance (L2-, Euclidean norm).* \param[in] nurbs the B-Spline surface.* \param[in] pt the point to which the closest point on the surface will be computed.* \param[in] error the distance between the point pt and p after convergence.* \param[in] p closest boundary point on surface.* \param[in] tu the tangent vector at point p in u-direction.* \param[in] tv the tangent vector at point p in v-direction.* \param[in] maxSteps maximum number of iterations.* \param[in] accuracy convergence criteria: if error is lower than accuracy the function returns* \return closest point on surface in parametric domain.*/static Eigen::Vector2dinverseMappingBoundary (const ON_NurbsSurface &nurbs, const Eigen::Vector3d &pt, double &error,Eigen::Vector3d &p, Eigen::Vector3d &tu, Eigen::Vector3d &tv, int maxSteps = 100,double accuracy = 1e-6, bool quiet = true);/** \brief Inverse mapping / point inversion: Given a point pt, this function finds the closest* point on one side of the boundary of the B-Spline surface using Newtons method and* point-distance (L2-, Euclidean norm).* \param[in] nurbs the B-Spline surface.* \param[in] pt the point to which the closest point on the surface will be computed.* \param[in] side the side of the boundary (NORTH, SOUTH, EAST, WEST)* \param[in] hint the starting point in parametric domain (warning: may lead to convergence at local minima).* \param[in] error the distance between the point pt and p after convergence.* \param[in] p closest boundary point on surface.* \param[in] tu the tangent vector at point p in u-direction.* \param[in] tv the tangent vector at point p in v-direction.* \param[in] maxSteps maximum number of iterations.* \param[in] accuracy convergence criteria: if error is lower than accuracy the function returns* \return closest point on surface in parametric domain.*/static Eigen::Vector2dinverseMappingBoundary (const ON_NurbsSurface &nurbs, const Eigen::Vector3d &pt, int side, double hint,double &error, Eigen::Vector3d &p, Eigen::Vector3d &tu, Eigen::Vector3d &tv,int maxSteps = 100, double accuracy = 1e-6, bool quiet = true);

5)根据约束条件,设定待求解的系统方程:

 /** \brief Assemble the system of equations for fitting* - for large point-clouds this is time consuming.* - should be done once before refinement to initialize the starting points for point inversion.*/virtual voidassemble (Parameter param = Parameter ());

6)系统方程的求解,使用Eigen或者UmfPack,UmfPack可以加速求解稀疏矩阵方程组:

      /** \brief Solve system of equations using Eigen or UmfPack (can be defined in on_nurbs.cmake),* and updates B-Spline surface if a solution can be obtained.*/virtual voidsolve (double damp = 1.0);

7)曲面的更新:

/** \brief Update surface according to the current system of equations.* \param[in] damp damping factor from one iteration to the other.*/virtual voidupdateSurf (double damp);

8)通过插入中间节点修正曲面:

/** \brief Refines surface by inserting a knot in the middle of each element.* \param[in] dim dimension of refinement (0,1)*/voidrefine (int dim);static voidrefine (ON_NurbsSurface &nurbs, int dim);

总结:

PCL中B样条曲面拟合的思路是,对初始化的曲面,通过在两个维度上,不断插入中间节点来修正曲面,每次求解过程通过点线距离约束或者切线距离约束,构造矩阵方程组,求解得到控制点,不断迭代修正,对于稠密点云,求解矩阵方程组的过程较慢,导致拟合速度较慢,使用UmfPack可加快求解速度。

3. 多个B样条曲面的全局优化

global_optimization_pdm.h、global_optimization_pdm.cpp

global_optimization_sdm.h、global_optimization_sdm.cpp

在单个方程组中使用点距离或切线距离最小化法,从全局的三维点云中拟合和优化多个B样条曲面.

主要函数:
设置两个B样条曲面的共同边界点

      /** \brief Set common boundary points two NURBS should lie on*  \param[in] boundary vector of boundary points.*  \param[in] nurbs_indices vector of 2 NURBS indices sharing the boundary point. */voidsetCommonBoundary (const vector_vec3d &boundary, const vector_vec2i &nurbs_indices);

其他函数与单个B样条曲面拟合基本相同。

参考
https://github.com/PointCloudLibrary/pcl/tree/master/surface

PCL-surface/on_nurbs模块分析相关推荐

  1. 斯坦福的著名小兔子模型的点云数据_传统方法的点云分割以及PCL中分割模块

    之前在微信公众号中更新了以下几个章节 1,如何学习PCL以及一些基础的知识 2,PCL中IO口以及common模块的介绍 3,  PCL中常用的两种数据结构KDtree以及Octree树的介绍 有兴趣 ...

  2. 觉SLAM的主要功能模块分析

    视觉SLAM的主要功能模块分析 一.基本概念 SLAM (simultaneous localization and mapping),也称为CML (Concurrent Mapping and L ...

  3. Asterisk cli模块分析

    最近写一些工具库,需要远程命令行调试(cli)功能,原有的一个cli模块是将接收处理的命令具体实现在cli模块中,其他模块需要修改添加自己的cli命令都需要去修改cli模块代码,觉得模块间耦合度太高, ...

  4. 2016年大数据Spark“蘑菇云”行动代码学习之AdClickedStreamingStats模块分析

    2016年大数据Spark"蘑菇云"行动代码学习之AdClickedStreamingStats模块分析     系统背景:用户使用终端设备(IPAD.手机.浏览器)等登录系统,系 ...

  5. 来自damon的zencart二次开发教程-2.2登录模块分析

    我们在制作zencart的模板时,经常会遇到需要将zencart的登陆页面与注册账户页面分离的情况(在 默认情况下,点击"Login"按钮会进入登陆页面与注册账号页面,登录zenc ...

  6. Mybatis源码日志模块分析

    看源码需要先下载源码,可以去Mybatis的github上的仓库进行下载,Mybatis 这次就先整理一下日志这一块的源码分析,这块相对来说比较简单而且这个模块是Mybatis的基础模块. 之前的文章 ...

  7. 【转】python模块分析之collections(六)

    [转]python模块分析之collections(六) collections是Python内建的一个集合模块,提供了许多有用的集合类. 系列文章 python模块分析之random(一) pyth ...

  8. 旅游类APP-Android模块分析

    2.Android模块分析 2.1系统框架 2.2Android APP启动流程 AndroidManifest.xml 2.3网络交互 2.4开发中的知识点 1.启动时使用引导页使用渐变效果: pr ...

  9. 游戏模块分析总结(4)之系统篇

    游戏模块分析总结(4)之系统篇 发布者: wuye | 发布时间: 2014-12-19 12:10| 评论数: 1 1.系统结构 几乎所有游戏都遵循同一个原则,即:玩→获得产出→能力提升→继续玩.每 ...

最新文章

  1. 汇编和python-编程语言与Python介绍
  2. 【算法】双指针算法 ( 有效回文串 II )
  3. Android杂谈--通过DDMS实现电脑与Android设备(如手机,平板)的网络连接、截图...
  4. 第十二届蓝桥杯决赛JavaC组真题——详细答案对照(全网唯一:异或变换100%数据)
  5. Java PipedInputStream close()方法与示例
  6. C#中通过代码控制IIS服务重启
  7. 2021中国新流量价值洞察报告
  8. WebKit编译小结
  9. MySQL数据类型和常用字段属性总结
  10. mysql存储过程多值_mysql存储过程之返回多个值的方法示例
  11. win10 如何卸载OfficeScan
  12. 2019-03-02 致虚极守静笃 读老子《道德经》有感
  13. GAT GAX 简介
  14. 姓名: 张轩瑞(小名happy) 性别: 男 年龄:3周岁 走失时间: 2018年7月1日下午4:30 家属电话:18735352768
  15. sybase客户端SqlDbx中文乱码问题解决
  16. windows 7 UEFI 启动模式安装,解决win7 64 setup会提示GPT分区不支持的问题
  17. ES集群可视化管理工具-Cerebro
  18. 干货分享|串流游戏软件大比拼
  19. android拓展内存卡,都取消存储卡拓展,而它却解决了安卓手机的大问题
  20. 升级Win11后Office无法验证此产品的许可证怎么办?

热门文章

  1. PDF如何插入空白页面
  2. Anaconda安装jieba、wordcloud等第三方库
  3. STAPLE目标跟踪算法 基于C++ /Opencv实现步骤以及代码详解
  4. Windows11安装安卓/Android子系统运行安卓应用程序详细教程
  5. 让你立刻爱上数学的8个算术游戏
  6. Kali Linux安装mysql-sniffer
  7. oracle11gRAC升级到oracleRAC19C
  8. Xshell使用密钥登录Linux服务器
  9. 管好加载项,提速 Office
  10. 查看微信好友是否被删除