【点云surface】 修剪B样条曲线拟合

1 介绍

Fitting trimmed B-splines(修剪B样条曲线拟合)是一种用于对给定的点云数据进行曲线拟合的算法。该算法使用B样条曲线模型来逼近给定的点云数据,并通过对模型进行修剪来提高拟合的精度和准确性。

B样条曲线是一种常用的曲线表示方法,它通过一组控制点和节点向量来定义曲线的形状。B样条曲线具有局部控制性和平滑性,因此在曲线拟合问题中被广泛应用。

修剪B样条曲线拟合算法的基本步骤如下:

  1. 初始化:定义一个B样条曲线模型,并设置模型的阶数、节点向量和控制点。

  2. 迭代优化:通过迭代优化的方法,不断调整模型的控制点,使得模型更好地逼近给定的点云数据。在每次迭代中,根据给定的拟合参数和优化目标函数,计算出新的控制点位置。

  3. 修剪:根据给定的修剪参数,对拟合的B样条曲线进行修剪。修剪可以通过删除不需要的曲线段或调整曲线段的权重来实现。修剪的目的是提高拟合的准确性和精度。

  4. 终止条件:根据设定的终止条件,判断是否终止迭代优化过程。终止条件可以是达到最大迭代次数、拟合精度满足要求或其他自定义条件。

  5. 输出结果:输出最终的修剪B样条曲线拟合结果。结果可以是修剪后的B样条曲线模型,也可以是曲线的控制点和节点向量等表示。

2 效果

3 说明

在进行B样条曲面拟合时,通常需要先对曲面进行拟合,然后再对曲面上的曲线进行拟合。这是因为曲面上的曲线通常是曲面的边界或者用于修剪曲面的曲线,它们与曲面的形状紧密相关,因此需要单独进行拟合和调整。

首先,进行B样条曲面拟合时,目标是通过一组控制点和节点向量来逼近给定的点云数据,以生成一个平滑的曲面模型。这个曲面模型可以用来表示曲面的整体形状。

然后,在曲面拟合的基础上,进行B样条曲线拟合。曲线拟合通常是对曲面的边界曲线或者修剪曲线进行拟合。这些曲线与曲面的形状紧密相关,因此需要单独进行拟合和调整。通过对曲线进行拟合,可以更好地捕捉曲面的边界形状或者修剪曲线的形状,从而提高拟合的精度和准确性。

总结起来,进行B样条曲面拟合后,还需要对曲面上的曲线进行拟合的原因是曲线与曲面的形状紧密相关,需要单独进行拟合和调整以提高拟合的精度和准确性。通过分别拟合曲面和曲线,可以更好地捕捉曲面的整体形状和边界形状,从而得到更好的拟合结果。

曲面拟合时的参数

  • order:曲面的阶数。该参数定义了B样条曲面的阶数,即每个控制点的影响范围。较高的阶数可以提供更大的自由度,但也会增加计算时间和内存消耗。

  • refinement:细化次数。该参数定义了在拟合过程中进行的细化次数。通过细化,可以在拟合过程中增加新的控制点,以提高拟合的精度和准确性。

  • iterations:迭代次数。该参数定义了拟合过程中的迭代次数。增加迭代次数可以提高拟合的精度,但也会增加计算时间和内存消耗。

  • mesh_resolution:网格分辨率。该参数定义了生成曲面网格的分辨率。较高的分辨率会导致更细致的曲面表示,但也会增加计算时间和内存消耗。

  • params.interior_smoothness:内部平滑度。该参数用于调整曲面内部的平滑度。较大的值会使曲面更平滑。

  • params.interior_weight:内部权重。该参数用于调整曲面内部点对拟合结果的权重。较大的权重会使内部点对拟合结果的影响更大。

  • params.boundary_smoothness:边界平滑度。该参数用于调整曲面边界的平滑度。较大的值会使曲面边界更平滑。

  • params.boundary_weight:边界权重。该参数用于调整曲面边界点对拟合结果的权重。较大的权重会使边界点对拟合结果的影响更大。

