scipy.spatial.transform.Rotation.

align_vectors#

classmethod Rotation.align_vectors(cls, a, b, weights=None, return_sensitivity=False)#

估計一個旋轉以最佳地對齊兩組向量。

找出框架 A 和 B 之間的旋轉,以最佳地對齊在這些框架中觀察到的一組向量 ab。以下損失函數被最小化以求解旋轉矩陣 \(C\)

\[L(C) = \frac{1}{2} \sum_{i = 1}^{n} w_i \lVert \mathbf{a}_i - C \mathbf{b}_i \rVert^2 ,\]

其中 \(w_i\) 是對應於每個向量的 weights

旋轉是使用 Kabsch 演算法 [1] 估計的,並解決了所謂的「指向問題」或「Wahba 問題」 [2]

有兩種特殊情況。第一種情況是如果為 ab 給定單個向量,在這種情況下,將返回對齊 ba 的最短距離旋轉。

第二種情況是當其中一個權重為無限大時。在這種情況下,主要無限權重向量之間的最短距離旋轉如上計算。然後,計算關於對齊的主要向量的旋轉,使得次要向量根據上述損失函數最佳地對齊。結果是這兩個旋轉的組合。透過此過程得到的結果與 Kabsch 演算法相同,因為相應的權重在極限中接近無限大。對於單個次要向量,這被稱為「對齊約束」演算法 [3]

對於這兩種特殊情況(單個向量或無限權重),靈敏度矩陣沒有物理意義,如果請求,將會引發錯誤。對於無限權重,主要向量充當具有完美對齊的約束,因此即使它們長度不同,它們對 rssd 的貢獻也將被強制設為 0。

參數:
aarray_like,形狀 (3,) 或 (N, 3)

在初始框架 A 中觀察到的向量分量。a 的每一列表示一個向量。

barray_like,形狀 (3,) 或 (N, 3)

在另一個框架 B 中觀察到的向量分量。b 的每一列表示一個向量。

weightsarray_like 形狀 (N,),可選

描述向量觀測相對重要性的權重。如果為 None(預設),則 weights 中的所有值都假定為 1。只能有一個權重可以是無限大,並且權重必須為正。

return_sensitivitybool,可選

是否返回靈敏度矩陣。詳情請參閱「Notes」。預設為 False。

返回:
rotationRotation 實例

b 轉換為 a 的最佳旋轉估計。

rssdfloat

代表「均方根距離」。對齊後,給定向量組之間平方距離的加權總和的平方根。它等於 sqrt(2 * minimum_loss),其中 minimum_loss 是針對找到的最佳旋轉評估的損失函數。請注意,結果也將按向量的大小加權,因此如果完美對齊的向量對長度不同,則將具有非零 rssd。因此,根據用例,在調用此方法之前,可能需要將輸入向量歸一化為單位長度。

sensitivity_matrixndarray,形狀 (3, 3)

如「Notes」中所述,估計旋轉估計的靈敏度矩陣。僅當 return_sensitivity 為 True 時返回。如果對齊單個向量對或存在無限權重,則無效,在這種情況下將引發錯誤。

Notes

靈敏度矩陣給出了估計旋轉對向量測量微小擾動的靈敏度。具體來說,我們將旋轉估計誤差視為框架 A 的小旋轉向量。靈敏度矩陣與此旋轉向量的共變異數成正比,假設 a 中的向量的測量誤差遠小於它們的長度。為了獲得真實的共變異數矩陣,返回的靈敏度矩陣必須乘以每次觀測中變異數的調和平均數 [4]。請注意,weights 應該與觀測變異數成反比,以獲得一致的結果。例如,如果所有向量都以相同的 0.01 精度測量(weights 必須全部相等),那麼您應該將靈敏度矩陣乘以 0.01**2 以獲得共變異數。

有關共變異數估計的更嚴謹討論,請參閱 [5]。有關指向問題和最小適當指向的更多討論,請參閱 [6]

參考文獻

[3]

Magner, Robert,「透過軌跡和動量設定點最佳化擴展目標追蹤能力」。小型衛星會議,2018 年。

[5]

F. Landis Markley,「使用向量觀測確定姿態:一種快速最佳矩陣演算法」,《航太科學雜誌》,第 41 卷,第 2 期,1993 年,第 261-280 頁。

[6]

Bar-Itzhack, Itzhack Y.、Daniel Hershkowitz 和 Leiba Rodman,「在真實歐幾里得空間中指向」,《導航、控制和動力學雜誌》,第 20 卷,第 5 期,1997 年,第 916-922 頁。

範例

>>> import numpy as np
>>> from scipy.spatial.transform import Rotation as R

在這裡,我們運行基準 Kabsch 演算法以最佳地對齊兩組向量,其中 b 集合的最後兩個向量測量存在雜訊

>>> a = [[0, 1, 0], [0, 1, 1], [0, 1, 1]]
>>> b = [[1, 0, 0], [1, 1.1, 0], [1, 0.9, 0]]
>>> rot, rssd, sens = R.align_vectors(a, b, return_sensitivity=True)
>>> rot.as_matrix()
array([[0., 0., 1.],
       [1., 0., 0.],
       [0., 1., 0.]])

當我們將旋轉應用於 b 時,我們得到的向量接近 a

>>> rot.apply(b)
array([[0. , 1. , 0. ],
       [0. , 1. , 1.1],
       [0. , 1. , 0.9]])

第一個向量的誤差為 0,最後兩個向量的誤差為幅度 0.1。rssd 是加權平方誤差總和的平方根,預設權重均為 1,因此在本例中,rssd 的計算方式為 sqrt(1 * 0**2 + 1 * 0.1**2 + 1 * (-0.1)**2) = 0.141421356237308

>>> a - rot.apply(b)
array([[ 0., 0.,  0. ],
       [ 0., 0., -0.1],
       [ 0., 0.,  0.1]])
>>> np.sqrt(np.sum(np.ones(3) @ (a - rot.apply(b))**2))
0.141421356237308
>>> rssd
0.141421356237308

本範例的靈敏度矩陣如下

>>> sens
array([[0.2, 0. , 0.],
       [0. , 1.5, 1.],
       [0. , 1. , 1.]])

特殊情況 1:尋找單個向量之間的最短旋轉

>>> a = [1, 0, 0]
>>> b = [0, 1, 0]
>>> rot, _ = R.align_vectors(a, b)
>>> rot.as_matrix()
array([[0., 1., 0.],
       [-1., 0., 0.],
       [0., 0., 1.]])
>>> rot.apply(b)
array([1., 0., 0.])

特殊情況 2:一個無限權重。在這裡,我們找到主要向量和次要向量之間可以精確對齊的旋轉

>>> a = [[0, 1, 0], [0, 1, 1]]
>>> b = [[1, 0, 0], [1, 1, 0]]
>>> rot, _ = R.align_vectors(a, b, weights=[np.inf, 1])
>>> rot.as_matrix()
array([[0., 0., 1.],
       [1., 0., 0.],
       [0., 1., 0.]])
>>> rot.apply(b)
array([[0., 1., 0.],
       [0., 1., 1.]])

在這裡,次要向量必須是最佳擬合

>>> a = [[0, 1, 0], [0, 1, 1]]
>>> b = [[1, 0, 0], [1, 2, 0]]
>>> rot, _ = R.align_vectors(a, b, weights=[np.inf, 1])
>>> rot.as_matrix()
array([[0., 0., 1.],
       [1., 0., 0.],
       [0., 1., 0.]])
>>> rot.apply(b)
array([[0., 1., 0.],
       [0., 1., 2.]])