2012-01-15 96 views
-3

我想对此示例数据集执行转换。
在一个坐标[primary_system]系统中有四个坐标为x,y,z的已知点,以及坐标为x,y,h的下一个四个已知点属于另一个坐标系[secondary_system]。 这些点对应;例如primary_system1点和secondary_system1点是完全相同的点,但我们在两个不同的坐标系中有它的坐标。 所以我在这里有四对调整点,并希望根据调整将另一个点坐标从主系统转换到辅助系统。如何使用python执行坐标仿射变换?

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 

所以上面我试图计算平均平移矢量各轴

+1

你的问题很晦涩!这些数字是什么? – 2012-01-15 21:35:12

+4

那么,你有什么尝试?你有什么代码? – Marcin 2012-01-15 21:37:18

+0

@Rig Poggi如果你对这些数字不清楚,那么你可能不知道该做什么,那么你的评论是什么? – daikini 2012-01-15 21:49:21

回答

7

如果它只是一个平移和旋转,那么这是一个被称为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是4×4矩阵:

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

(请参阅Wiki页面以了解更多信息)。

所以基本上,你要解决的方程式:

y = A2 x 

A2,其中ysecondary_system 1粘在年底由点,并卡x百分点primary_system 1上月底,并且A2是4x4矩阵。

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

A2 = y*x^(-1) 

x是4X1。然而,你是幸运的,并具有套x用4个对应的y集,这样就可以构造一个x即4×4像这样:

x = [ primary_system1 | primary_system2 | primary_system3 | primary_system4 ] 

,其中每个的primary_systemi是一个4×1的列向量。与y相同。

一旦你有了A2,从系统1变换点系统2你只是做:

transformed = A2 * point_to_transform 

您可以设置这件事(在numpy EG)是这样的:

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的订单)可能是可以接受的。

+0

非常感谢您的完整答案! – daikini 2012-01-16 08:37:28

+0

可能是我对这个问题看到的最完整的答案之一。做得好。 – b10hazard 2017-06-28 12:22:58