曲线拟合的参数

  • curve_params.addCPsAccuracy:添加控制点的精度。控制点是用于定义B样条曲线形状的关键点。该参数指定了在拟合过程中添加新的控制点的精度。较小的值会导致更精确的拟合结果,但可能会增加计算时间和内存消耗。

  • curve_params.addCPsIteration:添加控制点的迭代次数。在拟合过程中,可以通过迭代的方式不断添加新的控制点来改进拟合结果。该参数指定了添加控制点的迭代次数。增加迭代次数可以提高拟合的精度,但也会增加计算时间和内存消耗。

  • curve_params.maxCPs:最大控制点数。该参数限制了拟合过程中允许的最大控制点数。超过这个数目的控制点将被丢弃。通过调整这个参数,可以控制拟合结果的复杂度和平滑度。

  • curve_params.accuracy:拟合的精度。该参数指定了拟合结果与原始数据之间的误差阈值。较小的值会导致更精确的拟合结果,但可能会增加计算时间和内存消耗。

  • curve_params.iterations:迭代次数。该参数指定了拟合过程中的迭代次数。增加迭代次数可以提高拟合的精度,但也会增加计算时间和内存消耗。

  • curve_params.param.closest_point_resolution:最近点的分辨率。该参数用于计算曲线上最近点的分辨率。较小的值会导致更精确的最近点计算,但可能会增加计算时间和内存消耗。

  • curve_params.param.closest_point_weight:最近点的权重。该参数用于计算曲线上最近点的权重。较大的权重会使最近点对拟合结果的影响更大。

  • curve_params.param.closest_point_sigma2:最近点的方差。该参数用于计算曲线上最近点的方差。较小的方差会使最近点对拟合结果的影响更大。

  • curve_params.param.interior_sigma2:内部点的方差。该参数用于计算曲线上内部点的方差。较小的方差会使内部点对拟合结果的影响更大。

  • curve_params.param.smooth_concavity:平滑凹度。该参数用于调整曲线的平滑凹度。较大的值会使曲线更平滑。

  • curve_params.param.smoothness:平滑度。该参数用于调整曲线的平滑度。较大的值会使曲线更平滑。

