整体最小二乘拟合空间直线


在这里插入图片描述

本文由CSDN点云侠原创,原文链接。爬虫自重,把自己当个人。

1、算法过程

  空间直线的点向式方程为:
x − x 0 m = y − y 0 n = z − z 0 p (1) \frac{x-x_0}{m}=\frac{y-y_0}{n}=\frac{z-z_0}{p}\tag{1} mxx0=nyy0=pzz0(1)
式中: m , n , p m,n,p m,n,p为空间直线的方向向量; x 0 , y 0 , z 0 x_0,y_0,z_0 x0,y0,z0为空间直线的已知点。

  空间中任意一点 P ( x , y , z ) P(x,y,z) P(x,y,z)到空间点 Q 1 ( x 1 , y 1 , z 1 ) Q_1(x_1,y_1,z_1) Q1(x1,y1,z1) Q 2 ( x 1 , y 1 , z 1 ) Q_2(x_1,y_1,z_1) Q2(x1,y1,z1)组成的空间直线的距离为:
d = ∣ ∣ ( Q 1 Q 2 × Q 1 P ) ∣ ∣ 2 ∣ ∣ Q 1 Q 2 ∣ ∣ 2 (2) d=\frac{||(Q_1Q_2\times Q_1P)||_2}{||Q_1Q_2||_2}\tag{2} d=∣∣Q1Q22∣∣(Q1Q2×Q1P)2(2)

  式(1)可以变形为:

