align_vectors#
- classmethod Rotation.align_vectors(cls, a, b, weights=None, return_sensitivity=False)#
估計一個旋轉以最佳地對齊兩組向量。
找出框架 A 和 B 之間的旋轉,以最佳地對齊在這些框架中觀察到的一組向量 a 和 b。以下損失函數被最小化以求解旋轉矩陣 \(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]。
有兩種特殊情況。第一種情況是如果為 a 和 b 給定單個向量,在這種情況下,將返回對齊 b 到 a 的最短距離旋轉。
第二種情況是當其中一個權重為無限大時。在這種情況下,主要無限權重向量之間的最短距離旋轉如上計算。然後,計算關於對齊的主要向量的旋轉,使得次要向量根據上述損失函數最佳地對齊。結果是這兩個旋轉的組合。透過此過程得到的結果與 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。
- 返回:
- rotation
Rotation
實例 將 b 轉換為 a 的最佳旋轉估計。
- rssdfloat
代表「均方根距離」。對齊後,給定向量組之間平方距離的加權總和的平方根。它等於
sqrt(2 * minimum_loss)
,其中minimum_loss
是針對找到的最佳旋轉評估的損失函數。請注意,結果也將按向量的大小加權,因此如果完美對齊的向量對長度不同,則將具有非零 rssd。因此,根據用例,在調用此方法之前,可能需要將輸入向量歸一化為單位長度。- sensitivity_matrixndarray,形狀 (3, 3)
如「Notes」中所述,估計旋轉估計的靈敏度矩陣。僅當 return_sensitivity 為 True 時返回。如果對齊單個向量對或存在無限權重,則無效,在這種情況下將引發錯誤。
- rotation
Notes
靈敏度矩陣給出了估計旋轉對向量測量微小擾動的靈敏度。具體來說,我們將旋轉估計誤差視為框架 A 的小旋轉向量。靈敏度矩陣與此旋轉向量的共變異數成正比,假設 a 中的向量的測量誤差遠小於它們的長度。為了獲得真實的共變異數矩陣,返回的靈敏度矩陣必須乘以每次觀測中變異數的調和平均數 [4]。請注意,weights 應該與觀測變異數成反比,以獲得一致的結果。例如,如果所有向量都以相同的 0.01 精度測量(weights 必須全部相等),那麼您應該將靈敏度矩陣乘以 0.01**2 以獲得共變異數。
有關共變異數估計的更嚴謹討論,請參閱 [5]。有關指向問題和最小適當指向的更多討論,請參閱 [6]。
參考文獻
[1]https://en.wikipedia.org/wiki/Kabsch_algorithm (Kabsch 演算法)
[2][3]Magner, Robert,「透過軌跡和動量設定點最佳化擴展目標追蹤能力」。小型衛星會議,2018 年。
[4][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.]])