4 代码

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/surface/on_nurbs/fitting_surface_tdm.h>
#include <pcl/surface/on_nurbs/fitting_curve_2d_asdm.h>
#include <pcl/surface/on_nurbs/triangulation.h>typedef pcl::PointXYZ Point;
std::ostringstream os;// 将点云数据中的有效点(即非NaN值)提取出来,并以Eigen::Vector3d类型的形式保存起来
void PointCloud2Vector3d(pcl::PointCloud<Point>::Ptr cloud, pcl::on_nurbs::vector_vec3d & data)
{for (unsigned i = 0; i< cloud->size(); i++){Point &p = cloud->at(i);if(!std::isnan(p.x) && !std::isnan(p.z) && !std::isnan(p.z))data.push_back(Eigen::Vector3d(p.x, p.y, p.z));}
}// 将ON_NurbsCurve和ON_NurbsSurface的曲线和控制点可视化显示在PCLVisualizer中,方便用户观察和分析曲线的形状和控制点的位置。
void visualizeCurve (ON_NurbsCurve &curve,ON_NurbsSurface &surface,pcl::visualization::PCLVisualizer &viewer)
{// 将曲线转换为点云数据pcl::PointCloud<pcl::PointXYZRGB>::Ptr curve_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);pcl::on_nurbs::Triangulation::convertCurve2PointCloud (curve, surface, curve_cloud, 4);//该函数会将曲线上的点均匀地采样,并将采样点作为点云数据的点。// 可视化for(std::size_t i=0; i< curve_cloud->size() - 1; i++){pcl::PointXYZRGB &p1 = curve_cloud->at(i);pcl::PointXYZRGB &p2 = curve_cloud->at(i+1);os << "line" << i;viewer.removeShape(os.str());viewer.addLine<pcl::PointXYZRGB>(p1, p2, 1.0, 0.0, 0.0, os.str());}//pcl::PointCloud<pcl::PointXYZRGB>::Ptr curve_cps (new pcl::PointCloud<pcl::PointXYZRGB>);for(int i=0; i< curve.CVCount(); i++){ON_3dPoint p1;curve.GetCV(i, p1); // 曲线的一个控制点double pnt[3];surface.Evaluate(p1.x ,p1.y, 0, 3, pnt); // 加usn曲面上对应的点的坐标pcl::PointXYZRGB p2;p2.x = float (pnt[0]);p2.y = float (pnt[1]);p2.z = float (pnt[2]);p2.r = 255;p2.g = 0;p2.b = 0;curve_cps->push_back (p2);}viewer.removePointCloud ("cloud_cps");viewer.addPointCloud (curve_cps, "cloud_cps");
}int main()
{pcl::visualization::PCLVisualizer viewer("B-spline surface fitting");viewer.setSize(800, 600);pcl::PCLPointCloud2 cloud2;pcl::PointCloud<Point>::Ptr cloud(new pcl::PointCloud<Point>);if(pcl::io::loadPCDFile("/home/lrj/work/pointCloudData/bun0.pcd", cloud2) == -1)throw std::runtime_error("    PCD file not found.");pcl::fromPCLPointCloud2(cloud2, *cloud);pcl::on_nurbs::NurbsDataSurface data;PointCloud2Vector3d(cloud, data.interior);pcl::visualization::PointCloudColorHandlerCustom<Point> handler(cloud, 0, 255, 0);viewer.addPointCloud<Point>(cloud, handler, "cloud_cylinder");std::printf("     %lu points in data set\n", cloud->size());// ############################################################################// fit B-spline surface/** 整个过程的目的是通过ON-Nurbs算法对给定的点云数据进行曲面拟合,并将拟合结果以三角网格的形式可视化显示出来。* 通过多次细化和迭代,逐步优化曲面拟合结果,使其更加接近原始点云数据。*/// parametersunsigned order(3); // 曲面的阶数unsigned refinement(5); // 细化次数unsigned iterations(10); // 迭代次数unsigned mesh_resolution(256); // 网格分辨率pcl::on_nurbs::FittingSurface::Parameter params;params.interior_smoothness = 0.2; // 内部平滑度params.interior_weight = 1.0; // 内部权重params.boundary_smoothness = 0.2; // 边界平滑度params.boundary_weight = 0.0; // 边界权重// 生成初始的曲面拟合结果printf("   surface fitting ...\n");ON_NurbsSurface nurbs = pcl::on_nurbs::FittingSurface::initNurbsPCABoundingBox(order, &data);pcl::on_nurbs::FittingSurface fit(&data, nurbs);//  fit.setQuiet (false); // enable/disable debug output// 将拟合结果转为三角网格,并将其添加到可视化窗口进行现实pcl::PolygonMesh mesh;pcl::PointCloud<pcl::PointXYZ>::Ptr mesh_cloud(new pcl::PointCloud<pcl::PointXYZ>);std::vector<pcl::Vertices> mesh_vertices;std::string mesh_id = "mesh_nurbs";pcl::on_nurbs::Triangulation::convertSurface2PolygonMesh(fit.m_nurbs, mesh, mesh_resolution);viewer.addPolygonMesh(mesh, mesh_id);// 进行多次曲面细化和求解for (unsigned i=0; i< refinement; i++){fit.refine(0);fit.refine(1);fit.assemble(params);fit.solve();pcl::on_nurbs::Triangulation::convertSurface2Vertices (fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution); // 将曲面转为顶点数据viewer.updatePolygonMesh<pcl::PointXYZ> (mesh_cloud, mesh_vertices, mesh_id); // 视窗刷新,以便观察到曲面拟合的过程viewer.spinOnce ();}// 进行一定次数的曲面拟合迭代for (unsigned i = 0; i < iterations; i++){fit.assemble (params);fit.solve ();pcl::on_nurbs::Triangulation::convertSurface2Vertices (fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution);viewer.updatePolygonMesh<pcl::PointXYZ> (mesh_cloud, mesh_vertices, mesh_id);viewer.spinOnce();}// ############################################################################// fit B-spline curve/** 整个曲线拟合的过程的目的是使用ON-Nurbs算法对给定的点云数据进行曲线拟合,并将拟合结果可视化显示出来。* 通过调整拟合参数,可以控制拟合的精度和平滑度,以得到最优的拟合结果。*/// parameterspcl::on_nurbs::FittingCurve2dAPDM::FitParameter curve_params;curve_params.addCPsAccuracy = 5e-2; // 添加控制点的精度curve_params.addCPsIteration = 3; // 添加控制点的迭代次数curve_params.maxCPs = 200; // 最大控制点数curve_params.accuracy = 1e-3; // 拟合的精度curve_params.iterations = 100; // 迭代次数curve_params.param.closest_point_resolution = 0; // 最近点的分辨率curve_params.param.closest_point_weight = 1.0; // 最近点的权重curve_params.param.closest_point_sigma2 = 0.1; // 最近点的方差curve_params.param.interior_sigma2 = 0.00001; // 内部点的方差curve_params.param.smooth_concavity = 1.0; // 平滑凹度curve_params.param.smoothness = 1.0; // 平滑度// initialisation (circular)printf ("  curve fitting ...\n");pcl::on_nurbs::NurbsDataCurve2d curve_data;curve_data.interior = data.interior_param;curve_data.interior_weight_function.push_back (true);ON_NurbsCurve curve_nurbs = pcl::on_nurbs::FittingCurve2dAPDM::initNurbsCurve2D (order, curve_data.interior);// curve fittingpcl::on_nurbs::FittingCurve2dASDM curve_fit (&curve_data, curve_nurbs);// curve_fit.setQuiet (false); // enable/disable debug outputcurve_fit.fitting (curve_params);visualizeCurve (curve_fit.m_nurbs, fit.m_nurbs, viewer);// ############################################################################// triangulation of trimmed surfaceprintf ("  triangulate trimmed surface ...\n");viewer.removePolygonMesh (mesh_id);pcl::on_nurbs::Triangulation::convertTrimmedSurface2PolygonMesh (fit.m_nurbs, curve_fit.m_nurbs, mesh,mesh_resolution); // 将拟合的曲面、曲线转为三角网格viewer.addPolygonMesh (mesh, mesh_id);// save trimmed B-spline surfaceif ( fit.m_nurbs.IsValid() ){ONX_Model model;ONX_Model_Object& surf = model.m_object_table.AppendNew();surf.m_object = new ON_NurbsSurface(fit.m_nurbs);surf.m_bDeleteObject = true;surf.m_attributes.m_layer_index = 1;surf.m_attributes.m_name = "surface";ONX_Model_Object& curv = model.m_object_table.AppendNew();curv.m_object = new ON_NurbsCurve(curve_fit.m_nurbs);curv.m_bDeleteObject = true;curv.m_attributes.m_layer_index = 2;curv.m_attributes.m_name = "trimming curve";//        model.Write(file_3dm.c_str());
//        printf("  model saved: %s\n", file_3dm.c_str());}printf ("  ... done.\n");viewer.spin();return 0;
}

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

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

