2012-01-15 293 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