奇异值分解(SVD)拟合平面

news/2025/2/25 11:52:48

SVD_0">奇异值分解(SVD)拟合平面

在三维空间中,使用奇异值分解(SVD)来拟合平面是一种常见且有效的方法。下面将详细介绍其原理、实现步骤,并给出Python代码示例。

原理

给定一组三维空间中的点 P = { p 1 , p 2 , ⋯   , p n } \mathbf{P} = \{\mathbf{p}_1, \mathbf{p}_2, \cdots, \mathbf{p}_n\} P={p1,p2,,pn},其中 p i = [ x i , y i , z i ] T \mathbf{p}_i = [x_i, y_i, z_i]^T pi=[xi,yi,zi]T。我们的目标是找到一个平面方程 z = a x + b y + c z=ax + by + c z=ax+by+c 来拟合这些点。

可以通过最小化点到平面的距离平方和来实现平面拟合。具体步骤如下:

  1. 计算点集的质心 c = 1 n ∑ i = 1 n p i \mathbf{c} = \frac{1}{n}\sum_{i = 1}^{n}\mathbf{p}_i c=n1i=1npi
  2. 将点集进行中心化 q i = p i − c \mathbf{q}_i = \mathbf{p}_i - \mathbf{c} qi=pic i = 1 , 2 , ⋯   , n i = 1, 2, \cdots, n i=1,2,,n
  3. 构建数据矩阵 A = [ q 1 , q 2 , ⋯   , q n ] T A = [\mathbf{q}_1, \mathbf{q}_2, \cdots, \mathbf{q}_n]^T A=[q1,q2,,qn]T
  4. 对数据矩阵进行奇异值分解 A = U Σ V T A = U\Sigma V^T A=UΣVT,其中 U U U n × n n\times n n×n 的正交矩阵, Σ \Sigma Σ n × 3 n\times 3 n×3 的对角矩阵, V V V 3 × 3 3\times 3 3×3 的正交矩阵。
  5. 确定平面的法向量 V V V 的最后一列对应的向量即为平面的法向量 n = [ a , b , c ] T \mathbf{n} = [a, b, c]^T n=[a,b,c]T

Python代码实现

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def plane_fit(x, y, z):
    """
    拟合平面 z = Ax + By + C 到给定的 (x, y, z) 数据
    :param x: 一维数组,x 坐标
    :param y: 一维数组,y 坐标
    :param z: 一维数组,z 坐标
    :return: A, B, C 平面方程的系数
    """
    # 计算数据点的质心
    P = np.array([np.mean(x), np.mean(y), np.mean(z)])
    # 数据中心化
    centered_data = np.column_stack((x - P[0], y - P[1], z - P[2]))
    # 进行奇异值分解
    U, S, Vt = np.linalg.svd(centered_data)
    # 获取平面的法向量
    print(Vt)
    N =-1/Vt[-1,-1]* Vt[-1, :] 
    print(N)
    # 提取平面方程的系数
    A = N[0]
    B = N[1]
    C = -np.dot(P, N)
    print(A,B,C)
    return A, B, C

# 示例代码
if __name__ == "__main__":
    # 生成网格数据
    x_grid, y_grid = np.meshgrid(np.linspace(0, 10, 20), np.linspace(0, 10, 20))
    # 定义平面方程的真实参数
    a = 1
    b = 2
    c = -2
    # 计算理论 z 值
    z_grid = (a * x_grid) + (b * y_grid) + c
    # 将网格数据转换为一维数组
    x = x_grid.flatten()
    y = y_grid.flatten()
    z = z_grid.flatten()
    # 添加高斯噪声
    z = z + np.random.randn(len(z))
    # 拟合平面
    A, B, C = plane_fit(x, y, z)
    # 生成用于绘制拟合平面的网格
    X, Y = np.meshgrid(np.linspace(np.min(x), np.max(x), 20), np.linspace(np.min(y), np.max(y), 20))
    # 计算拟合平面的 z 值
    Z = (A * X) + (B * Y) + C
    # 创建 3D 图形
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    # 绘制原始数据点
    ax.scatter(x, y, z, c='r', marker='.')
    # 绘制拟合平面
    ax.plot_surface(X, Y, Z, color='g', alpha=0.5)
    # 设置坐标轴网格
    ax.grid(True)
    # 设置图形标题
    title = f' a={a:.4f},b={b:.4f},c={c:.4f},\nA={A:.4f},B={B:.4f},C={C:.4f}'
    ax.set_title(title)
    # 显示图形
    plt.show()

