最小二乘拟合平面——拉格朗日乘子法

目录

  • 一、算法原理
  • 二、代码实现
    • 1、python
    • 2、matlab
  • 三、算法效果

一、算法原理

  设拟合出的平面方程为:
a x + b y + c z + d = 0 (1) ax+by+cz+d=0\tag{1} ax+by+cz+d=0(1)
约束条件为: a 2 + b 2 + c 2 = 1 (2) a^2+b^2+c^2=1\tag{2} a2+b2+c2=1(2)
  可以得到平面参数 a 、 b 、 c 、 d a、b、c、d abcd。此时,要使获得的拟合平面是最佳的,就是使点到该平面的距离的平方和最小,即满足:
e = ∑ i = 1 n d i 2 → m i n (3) e=\sum_{i=1}^nd_i^2\rightarrow min\tag{3} e=i=1ndi2min(3)
  式中, d i = ∣ a x i + b y i + c z i + d ∣ d_i=|ax_i+by_i+cz_i+d| di=axi+byi+czi+d,是点云数据中的任一点 p i ( x i , y i , z i ) p_i(x_i,y_i,z_i) pi(xi,yi,zi)到这个平面的距离。要使 e → m i n e\rightarrow min emin,可以利用拉格朗日乘子法求解极值,得到函数:
f = e − λ ( a 2 + b 2 + c 2 − 1 ) = ∑ i = 1 n d i 2 − λ ( a 2 + b 2 + c 2 − 1 ) (4) f = e - λ(a^2 + b^2 + c^2 - 1) =\sum_{i=1}^nd_i^2 - λ(a^2 + b^2 + c^2 - 1) \tag{4} f=eλ(a2+b2+c21)=i=1ndi2λ(a2+b2+c21)(4)

  先将式(2-4)两边对 d d d求偏导,并且令偏导数为零,得到:
