gpt4 book ai didi

python - 如何使用python进行坐标仿射变换?

转载 作者:太空狗 更新时间:2023-10-30 02:05:46 24 4
gpt4 key购买 nike

我想对这个示例数据集进行转换。
在一个坐标系[primary_system] 中有四个坐标为 x, y, z 的已知点,接下来的四个坐标为 x, y, h 的已知点属于另一个坐标系 [secondary_system]。这些点对应;例如 primary_system1 点和 secondary_system1 点是完全相同的点,但我们在两个不同的坐标系中有它的坐标。所以我这里有四对调整点,想根据调整将另一点坐标从主系统转换到次系统。

primary_system1 = (3531820.440, 1174966.736, 5162268.086)
primary_system2 = (3531746.800, 1175275.159, 5162241.325)
primary_system3 = (3532510.182, 1174373.785, 5161954.920)
primary_system4 = (3532495.968, 1175507.195, 5161685.049)

secondary_system1 = (6089665.610, 3591595.470, 148.810)
secondary_system2 = (6089633.900, 3591912.090, 143.120)
secondary_system3 = (6089088.170, 3590826.470, 166.350)
secondary_system4 = (6088672.490, 3591914.630, 147.440)

#transform this point
x = 3532412.323
y = 1175511.432
z = 5161677.111<br>


目前,我尝试使用四对点中的每一个对 x、y 和 z 轴进行平均平移,例如:

#x axis
xt1 = secondary_system1[0] - primary_system1[0]
xt2 = secondary_system2[0] - primary_system2[0]
xt3 = secondary_system3[0] - primary_system3[0]
xt4 = secondary_system4[0] - primary_system4[0]

xt = (xt1+xt2+xt3+xt4)/4 #averaging

...对于 y 和 z 轴依此类推

#y axis
yt1 = secondary_system1[1] - primary_system1[1]
yt2 = secondary_system2[1] - primary_system2[1]
yt3 = secondary_system3[1] - primary_system3[1]
yt4 = secondary_system4[1] - primary_system4[1]

yt = (yt1+yt2+yt3+yt4)/4 #averaging

#z axis
zt1 = secondary_system1[2] - primary_system1[2]
zt2 = secondary_system2[2] - primary_system2[2]
zt3 = secondary_system3[2] - primary_system3[2]
zt4 = secondary_system4[2] - primary_system4[2]

zt = (zt1+zt2+zt3+zt4)/4 #averaging

所以上面我试图计算每个轴的平均平移向量

最佳答案

如果只是平移和旋转,那么这就是一个称为 affine transformation 的转换.

它基本上采用以下形式:

secondary_system = A * primary_system + b

其中 A 是 3x3 矩阵(因为您处于 3D 中),b 是 3x1 平移。

这可以等价地写成

secondary_system_coords2 = A2 * primary_system2,

在哪里

  • secondary_system_coords2 是向量[secondary_system,1],
  • primary_system2 是向量[primary_system,1],并且
  • A2 是 4x4 矩阵:

    [   A   b ]
    [ 0,0,0,1 ]

(有关更多信息,请参阅 wiki 页面)。

基本上,您想要求解方程式:

y = A2 x

对于 A2,其中 y 由来自 secondary_system 的点组成,最后是 1,而 x是来自 primary_system 的点,最后是 1,A2 是一个 4x4 矩阵。

现在如果 x 是一个方阵,我们可以像这样解决它:

A2 = y*x^(-1)

但是 x 是 4x1。然而,你很幸运,有 4x 和 4 组相应的 y,所以你可以构造一个 x 像这样的 4x4:

x = [ primary_system1 | primary_system2 | primary_system3 | primary_system4 ]

其中每个 primary_systemi 都是一个 4x1 列向量。与 y 相同。

一旦有了A2,要将点从系统 1 转换为系统 2,您只需执行以下操作:

transformed = A2 * point_to_transform

您可以这样设置(例如在 numpy 中):

import numpy as np
def solve_affine( p1, p2, p3, p4, s1, s2, s3, s4 ):
x = np.transpose(np.matrix([p1,p2,p3,p4]))
y = np.transpose(np.matrix([s1,s2,s3,s4]))
# add ones on the bottom of x and y
x = np.vstack((x,[1,1,1,1]))
y = np.vstack((y,[1,1,1,1]))
# solve for A2
A2 = y * x.I
# return function that takes input x and transforms it
# don't need to return the 4th row as it is
return lambda x: (A2*np.vstack((np.matrix(x).reshape(3,1),1)))[0:3,:]

然后像这样使用它:

transformFn = solve_affine( primary_system1, primary_system2, 
primary_system3, primary_system4,
secondary_system1, secondary_system2,
secondary_system3, secondary_system4 )

# test: transform primary_system1 and we should get secondary_system1
np.matrix(secondary_system1).T - transformFn( primary_system1 )
# np.linalg.norm of above is 0.02555

# transform another point (x,y,z).
transformed = transformFn((x,y,z))

注意:这里当然存在数值误差,这可能不是解决变换的最佳方法(您可以做一些最小二乘法)。

此外,将 primary_systemx 转换为 secondary_systemx 的错误(对于本示例)为 10^(-2) 阶。

你必须考虑这是否可以接受(它看起来确实很大,但与你的输入点相比,它可能是可以接受的,这些点都是 10^6 阶)。

关于python - 如何使用python进行坐标仿射变换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8873462/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com