{ x = m p ( z − z 0 ) + x 0 y = n p ( z − z 0 ) + y 0 (3) \begin{cases} x=\frac{m}{p}(z-z_0)+x_0\\ y=\frac{n}{p}(z-z_0)+y_0\\ \end{cases} \tag{3} { x=pm(zz0)+x0y=pn(zz0)+y0(3)
  设 a = m p 、 b = x 0 − m p z 0 、 c = n p 、 d = y 0 − n p z 0 a=\frac{m}{p}、b=x_0-\frac{m}{p}z_0、c=\frac{n}{p}、d=y_0-\frac{n}{p}z_0 a=pmb=x0pmz0c=pnd=y0pnz0则式(1)可表示为:
{ x = a z + b y = c z + d (4) \begin{cases} x=az+b\\ y=cz+d\\ \end{cases} \tag{4} { x=az+by=cz+d(4)

  三维空间直线的变换方程式(4),其矩阵形式为:

[ x y ] = [ z 1 0 0 0 0 z 1 ] [ a ^ b ^ c ^ d ^ ] (5) \left[ \begin{matrix} x \\ y \\ \end{matrix} \right]=\left[ \begin{matrix} z&1&0&0\\ 0&0&z&1\\ \end{matrix} \right] \left[ \begin{matrix} \hat{a}\\ \hat{b}\\ \hat{c}\\ \hat{d}\\ \end{matrix} \right] \tag{5} [xy]=[z0100z01] a^b^c^d^ (5)

式(5)的误差方程可表示为:

V = [ z 1 0 0 0 0 z 1 ] [ a ^ b ^ c ^ d ^ ] − [ x y ] (6) V=\left[ \begin{matrix} z&1&0&0\\ 0&0&z&1\\ \end{matrix} \right] \left[ \begin{matrix} \hat{a}\\ \hat{b}\\ \hat{c}\\ \hat{d}\\ \end{matrix} \right] -\left[ \begin{matrix} x\\ y\\ \end{matrix} \right]\tag{6} V=[z0100z01] a^b^c^d^ [xy](6)

令:
B = [ z 1 0 0 0 0 z 1 ] , L = [ x y ] , X ^ = [ a ^ b ^ c ^ d ^ ] B=\left[ \begin{matrix} z&1&0&0\\ 0&0&z&1\\ \end{matrix} \right], L=\left[ \begin{matrix} x\\ y\\ \end{matrix} \right], \hat{X}=\left[ \begin{matrix} \hat{a}\\ \hat{b}\\ \hat{c}\\ \hat{d}\\ \end{matrix} \right] B=[z0100z01],L=[xy],X^= a^b^c^d^

则式(6)可以简化为:
V = B X ^ − L (7) V=B\hat{X}-L\tag{7} V=BX^L(7)

  假设三维空间直线的观测数据为 L i ( x i , y i , z i ) L_i(x_i,y_i,z_i) Li(xi,yi,zi),其误差方程可以按照式(7)表述为:
B = [ z 1 1 0 0 0 0 z 1 1 ⋮ ⋮ ⋮ ⋮ z n 1 0 0 0 0 z n 1 ] , L = [ x 1 y 1 ⋮ x n y n ] , X ^ = [ a ^ b ^ c ^ d ^ ] B=\left[ \begin{matrix} z_1&1&0&0\\ 0&0&z_1&1\\ \vdots&\vdots&\vdots&\vdots\\ z_n&1&0&0\\ 0&0&z_n&1\\ \end{matrix} \right], L=\left[ \begin{matrix} x_1\\ y_1\\ \vdots\\ x_n\\ y_n\\ \end{matrix} \right], \hat{X}=\left[ \begin{matrix} \hat{a}\\ \hat{b}\\ \hat{c}\\ \hat{d}\\ \end{matrix} \right] B= z10zn010100z10zn0101 ,L= x1y1xnyn ,X^= a^b^c^d^

  整体最小二乘是同时顾及观测值和系数矩阵误差的一种平差方法,相比于最小二乘,其参数估值是统计最优解,但参数求解相对复杂。整体最小二乘有两种解法:奇异值分解解法和迭代解法。若利用整体最小二乘的SVD解法对误差方程式(7)进行解算,即认为误差方程矩阵 B B L L 的所有元素均包含误差。而三维空间直线的误差方程式(7)的系数阵中包含了常数项和带有误差的观测量,整体最小二乘的SVD解法忽略了误差方程式(7)的特殊性。
迭代解法解算整体最小二乘空间直线的误差方程式(7),平差准则为:
∑ i = 1 n ( L ^ i − L i ) 2 + ∑ i = 1 , j = 1 j = t , i = n ( B ^ i j − B i j ) 2 = m i n (8) \sum_{i=1}^n (\hat{L}_{i}-L_{i})^2+\sum_{i=1,j=1}^{j=t,i=n} (\hat{B}_{ij}-B_{ij})^2=min\tag{8} i=1n(L^iLi)2+i=1,j=1j=t,i=n(B^ijBij)2=min(8)

代入式(7),对各元素进行求导,获得迭代方程:
{ B ^ T X ^ = B ^ T L N b B ^ T = B ^ T + X ^ L T (9) \begin{cases} \hat{B}^T\hat{X}=\hat{B}^TL\\ N_b\hat{B}^T=\hat{B}^T+\hat{X}L^T\\ \end{cases} \tag{9} { B^TX^=B^TLNbB^T=B^T+X^LT(9)

式中: N b = E + X ^ X ^ T N_b=E+\hat{X}\hat{X}^T Nb=E+X^X^T。整体最小二乘空间直线拟合的迭代解法过程如下图所示。
在这里插入图片描述

2、参考文献

[1] 包建强,张献州,李圆等.多种空间直线拟合方法应用分析[J].测绘科学,2020,45(05):132-139+151.DOI:10.16251/j.cnki.1009-2307.2020.05.020.

3、算法伪码

import numpy as np


def line_fit_3d_points_m(points):
    """
    全局最小二乘拟合空间直线
    :param points: 三维点集合
     直线方程:
     x = a * z + b
     y = c * z + d
    :return: 直线参数向量数组X
    """

    n = points.shape[0]  # 点的个数
    B = np.zeros((#, 4)  # 矩阵B
    L = np.zeros(#, 1)   # 矩阵L
    X = np.ones(#, 1)    # 解X
    deltX = np.ones(#, 1)   # 迭代增量deltX
    # 构建计算所需矩阵
    for i in range(0, n):
        B[# * i, 0] = points[i].z
        B[# * i, 1] = 1
        B[# * i + 1, 2] = points[i].z
        B[# * i + 1, 3] = 1

        L[# * i] = points[i].x
        L[# * i + 1] = points[i].y
    # 迭代计算
    count = 0
    while norm(deltX) > 0.0001:
        W = B.T*l
        deltX = inv(B.T*B)*W

        X += deltX
        count += 1
        if count >= 10:
            break
    print("迭代次数:", count)

    return X

4、算法效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_36686437/article/details/131747052
今日推荐