相关文章

基于C#实现并查集

一、场景 有时候我们会遇到这样的场景&#xff0c;比如:M{1,4,6,8},N{2,4,5,7}&#xff0c;我的需求就是判断{1,2}是否属于同一个集合&#xff0c;当然实现方法有很多&#xff0c;一般情况下&#xff0c;普通青年会做出 O(MN)的复杂度&#xff0c;那么有没有更轻量级的复杂度呢…

unordered_map 与 unordered_set 的模拟实现

unordered_map 与 unordred_set 的模拟实现与 map 与 set 的模拟实现差不多。map 与 set 的模拟实现中&#xff0c;底层的数据结构是红黑树。unordered_map 与 unordered_set 的底层数据结构是哈希表。因此&#xff0c;在模拟实现 unordered_map 与 unordred_set 之前你必须确保…

开源语音大语言模型来了!阿里基于Qwen-Chat提出Qwen-Audio!

论文链接&#xff1a;https://arxiv.org/pdf/2311.07919.pdf 开源代码&#xff1a;https://github.com/QwenLM/Qwen-Audio 引言 大型语言模型&#xff08;LLMs&#xff09;由于其良好的知识保留能力、复杂的推理和解决问题能力&#xff0c;在通用人工智能&#xff08;AGI&am…

基于51单片机超声波测距汽车避障系统

