2013-12-12 36 views
5

我有同樣的問題,如下所述: how to perform coordinates affine transformation using python?如何使用python執行座標仿射變換?第2部分

我試圖用描述的方法,但由於某種原因,我會得到錯誤信息。 我對代碼所做的更改是替換主系統和輔助系統點。我使用不同的origo創建了輔助座標點。在我研究這個主題的實際案例中,在測量座標時會有一些錯誤。

primary_system1 = (40.0, 1160.0, 0.0) 
primary_system2 = (40.0, 40.0, 0.0) 
primary_system3 = (260.0, 40.0, 0.0) 
primary_system4 = (260.0, 1160.0, 0.0) 

secondary_system1 = (610.0, 560.0, 0.0) 
secondary_system2 = (610.0,-560.0, 0.0) 
secondary_system3 = (390.0, -560.0, 0.0) 
secondary_system4 = (390.0, 560.0, 0.0) 

錯誤我是執行以下時從獲得。

*Traceback (most recent call last): 
    File "affine_try.py", line 57, in <module> 
    secondary_system3, secondary_system4) 
    File "affine_try.py", line 22, in solve_affine 
    A2 = y * x.I 
    File "/usr/lib/python2.7/dist-packages/numpy/matrixlib/defmatrix.py", line 850, in getI 
    return asmatrix(func(self)) 
    File "/usr/lib/python2.7/dist-packages/numpy/linalg/linalg.py", line 445, in inv 
    return wrap(solve(a, identity(a.shape[0], dtype=a.dtype))) 
    File "/usr/lib/python2.7/dist-packages/numpy/linalg/linalg.py", line 328, in solve 
    raise LinAlgError, 'Singular matrix' 
numpy.linalg.linalg.LinAlgError: Singular matrix* 

可能是什麼問題?

回答

15

問題是你的矩陣是單數的,這意味着它不可逆。既然你試圖去反過來,那就是一個問題。你鏈接的線程是解決你的問題的基本方法,但這不是最好的解決方案。不是僅僅反演矩陣,你實際上想要做的就是求解最小二乘最小化問題,以找到最適合你的噪聲數據的仿射變換矩陣。這裏是你會怎麼做:

import numpy as np 

primary = np.array([[40., 1160., 0.], 
        [40., 40., 0.], 
        [260., 40., 0.], 
        [260., 1160., 0.]]) 

secondary = np.array([[610., 560., 0.], 
         [610., -560., 0.], 
         [390., -560., 0.], 
         [390., 560., 0.]]) 

# Pad the data with ones, so that our transformation can do translations too 
n = primary.shape[0] 
pad = lambda x: np.hstack([x, np.ones((x.shape[0], 1))]) 
unpad = lambda x: x[:,:-1] 
X = pad(primary) 
Y = pad(secondary) 

# Solve the least squares problem X * A = Y 
# to find our transformation matrix A 
A, res, rank, s = np.linalg.lstsq(X, Y) 

transform = lambda x: unpad(np.dot(pad(x), A)) 

print "Target:" 
print secondary 
print "Result:" 
print transform(primary) 
print "Max error:", np.abs(secondary - transform(primary)).max() 

,你的原始矩陣是奇異的原因是你的第三個座標始終爲零,所以沒有辦法告訴變換上什麼座標應爲(零次東西給人零,所以任何值都可以工作)。

印刷A值告訴你,最小二乘找到了改造:其中x1, y1, z1在原始系統的座標,相當於x2 = -x1 + 650, y2 = y1 - 600, z2 = 0

A[np.abs(A) < 1e-10] = 0 # set really small values to zero 
print A 

結果

[[ -1. 0. 0. 0.] 
[ 0. 1. 0. 0.] 
[ 0. 0. 0. 0.] 
[ 650. -600. 0. 1.]] 

x2, y2, z2是您新系統中的座標。正如你所看到的,由於你的系統實際上是二維的,所以最小二乘法將所有與第三維相關的項設置爲零。