<a class=SVD拟合点云平面" />

代码解释

  1. 计算质心:使用 np.mean 函数计算点集的质心。
  2. 中心化点集:将每个点减去质心,得到中心化后的点集。
  3. 奇异值分解:使用 np.linalg.svd 函数对数据矩阵进行奇异值分解。
  4. 确定法向量:取 V V V 的最后一列作为平面的法向量。

复杂度分析

  • 时间复杂度:主要由奇异值分解的复杂度决定,为 O ( n m 2 ) O(nm^2) O(nm2),其中 n n n 是点的数量, m = 3 m = 3 m=3 是点的维度。
  • 空间复杂度:主要用于存储数据矩阵和奇异值分解的结果,为 O ( n m ) O(nm) O(nm)

http://www.niftyadmin.cn/n/5865464.html

相关文章

【无标题】PHP-get_definde_vars

[题目信息]&#xff1a; 题目名称题目难度PHP-get_defined_vars2 [题目考点]&#xff1a; get_defined_vars — 返回由所有已定义变量所组成的数组此函数返回一个包含所有已定义变量列表的多维数组&#xff0c;这些变量包括环境变量、服务器变量和用户定义的变量。 [Flag格式…

DeepSeek-R1:通过强化学习激发大语言模型的推理能力

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》&#xff08;人工智能科学与技术丛书&#xff09;【陈敬雷编著】【清华大学出版社】 文章目录 DeepSeek大模型技术系列三DeepSeek大模型技术系列三》DeepSeek-…

如何解决 MySQL 数据库服务器 CPU 飙升的情况

大家好&#xff0c;我是 V 哥。当 MySQL 数据库服务器 CPU 飙升时&#xff0c;我们应该怎么办&#xff1f;从何入手解决问题&#xff0c;有没有什么套路&#xff0c;因为自古真情留不住&#xff0c;唯有套路得人心&#xff0c;虽然这是一句玩笑话&#xff0c;也算很贴切&#x…

【算法与数据结构】Dijkstra算法求单源最短路径问题

目录 Dijkstra算法 算法简介&#xff1a; 该算法的核心思想&#xff1a; 算法特点&#xff1a; 算法示例演示&#xff1a; 算法实现&#xff1a; 邻接矩阵存图 邻接表存图&#xff1a; 时间复杂度分析&#xff1a; Dijkstra算法 算法简介&#xff1a; Dijkstra算法&am…

蓝桥云课python代码

第一章语言基础 第一节编程基础 1 python开发环境 第一个Python程序 # 打印"Hello World" print("Hello World")# 打印2的100次方 print(2 ** 100)# 打印112 print("11",1 1)""" Hello World 126765060022822940149670320537…

Spring 源码硬核解析系列专题(一):IoC 容器的初始化过程

Spring 框架作为 Java 生态中最经典的开源项目之一,其核心魅力在于 IoC(控制反转)和 DI(依赖注入)的优雅实现。本系列将深入 Spring 源码,带你从零到一解剖其底层逻辑。本篇作为开篇,我们将聚焦 IoC 容器的初始化过程,以 ClassPathXmlApplicationContext 为例,逐步揭开…

【python】提取word\pdf格式内容到txt文件

一、使用pdfminer提取 import os import re from pdfminer.high_level import extract_text import docx2txt import jiebadef read_pdf(file_path):"""读取 PDF 文件内容:param file_path: PDF 文件路径:return: 文件内容文本"""try:text ext…

Skyeye 云智能制造办公系统 VUE 版本 v3.15.10 发布

Skyeye 云智能制造&#xff0c;采用 Springboot winUI 的低代码平台、移动端采用 UNI-APP。包含 30 多个应用模块、50 多种电子流程&#xff0c;CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公告、问卷、报表…