本文出自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} mx−x0=ny−y0=pz−z0(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=∣∣Q1Q2∣∣2∣∣(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(z−z0)+x0y=pn(z−z0)+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=pm、b=x0−pmz0、c=pn、d=y0−pnz0则式(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 O Y XOY XOY、 Y O Z YOZ YOZ和 X O Z XOZ XOZ 坐标平面,将空间直线的6个几何参数转化为4个几何参数。
基于最小二乘准则的三维空间直线拟合方法如下所述:
假设 x i ^ = a z i ^ + b \hat{x_i}=a\hat{z_i}+b xi^=azi^+b表示按式(4)求得的近似值,则与实测值 x i x_i xi的较差和为:
Q x = ∑ i = 1 m [ x i − ( a z i + b ) ] 2 (5) Q_x=\sum_{i=1}^m\ [x_{i}-(az_i+b)]^2\tag{5} Qx=i=1∑m [xi−(azi+b)]2(5)
假设 y i ^ = c z i ^ + d \hat{y_i}=c\hat{z_i}+d yi^=czi^+d表示按式(4)求得的近似值,则与实测值 y i y_i yi的较差和为:
Q y = ∑ i = 1 m [ y i − ( c z i + d ) ] 2 (6) Q_y=\sum_{i=1}^m\ [y_{i}-(cz_i+d)]^2\tag{6} Qy=i=1∑m [yi−(czi+d)]2(6)
基于最小二乘准则,为获得 Q x Q_x Qx和 Q y Q_y Qy的最小值,对式(7)和式(8)求取关于 a 、 b 、 c 、 d a、b、c、d a、b、c、d的导数并令其为0,可得:
{ b N + a ∑ i = 1 m z i = ∑ i = 1 m x i b ∑ i = 1 m z i + a ∑ i = 1 m z i 2 = ∑ i = 1 m x i z i d N + c ∑ i = 1 m z i = ∑ i = 1 m y i d ∑ i = 1 m z i + c ∑ i = 1 m z i 2 = ∑ i = 1 m y i z i (7) \begin{cases} bN+a\sum_{i=1}^mz_i=\sum_{i=1}^mx_i\\ b\sum_{i=1}^mz_i+a\sum_{i=1}^mz_i^2=\sum_{i=1}^mx_iz_i\\ dN+c\sum_{i=1}^mz_i=\sum_{i=1}^my_i\\ d\sum_{i=1}^mz_i+c\sum_{i=1}^mz_i^2=\sum_{i=1}^my_iz_i\\ \end{cases} \tag{7} ⎩
⎨
⎧bN+a∑i=1mzi=∑i=1mxib∑i=1mzi+a∑i=1mzi2=∑i=1mxizidN+c∑i=1mzi=∑i=1myid∑i=1mzi+c∑i=1mzi2=∑i=1myizi(7)
令:
M = [ z 1 z 2 ⋯ z n 1 1 ⋯ 1 ] (8) M=\left[ \begin{matrix} z_1&z_2&\cdots&z_n \\ 1&1&\cdots&1 \\ \end{matrix} \right]\tag{8} M=[z11z21⋯⋯zn1](8)
则式(7)可简化为:
M M T A = M X , M M T B = M Y (9) MM^TA=MX,MM^TB=MY\tag{9} MMTA=MX,MMTB=MY(9)
式中: A = [ a , b ] T ; X = [ x 1 , . . . , x m ] T ; B = [ c , d ] T ; Y = [ y 1 , . . . , y m ] T A=[a,b]^T;X=[x_1,...,x_m]^T;B=[c,d]^T;Y=[y_1,...,y_m]^T A=[a,b]T;X=[x1,...,xm]T;B=[c,d]T;Y=[y1,...,ym]T。
或者最小二乘直接求解:
a = n ∑ i = 1 n x i z i − ∑ i = 1 n x i ∗ ∑ i = 1 n z i n ∑ i = 1 n z i 2 − ∑ i = 1 n z i ∗ ∑ i = 1 n z i a=\frac{n\sum_{i=1}^nx_iz_i-\sum_{i=1}^nx_i*\sum_{i=1}^nz_i}{n\sum_{i=1}^nz_{i}^2-\sum_{i=1}^nz_i*\sum_{i=1}^nz_i} a=n∑i=1nzi2−∑i=1nzi∗∑i=1nzin∑i=1nxizi−∑i=1nxi∗∑i=1nzi
b = ∑ i = 1 n x i − a ∑ i = 1 n z i n b=\frac{\sum_{i=1}^nx_i-a\sum_{i=1}^nz_i}{n} b=n∑i=1nxi−a∑i=1nzi
c = n ∑ i = 1 n y i z i − ∑ i = 1 n y i ∗ ∑ i = 1 n z i n ∑ i = 1 n z i 2 − ∑ i = 1 n z i ∗ ∑ i = 1 n z i c=\frac{n\sum_{i=1}^ny_iz_i-\sum_{i=1}^ny_i*\sum_{i=1}^nz_i}{n\sum_{i=1}^nz_{i}^2-\sum_{i=1}^nz_i*\sum_{i=1}^nz_i} c=n∑i=1nzi2−∑i=1nzi∗∑i=1nzin∑i=1nyizi−∑i=1nyi∗∑i=1nzi
d = ∑ i = 1 n y i − c ∑ i = 1 n z i n d=\frac{\sum_{i=1}^ny_i-c\sum_{i=1}^nz_i}{n} d=n∑i=1nyi−c∑i=1nzi
2、参考文献
[1] 包建强,张献州,李圆等.多种空间直线拟合方法应用分析[J].测绘科学,2020,45(05):132-139+151.DOI:10.16251/j.cnki.1009-2307.2020.05.020.
[2] 薛丽红.三维空间点中基于最小二乘法的分段直线拟合方法[J].齐齐哈尔大学学报(自然科学版),2015,31(04):84-85+89.
[3] 三维空间点的直线方程拟合(最小二乘法)
[4] 最小二乘法拟合空间直线的原理及实现(这篇博客的方法存在不足!!!)
3、示例代码
import numpy as np
def line_fit_3d_points(points):
"""
最小二乘拟合空间直线
:param points: 三维点集合
直线方程:
x = a * z + b
y = c * z + d
:return: 直线参数a,b,c,d
"""
x = points[:, 0]
y = points[:, 1]
z = points[:, 2]
n = points.shape[0]
a = (n * sum(x * z) - sum(x) * sum(z)) / (n * sum(z * z) - sum(z) * sum(z))
b = (sum(x) - a * sum(z)) / n
c = (n * sum(y * z) - sum(y) * sum(z)) / (n * sum(z * z) - sum(z) * sum(z))
d = (sum(y) - c * sum(z)) / n
return a, b, c, d