离散点云拟合三维平面参数推导(基于最小二乘)

embedded/2024/9/22 23:16:22/

1、背景介绍

      实际中,很多人工构造物是由平面结构构造而成,如下图所示,为一典型的由多个平面组成的人工构筑物。因此,根据离散点拟合成平面,获取拟合平面方程,是点云数据处理中非常常见的数据处理操作。

2、平面拟合参数推导

      基于若离散点,估算平面方程过程如下:

3、程序设计

      基于上述理论,使用C++、PCL编写的程序,下载链接如下:https://download.csdn.net/download/qq_32867925/89381863。

3.1 已知平面方程拟合测试

      本次首先给定平面方程为x+2y+3z+4=0 (x+4y+5z+6=0)的平面,在平面上随机生成50个点,利用这50个点拟合平面方程。部分结果与代码如下:

int main()
{//a*x+b*y+c*z+d=0  平面方程形式double a, b, c, d;a = 1;b = 4;c = 5;d = 6;//随机生成50个点// 初始化随机数生成器srand(static_cast<unsigned int>(time(nullptr)));vector<pcl::PointXYZ> pts;for (int i = 0; i < 50; i++){pcl::PointXYZ pt;pt.x= static_cast<double>(rand()) / RAND_MAX;pt.y = static_cast<double>(rand()) / RAND_MAX;pt.z = (-d - a * pt.x - b * pt.y) / c;pts.push_back(pt);}NormalEigenvalueCurvature planeparam = EstimateNormalEigenvalue(pts);cout << "在平面方程为" << a << "x+" << b << "y+" << c << "z+" << d << "=0" << "平面上产生的点,经过拟合后得到的平面参数如下:" << endl;cout << "拟合参数 a b c d 分别如下:" << endl << "a=" << planeparam.normal_x << "  b=" << planeparam.normal_y << "  c=" << planeparam.normal_z << "  d=" << planeparam.d << endl;system("pause");return 0;
}

      根据拟合可知,拟合得到的平面参数,与实现给定平面方程,几乎一致,只是参数a、b、c进行了单位归一化。证明了本方法的正确性。

3.2 法向量估算

      根据推导过程可知,平面方程ax+by+cz+d=0中参数a、b、c为平面法向量。使用kdtree搜索点云近邻点,利用近邻点拟合得到局部平面,将局部平面的法向量进行可视化,可以进一步验证估算法向量是否正确。部分代码与结果如下:

将估算的参数a、b、c作为法向量,并进行可视化代码示意:

vector<NormalEigenvalueCurvature> ptsNormal = PtsEstimateNormalEigenvalue(pts, 15);//估算每个点平面方程//增加点云法向量pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);normals->width = pts.size();normals->height = 1;normals->resize(normals->width * normals->height);for (int i = 0; i < ptsNormal.size(); i++){double normal_x = ptsNormal[i].normal_x;double normal_y = ptsNormal[i].normal_y;double normal_z = ptsNormal[i].normal_z;double length = sqrt(normal_x * normal_x + normal_y * normal_y + normal_z * normal_z);normal_x = normal_x / length;normal_y = normal_y / length;normal_z = normal_z / length;normals->points[i].normal_x = normal_x;normals->points[i].normal_y = normal_y;//将法向量调整都朝向if (normal_z >= 0){normals->points[i].normal_z = normal_z;}else{normals->points[i].normal_z = -normal_z;}}

所有点法向量估算示意图

      由上图可知,位于一个面上法向量是垂直于该平面的,证明估算法向量正确。

4、小结

     介绍了基于最小二乘估算平面方程的推导过程,以及测试结果。

基于PCL、C++编写的代码链接:https://download.csdn.net/download/qq_32867925/89381863


http://www.ppmy.cn/embedded/45969.html

相关文章

从报名到领证:软考高级【网络规划设计师】报名考试全攻略

本文共计10551字&#xff0c;预计阅读35分钟。包括七个篇章&#xff1a;报名、准考证打印、备考、考试、成绩查询、证书领取及常见问题。 不想看全文的可以点击目录&#xff0c;找到自己想看的篇章进行阅读。 一、报名篇 报名条件要求&#xff1a; 1.凡遵守中华人民共和国宪…

我的app开始养活我了

大家在日常使用各类 app 时应该会发现&#xff0c;进入 app 会有个开屏广告&#xff0c;在使用 app 中&#xff0c;时不时的也会有广告被我们刷到。 这时候如果我们看完了这个广告&#xff0c;或者点击了这个广告的话&#xff0c;app商家就会获得这个广告的佣金。 这个佣金就是…

Java实现成绩管理系统

1.思路分析实现 要求一和要求二&#xff0c;一个要求使用顺序表一个使用链表&#xff0c;但又因为这两个都是List的实现类&#xff0c;所以我就使用多态的形式通过一个方法进行实现上面两种内容&#xff0c;需要用什么方法实现就传入什么实现类&#xff0c;形参是List类型。创建…

透视 static 和 extern 对函数的重大影响

目录 一、生命周期和作用域1、生命周期2、作用域 二、static 的影响1、static的作用2、static 修饰局部变量 三、extern 的魔力四、static 与 extern 的协同与冲突1、static修饰全局变量2、static修饰函数 在 C 语言的世界里&#xff0c; static 和 extern 这两个关键字在函数的…

Vue中使用Axios

安装Axios&#xff1a; 首先确保已经安装了Axios。你可以使用npm或者yarn进行安装&#xff0c;如下所示&#xff1a; pm install axios 导入Axios&#xff1a; 在需要发送HTTP请求的组件中&#xff0c;使用import语句导入Axios库。 import axios from axios; 发送HTTP请求&…

数据库 - 理解了完全依赖和部分依赖,就很容易理解第二范式

第二范式(Second Normal Form,2nd NF)是指每个表必须有主关键字(Primary key),其他数据元素与主关键字一一对应。通常称这种关系为函数依赖(Functional dependence)关系&#xff0c;即表中其他数据元素都依赖于主关键字,或称该数据元素唯一地被主关键字所标识。第二范式是数据库…

程序员搞副业得搞出影响力来

技能影响力类 工具是免费提供的&#xff0c;开发者创建这类工具可能仅仅是为了分享自己的成果。 这类工具通常开源发布在Github上&#xff0c;开发者有时会附上自己的支付宝或微信收款码&#xff0c;允许用户进行捐赠和打赏&#xff0c;采取一种随缘的赚钱方式。 通过这些工…

「布道师系列文章」众安保险王凯解析 Kafka 网络通信

作者&#xff5c;众安保险基础平台 Java 开发专家王凯 引言 今天给大家带来的是 Kafka 网路通信主要流程的解析&#xff08;基于 Apache Kafka 3.7[2]&#xff09;。同时引申分析了业界当前较火的AutoMQ基于Kafka在网络通信层面的优化和提升。 01 如何构建一个基本的请求…