三维空间离散点如何拟合平面?

news2024/9/23 1:34:33

文章目录

  • 0.引言
  • 1.算法原理
  • 2.算法实现

0.引言

  在点云建模过程中,有时需要对扫描建模的点云进行标定,在实际使用中往往以地面做为参照平面,需要将扫描的三维空间点云进行拟合平面,以便纠正扫描结果。本文对三维空间离散点拟合平面算法进行总结,并给出几种编程语言下的算法实现代码。

1.算法原理

  (1)最小二乘法
  

  (2)平面方程拟合
  在这里插入图片描述

2.算法实现

  (1)C#

using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;  
  
List<List<double>> dLL =new List<List<double>>();  
using (StreamReader sr = new StreamReader("E:\\4.txt", Encoding.UTF8))  
            {  
                string line;  
                // 从文件读取并显示行,直到文件的末尾   
                while ((line = sr.ReadLine()) != null)  
                {  
                    string[] strs = line.Split(',');  
                    List<double> dL = new List<double>();  
                    dL.Add(double.Parse(strs[0]));  
                    dL.Add(double.Parse(strs[1]));  
                    dL.Add(double.Parse(strs[2]));  
                    dLL.Add(dL);  
                }  
    }  
  
Matrix<double> A,b;  
double[,] dA=new double[dLL.Count(), 3];  
double[,] db = new double[dLL.Count(), 1];  
double[,] da = new double[3, 1];  
for (int i = 0; i < dLL.Count(); i++)  
{  
    dA[i, 0] = dLL[i][0];  
    dA[i, 1] = dLL[i][1];  
    dA[i, 2] = 1;  
    db[i,0] = dLL[i][2];  
}  
A = DenseMatrix.OfArray(dA);  
b = DenseMatrix.OfArray(db);  
Matrix<double> a = (A.Transpose() * A).Inverse() * A.Transpose() * b;  
Console.WriteLine("a0,a1,a2:"+a[0,0].ToString("f6")+","+a[1,0].ToString("f6") + ","+a[2,0].ToString("f6"));  

  (2)C++

//planePoints存储需要拟合的三维点云
vector<Eigen::Vector3d> planePoints;  
Eigen::MatrixXd A(planePoints.size(), 3);  
Eigen::VectorXd b(planePoints.size());  
//将观测点输入矩阵  
for (int i = 0; i < planePoints.size(); i++)  
{  
    A(i, 0) = planePoints[i](0);  
    A(i, 1) = planePoints[i](1);  
    A(i, 2) = 1;  
    b(i) = planePoints[i](2);  
}  
  
//使用最小二乘法求得系数向量  
Eigen::Vector3d a = (A.transpose()*A).inverse()*A.transpose()*b;  

  (3)Matlab