d = 1 n ( a ∑ i = 1 n x i 2 + b ∑ i = 1 n y i 2 + c ∑ i = 1 n z i 2 ) (5) d=\frac{1}{n}(a\sum_{i=1}^nx_i^2+b\sum_{i=1}^ny_i^2+c\sum_{i=1}^nz_i^2)\tag{5} d=n1(ai=1nxi2+bi=1nyi2+ci=1nzi2)(5)
x ˉ = ∑ i = 1 n x i n \bar{x}=\sum_{i=1}^n\frac{x_i}{n} xˉ=i=1nnxi y ˉ = ∑ i = 1 n y i n \bar{y}=\sum_{i=1}^n\frac{y_i}{n} yˉ=i=1nnyi z ˉ = ∑ i = 1 n z i n \bar{z}=\sum_{i=1}^n\frac{z_i}{n} zˉ=i=1nnzi,质心为 P ˉ = ( x ˉ , y ˉ , z ˉ ) \bar{P}=(\bar{x},\bar{y},\bar{z}) Pˉ=(xˉ,yˉ,zˉ) Δ x i = x i − x ˉ \Delta x_i=x_i-\bar{x} Δxi=xixˉ Δ y i = y i − y ˉ \Delta y_i=y_i-\bar{y} Δyi=yiyˉ Δ z i = z i − z ˉ \Delta z_i=z_i-\bar{z} Δzi=zizˉ则:
d i = ∣ a Δ x i + b Δ y i + c Δ z i ∣ (6) d_i=|a\Delta x_i+b\Delta y_i+c\Delta z_i|\tag{6} di=aΔxi+bΔyi+cΔzi(6)
  再对式(2-4)两边求对 a 、 b 、 c a 、b 、c abc 的偏导数,得
{ 2 ∑ i = 1 n ( a Δ x i + b Δ y i + c Δ z i ) Δ x i − 2 λ a = 0 2 ∑ i = 1 n ( a Δ x i + b Δ y i + c Δ z i ) Δ y i − 2 λ b = 0 2 ∑ i = 1 n ( a Δ x i + b Δ y i + c Δ z i ) Δ z i − 2 λ c = 0 \begin{cases} 2\sum_{i=1}^n(a\Delta x_i+b\Delta y_i+c\Delta z_i)\Delta x_i-2λa=0\\ 2\sum_{i=1}^n(a\Delta x_i+b\Delta y_i+c\Delta z_i)\Delta y_i-2λb=0\\ 2\sum_{i=1}^n(a\Delta x_i+b\Delta y_i+c\Delta z_i)\Delta z_i-2λc=0 \end{cases} 2i=1n(aΔxi+bΔyi+cΔzi)Δxi2λa=02i=1n(aΔxi+bΔyi+cΔzi)Δyi2λb=02i=1n(aΔxi+bΔyi+cΔzi)Δzi2λc=0

  将上述方程组构成特征值方程:
A x = λ x (7) Ax = λx \tag{7} Ax=λx(7)
式中,
A = [ ∑ i = 1 n Δ x i 2 ∑ i = 1 n Δ x i Δ y i ∑ i = 1 n Δ x i Δ z i ∑ i = 1 n Δ x i Δ y i ∑ i = 1 n Δ y i 2 ∑ i = 1 n Δ y i Δ z i ∑ i = 1 n Δ x i Δ z i ∑ i = 1 n Δ y i Δ z i ∑ i = 1 n Δ z i 2 ] A= \left[ \begin{matrix} \sum_{i=1}^n\Delta x_{i}^{2}&\sum_{i=1}^n\Delta x_{i}\Delta y_{i}&\sum_{i=1}^n\Delta x_{i}\Delta z_{i} \\ \sum_{i=1}^n\Delta x_{i}\Delta y_{i}&\sum_{i=1}^n\Delta y_{i}^{2}&\sum_{i=1}^n\Delta y_{i}\Delta z_{i} \\ \sum_{i=1}^n\Delta x_{i}\Delta z_{i} &\sum_{i=1}^n\Delta y_{i}\Delta z_{i} &\sum_{i=1}^n\Delta z_{i}^{2}\\ \end{matrix} \right] A= i=1nΔxi2i=1nΔxiΔyii=1nΔxiΔzii=1nΔxiΔyii=1nΔyi2i=1nΔyiΔzii=1nΔxiΔzii=1nΔyiΔzii=1nΔzi2
x = [ a b c ] x= \left[ \begin{matrix} a\\ b\\ c\\ \end{matrix} \right] x= abc
  那么,求解平面参数 a 、 b 、 c a 、b 、c abc ,就是求解矩阵的特征值和特征向量。又因为 A A A 是3 阶实对称矩阵,其特征值求解公式为:
λ = ( A x ) T x x T x , x ≠ 0 (8) λ=\frac{(Ax)^Tx}{x^Tx},x\neq0\tag{8} λ=xTx(Ax)Tx,x=0(8)
  在约束条件 a 2 + b 2 + c 2 = 1 a^2 + b^2 + c^2 = 1 a2+b2+c2=1 下,得 λ = ∑ i = 1 n ( a Δ x i + b Δ y i + c Δ z i ) 2 = ∑ i = 1 n d i 2 = e λ=\sum_{i=1}^n(a\Delta x_i+b\Delta y_i+c\Delta z_i)^2=\sum_{i=1}^nd_i^2=e λ=i=1n(aΔxi+bΔyi+cΔzi)2=i=1ndi2=e。 所以, e e e最小值就是矩阵 A A A的最小特征值,对应特征向量为平面参数 a 、 b 、 c a 、b 、c abc ,利用质心可求得 d d d

二、代码实现

1、python

import numpy as np# 创建函数,用于生成不同属于一个平面的100个离散点
def not_all_in_plane(a, b, c):x = np.random.uniform(-10, 10, size=100)y = np.random.uniform(-10, 10, size=100)z = (a * x + b * y + c) + np.random.normal(-1, 1, size=100)return x, y, z# 调用函数,生成离散点
x, y, z = not_all_in_plane(2, 5, 6)
# 计算质心
x0 = np.mean(x)
y0 = np.mean(y)
z0 = np.mean(z)
# 去质心
x = x - x0
y = y - y0
z = z - z0
# ------------------------构建系数矩阵-----------------------------
A = np.array([[sum(x * x), sum(x * y), sum(x * z)],[sum(x * y), sum(y * y), sum(y * z)],[sum(x * z), sum(y * z), sum(z * z)]])
[D, X] = np.linalg.eig(A)print('平面拟合结果为:z = %.3f * x + %.3f * y + %.3f' % (X[0, 2], X[1, 2], X[2, 2]))

2、matlab

clc;clear;
%% -------------------------------读取点云---------------------------------
pc = ReadPointCloud('plane1.pcd');
%% -----------------------------获取点云信息-------------------------------
n ; % 点的个数
x ; % 点的x坐标
y ; % 点的y坐标
z ; % 点的z坐标
% 1、计算点云质心
centroid = pcmean(pc);
% 2、去质心化
deMean=pcdemean(pc.Location,centroid);
%% -------------------------------拟合平面---------------------------------
% 3、矩阵A
A = [sumXX sumXY sumXZ;sumXY sumYY sumYZ;sumXZ sumYZ sumZZ];
% 4、矩阵A分解求特征值特征向量
[V,D]=eig(A);
a = V(1,1);b = V(2,1);c = V(3,1);
% 5、计算原点到拟合平面的距离
d = -dot([a b c],centroid);
%% ---------------------------可视化拟合结果-------------------------------figure
% 图形绘制
scatter3(x,y,z,'filled')
hold on;
[XFit,YFit]= meshgrid (xfit,yfit);
mesh(XFit,YFit,ZFit);
title('拉格朗日乘子法拟合平面');

三、算法效果

在这里插入图片描述

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

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

相关文章

【Django学习】(十四)自定义action_router

之前我们的视图类可以继承GenericViewSet或者ModelViewSet,我们不用再自定义通用的action方法,但是有时候我们需要自定义action,我们该如何设计呢? 自定义action 1、手写视图逻辑 1.1、先在视图集里自定义action方法&#xff0…

4、深入理解ribbon

一、负载均衡的两种方式 服务器端负载均衡 传统的方式前端发送请求会到我们的的nginx上去,nginx作为反向代理,然后路由给后端的服务器,由于负载均衡算法是nginx提供的,而nginx是部署到服务器端的,所以这种方式又被称为…

ETLBox for .Net Crack

ETLBox for .Net Crack 为设计的轻量级ETL(提取转换负载)工具箱和数据集成库。NET。 ETL是现代商业智能应用程序的基础,是将分析与之前的所有其他组件分离的唯一方法。ETL是提取-加载、转换和转换的缩写,描述了一个由三个步骤组成的过程: 提取…

【Unity面试篇】Unity 面试题总结甄选 |热更新与Lua语言 | ❤️持续更新❤️

前言 关于Unity面试题相关的所有知识点:🐱‍🏍2023年Unity面试题大全,共十万字面试题总结【收藏一篇足够面试,持续更新】为了方便大家可以重点复习某个模块,所以将各方面的知识点进行了拆分并更新整理了新…

javascript中过滤二维对象数组重复的字段并只保留唯一值(array.filter与Array.from)

javascript中过滤二维对象数组重复的字段并只保留唯一值 1.Array.filter过滤array.filter()方法 2.Array.from过滤Array.from方法 1.Array.filter过滤 在JavaScript中,你可以使用Array.filter()和Set数据结构来过滤二维对象数组中重复的字段,只保留唯一…

Java日期类

日期类 第一代日期类: 1、Date:精确到毫秒,代表特定的瞬间 2、SimpleDateFormat: **格式化和解析日期的具体类,**它允许进行:格式化(日期 → 文本) 解析(文本 → 日期) 和 规范化。 3、常用的使用方法…

SpringBoot源码分析(6)--SpringBootExceptionReporter/异常报告器

文章目录 一、前言二、异常报告器介绍2.1、作用2.2、接口定义2.3、FailureAnalyzer错误分析器2.4、FailureAnalysisReporter错误报告器 三 、SpringBootExceptionReporter源码分析四、shutdownHook介绍4.1、背景4.2、什么是Shutdown Hook4.3、什么时候会调用Shutdown Hook4.4、…

NUXT3学习笔记2

1、配置Ant design Vue (两个安装方式随便选一种,yarn会安装的更快) npm i ant-design-vue --save yarn add ant-design-vue 2、使⽤的 Vite,你可以使⽤ unplugin-vue-components 来进⾏按需加载。 yarn add unplugin-vue-components --save 在nuxt.…

第一阶段-第十一章 Python基础的综合案例(数据可视化-地图可视化)

目录 一、基础地图使用  1.学习目标  2.视觉映射器  3.本节的演示二、疫情地图-国内疫情地图  1.案例效果  2.函数的语法  3.本节的代码演示三、疫情地图-省级疫情地图  1.案例效果  2.本节的代码演示 说明:该文章是学习 黑马程序员在B站上分享的视…

【c++修行之路】IO流架构及使用

文章目录 前言输入输出库文件读写序列化与反序列化结语 前言 大家好久不见,今天一起来学习c中的IO流。 输入输出库 这两张架构图略显复杂,这里给出一张比较清楚的IO流架构图: 也就是说,我们平时使用的诸如cin、cout、cerr、cl…

python selenium.webdriver 爬取政策文件

文章目录 获取文章链接批量爬取政策文件应用selenium爬取文件信息数据处理导出为excel 获取文章链接 获取中央人民政府网站链接,进入国务院政策文件库,分为国务院文件和部门文件(发改委、工信部、交通运输部、市场监督局、商务部等&#xff…

QT实现按钮开关Form窗体的效果

实现效果叙述如下: MainWindow中的按钮实现Form窗体的开关,Form窗体的关闭按钮禁用掉,只允许使用窗体按钮进行,且关闭MainWindow按钮时Form窗体随之关闭。 注意: 要想实现关闭MainWindow按钮时Form窗体随之关闭&#x…