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

如何使用python执行坐标仿射变换?,python,coordinate-transformation,Python,Coordinate Transformation,我想对这个示例数据集执行转换。 在一个坐标系[主坐标系]中有四个坐标为x、y、z的已知点,接下来的四个坐标为x、y、h的已知点属于另一个坐标系[次坐标系]。 这些点对应;例如,primary_system1点和secondary_system1点是完全相同的点,但它的坐标在两个不同的坐标系中。 这里有四对平差点,我想根据平差将另一个点坐标从主坐标系转换到次坐标系 primary_system1 = (3531820.440, 1174966.736, 5162268.086) primary_s

我想对这个示例数据集执行转换。
在一个坐标系[主坐标系]中有四个坐标为x、y、z的已知点,接下来的四个坐标为x、y、h的已知点属于另一个坐标系[次坐标系]。 这些点对应;例如,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>
…对于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

所以在上面,我试图计算每个轴的平均平移向量,如果它只是一个平移和旋转,那么这就是一个称为平移的变换

其基本形式如下:

secondary_system = A * primary_system + b
其中
A
是一个3x3矩阵(因为您在3D中),而
b
是一个3x1转换

这可以等效地写

secondary_system_coords2 = A2 * primary_system2,
在哪里

  • secondary\u system\u coords2
    是向量
    [secondary\u system,1]
  • primary\u system 2
    是向量
    [primary\u system,1]
    ,和
  • A2
    是4x4矩阵:

    [   A   b ]
    [ 0,0,0,1 ]
    
(有关更多信息,请参见wiki页面)

所以基本上,你要解这个方程:

y = A2 x
对于
A2
,其中
y
secondary\u系统的点组成,1个卡在末端,
x
primary\u系统的点,1个卡在末端,
A2
是4x4矩阵

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

A2 = y*x^(-1)
但是
x
是4x1。但是,您很幸运,拥有4组
x
,以及4组相应的
y
,因此您可以构建一个4x4的
x
,如下所示:

x = [ primary_system1 | primary_system2 | primary_system3 | primary_system4 ]
其中,
primary\u 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))
然后像这样使用它:

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相比)是可以接受的。

< P>你所寻找的映射似乎是仿射变换。不在一个平面上的四个3D点是恢复仿射变换所需的精确点数。广义地说,后者是矩阵相乘加向量

secondary_system = A * primary_system + t
现在问题归结为寻找合适的矩阵A和向量t。我想,这段代码可能会对您有所帮助(很抱歉代码风格不好——我是数学家,不是程序员)

将numpy导入为np
#输入数据
ins=np.数组([3531820.4401174966.7365162268.086],
[3531746.800, 1175275.159, 5162241.325],
[3532510.182, 1174373.785, 5161954.920],

[3532495.9681175507.1955161685.049]#你的问题很难回答!那些数字是多少?那么,你试过什么?你有什么密码?问题不清楚。你到底想做什么?请编辑您的问题以澄清。这取决于两个坐标系之间的关系-是旋转还是平移?或者更复杂的问题,比如GPS->UTM?我把这个问题投了更高的票以抵消反对票,因为我很清楚:)非常感谢你的完整答案!这可能是我见过的关于这个问题最完整的答案之一。干得好