%文件名
fileName = "E:\\4.txt";  
points = csvread(fileName , 0, 0);  
length = size(points(:,1));  
A=[points(:,1),points(:,2),ones(length(1),1)];  
b=points(:,3);  
a=inv(A'*A)*A'*b;  

  (4)Java

//s为点文件数据字符串
String[] strs =  s.toString().split("\n");  
double dA[][] = new double[strs.length][3];  
double db[][] = new double[strs.length][1];  
double da[][] = new double[3][1];  
for(int i = 0;i <strs.length;i++){  
    if(strs[i].equals(""))continue;  
    String[] strs2 = strs[i].split(",");  
    dA[i][0]=Double.parseDouble(strs2[0]);  
    dA[i][1]=Double.parseDouble(strs2[1]);  
    dA[i][2] = 1;  
    db[i][0]=Double.parseDouble(strs2[2]);  
}  
//multiply、inverse、transpose分别为矩阵乘法、求逆、转置  
da = multiply(multiply(inverse(multiply(transpose(dA),dA)),transpose(dA)),db);  

  (5)VBA

Imports MathNet.Numerics.LinearAlgebra
Imports MathNet.Numerics.LinearAlgebra.Double  
  
Dim arr() As String, i As Long  
        arr = Split(CreateObject("scripting.filesystemobject").opentextfile("E:\\4.txt").readall.ToString(), vbLf)  
        Dim dA(UBound(arr), 2) As Double, db(UBound(arr), 0) As Double  
        Dim str() As String  
        For i = 0 To UBound(arr)  
            'ReDim Preserve Txt(i)  
            If arr(i) = "" Then  
                Continue For  
            End If  
            str = Split(arr(i), ",")  
            dA(i, 0) = Convert.ToDouble(str(0))  
            dA(i, 1) = Convert.ToDouble(str(1))  
            dA(i, 2) = 1  
            db(i, 0) = Convert.ToDouble(str(2))  
        Next  
        Dim A, b, ma As Matrix  
        A = DenseMatrix.OfArray(dA)  
        b = DenseMatrix.OfArray(db)  
        ma = (A.Transpose() * A).Inverse() * A.Transpose() * b  
        Console.WriteLine("a0,a1,a2:" + ma(0, 0).ToString("f6") + "," + ma(1, 0).ToString("f6") + "," + ma(2, 0).ToString("f6"))

  (6)Python

from numpy import *;
  
f=open('E:\\4.txt', encoding='gbk')  
txt=[]  
strs = []  
A = []  
b = []  
a = []  
for line in f:  
    strs=line.strip().split(',')  
    A.append([float(strs[0]),float(strs[1]),1])  
    b.append([float(strs[2])])  
A = mat(A)  
b = mat(b)  
a = (A.T*A).I*A.T*b  
print(a)

参考资料:
[1] HIIWAR_ZB. 最小二乘法——拟合平面方程(深度相机外参标定、地面标定); 2020-06-23 [accessed 2023-06-25].
[2]哈哈kls . 最小二乘法拟合平面; 2018-09-10 [accessed 2023-06-25].
[3] 脱掉外衣看本质. 三维空间离散点 平面拟合算法 C++实现; 2019-03-07 [accessed 2023-06-25].

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

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

相关文章

学习Vue3——watch(侦听器)

基本用法 watch有三个参数 第一个参数是监听源 第二个参数回调函数cb&#xff08;newVal,oldVal&#xff09; 第三个参数一个options配置项 监听单个属性 <template><div>姓:<input v-model"lastName" type"text" /></div><…

PostgreSQL 自增主键冲突问题分析及解决办法

创建一个test表 create table test (id integer default nextval(test_id_seq::regclass) not nullconstraint test_pkprimary key,c1 integer );插入数据 insert into test (c1) values (1); insert into test (c1) values (2); insert into test (c1) values (3);发现自增I…

自定义指令实现按钮加密

1. 需求描述 给按钮加一个密码保护&#xff0c;输入的密码正确之后才能进行下一步操作。 2. 实现思路 1. 直接在点击事件里面处理密码校验&#xff0c; <!-- template --> <el-button type"warning" click"handlePub">发布</el-button&…

Unity Android打包成Apk之后 紫屏 无内容

打包成Apk之后 打开游戏 过完logo是紫色的屏幕什么都没有 解决方法&#xff1a; 打开项目的目录&#xff1a; 删除除了 .vscode assets package 之外的所有文件夹 然后重新打开就可以了

【owt】发送侧接收并处理rtcp包 调用堆栈

发送测接收rtcp包并处理大神分析的RTCPReceiver处理的rtcp包 WebRTC源码之RTCPReceiver源码分析 可以看到xr是207MediaStream::read 中 通过 fb_sink_->deliverFeedback(std::move(packet)); 分发rtcp fbsink是 VideoFramePacketizer int VideoFramePacketizer::deliverFee…

HTML入门基础知识

一、简介 什么是HTML&#xff1f; HTML是用来描述网页的一种语言。它指的是超文本标记语言&#xff0c;是一种标记语言&#xff0c;是一套标记。标签HTML使用标记标签来描述网页 HTML基本结构如图&#xff1a; 二、基础内容 HTML的基本标签 HTML 标签 HTML 标记标签通常被称为…

Linux 的逻辑世界与 Windows 的复杂性

Linux的逻辑世界与Windows的复杂性 作为操作系统&#xff0c;Linux 和 Windows 都在全球用户心中赢得了一席之地。 这两种系统都很常用&#xff0c;每种都有不同的原因和目的。 作为一名有用的 AI 助手&#xff0c;我有机会广泛使用 Linux 和 Windows&#xff0c;并且我想探索…

rewrite实验示例

一、基于域名跳转 要求用户输入旧域名可以直接跳转到新域名 vim /usr/local/nginx/conf/nginx.conf systemctl restart nginx.service 查看元素可以看到返回301&#xff0c;实现了永久重定向跳转&#xff0c;而且域名后的参数也正常跳转 二、基于客户端 IP 访问跳转 要求除…

ncnn vulkan 以类的方式推理示例

ncnn vulkan 以类的方式推理示例 flyfish 环境 ncnn-android-vulkan.zip 20230517 opencv 4.6.0 开发环境Qt 6.2.4 模型 yolov5_62 构建套件 Clang arm64-v8a ndk 25 和api 28版本如下 头文件 #ifndef YOLOV5GPU_H #define YOLOV5GPU_H#include <string> #include &l…

C#调用Matlab--解决外部引用包问题(全网唯一)

1、好久没写文章了&#xff0c;今天给大家带来的是C#调用matlab程序的解决方案。 2、应用场景&#xff1a;C#调用matlab网上已经有很多文章了&#xff0c;但本文主要解决的是无法调用时的问题。 如当Matlab调用外部包&#xff08;CVX、IPOPT、gurobi、yalmip等优化求解器&…

STM32--DHT11温湿度传感器

本文介绍基于STM32F103实现的DHT11温湿度传感器数据采集及显示&#xff0c;完整代码见文末链接 一、DHT11传感器简介 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术&#xff0c;确保产品具有极高的可…

LabVIEW轿厢电梯控制系统

LabVIEW轿厢电梯控制系统 随着国民经济的快速发展&#xff0c;私家车不再是奢侈的商品&#xff0c;逐渐属于大众。大城市中越来越多的汽车对交通和环境造成了灾难性的影响&#xff0c;尤其是市中心遭受了损失。市中心拥堵和停车困难是两大交通问题。增加停车位以留出更多车辆是…

一个vue3注册表单,自定义element-ui的label样式

<template><div class"form"><div class"backLogin"><div class"text">已有账号&#xff1f;</div><el-button click"toLogin" typeprimary>立即登录</el-button></div><div clas…

elment-ui的Cascader 级联选择器,点击lable 也能选中前面的复选框

直接mounted里加就OK啦 mounted() {// Cascader 级联选择器: 点击文本就让它自动点击前面的input就可以触发选择。setInterval(function() {document.querySelectorAll(.el-cascader-node__label).forEach(el > {el.onclick function() {if (this.previousElementSibl…

解码奇思妙想:揭秘力扣解压缩编码列表的独特解题之道

本篇博客会讲解力扣“1313. 解压缩编码列表”的解题思路&#xff0c;这是题目链接。 题目要返回一个数组&#xff0c;这个数组是多大呢&#xff1f;由于下标是偶数的元素决定了每个数据要写入几次&#xff0c;所以要对这些项求和&#xff0c;就知道答案数组要开多大了。 接着&…

从零开始理解Linux中断架构(13)--Linux中断域

由于计算机系统日益复杂,外设中断数量不断增加,系统可能同时需要多个中断控制器进行级联,中断源需要统一管理,面对这样的状况,Linux对各种中断控制器进行抽象,对如何进行硬件中断号到IRQ number映射关系上进行进一步抽象出通用与设备无关的架构,通用中断处理代码中就有了…

SpringBoot整合FastDFS笔记

SpringBoot整合FastDFS笔记 FastDFS是国人余庆开发的一个的分布式存储系统&#xff0c;github地址是https://github.com/happyfish100/fastdfsFastDFS的特性:1、分组存储&#xff0c;灵活简洁、对等结构&#xff0c;不存在单点2、 文件ID由FastDFS生成&#xff0c;作为文件访问…

CSDN 周赛 60 期

CSDN 周赛 60 期 60期体验判断题单选题填空题编程题1、题目名称:贝博士的论文审阅统计2、题目名称:括号匹配小结60期体验 本次体验极差,编程题第一题完全看不懂。 然后就是,成绩极差,选择、判断、填空题一共40分,仅仅拿到了十分。 嗯。。。。请允许我先唱两句“都选C”…

[SWPUCTF 2021 新生赛] jicao

需要将json的值进行get传参&#xff0c;以及将id的值进行post传参 因此可以构造payload get传参&#xff1a;?json{"x":"wllm"} post传参&#xff1a;idwllmNB

Z世代消费者崛起,品牌如何靠吉祥物IP增强商业变现能力?

Z世代人群逐渐成为消费者最大主力军&#xff0c;对品牌而言&#xff0c;抓住Z世代消费者的心&#xff0c;就等于抓住机遇。Z世代的年轻人更趋向于为“兴趣”买单&#xff0c;将商品的使用价值与情感价值逐渐分离&#xff0c;拥抱更多的文化&#xff0c;崇尚个性潮流、喜欢新鲜事…