**单片机设计介绍&#xff0c; 基于51单片机超声波测距汽车避障系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于51单片机的超声波测距汽车避障系统是一种用于帮助汽车避免碰撞和发生事故的设备&#xff0c;以下是一个基本…

Nginx安装与配置、使用Nginx负载均衡及动静分离、后台服务部署、环境准备、系统拓扑图

目录 1. 系统拓扑图 2. 环境准备 3. 服务器安装 3.1 mysql&#xff0c;tomcat 3.2 Nginx的安装 4. 部署 4.1 后台服务部署 4.2 Nginx配置负载均衡及静态资源部署 1. 系统拓扑图 说明&#xff1a; 用户请求达到Nginx若请求资源为静态资源&#xff0c;则将请求转发至静态…

轻量级web开发框架:Flask本地部署及实现公网访问界面

轻量级web开发框架&#xff1a;Flask本地部署及实现公网访问界面 文章目录 轻量级web开发框架&#xff1a;Flask本地部署及实现公网访问界面前言1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 前言 本篇文章讲解如何…

指针运算详解

1.引入 指针的基本运算有三种&#xff0c;分别是&#xff1a; • 指针- 整数 • 指针-指针 • 指针的关系运算 2.指针- 整数 因为数组在内存中是连续存放的&#xff0c;只要知道第⼀个元素的地址&#xff0c;顺藤摸⽠就能找到后⾯的所有元素。 int arr[10] {1,2,3,4,5,…

Node.js入门指南(三)

目录 Node.js 模块化 介绍 模块暴露数据 导入模块 导入模块的基本流程 CommonJS 规范 包管理工具 介绍 npm cnpm yarn nvm的使用 我们上一篇文章介绍了Node.js中的http模块&#xff0c;这篇文章主要介绍Node.js的模块化&#xff0c;包管理工具以及nvm的使用。 Node…

JVM 内存分析工具 MAT及实践

线程分析工具 MAT 官网下载地址&#xff1a;http://www.eclipse.org/mat/downloads.php mat百度网盘链接&#xff1a;&#xff08;速度更快&#xff09; 链接&#xff1a;https://pan.baidu.com/s/1tMp8MQIXuPtg9zBgruO0Ug?pwdjqtv 提取码&#xff1a;jqtv jdk17 百度网盘链接…

ElasticSearch查询语法及深度分页问题

一、ES高级查询Query DSL ES中提供了一种强大的检索数据方式,这种检索方式称之为Query DSL&#xff08;Domain Specified Language 领域专用语言&#xff09; , Query DSL是利用Rest API传递JSON格式的请求体(RequestBody)数据与ES进行交互&#xff0c;这种方式的丰富查询语法…

Unity 讯飞 之 讯飞星火大模型的简单封装和使用(补充讯飞大模型识图功能)

Unity 讯飞 之 讯飞星火大模型的简单封装和使用&#xff08;补充讯飞大模型识图功能&#xff09; 目录 Unity 讯飞 之 讯飞星火大模型的简单封装和使用&#xff08;补充讯飞大模型识图功能&#xff09; 一、简单介绍 二、实现原理 三、注意事项 四、效果预览 五、案例简单…

php通过curl方式发送接受xml数据

目录 1、php通过curl方式发送xml数据 2、php通过file_get_contents接受curl方式发送xml数据 1、php通过curl方式发送xml数据 <?php function sendXmlData($url, $xmlData) {$ch curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFE…