物體在三維空間的旋轉,可以有三個自由度(Degree of Freedom, Dof) - Roll, Pitch, Yaw,而表示物體在三維空間旋轉的方法有很多,例如:歐拉角、旋轉矩陣、旋轉向量、四元數...等,以下將簡單說明,並簡單說明歐拉旋轉定理。

歐拉旋轉定理(Euler's Rotation Theorem)
歐拉 (Leonhard Euler) 於1775年根據簡單的幾何論述證明了這個旋轉定理:
在三維空間中,若一個剛體發生位移且剛體內至少有一點固定不動(通常情況下,此固定點為原點),則此位移等價於一個繞著穿越該固定點的固定軸的旋轉。

簡單來說,歐拉旋轉定理所要說明的理念就是:
任意三維空間的旋轉(在至少有一點固定不動的情況下,)皆可簡單表示為對於某一固定軸的旋轉。
用線性代數術語來說,若 R 是一個定義於 R3 的旋轉矩陣,則存在一非零向量 u 使得:
R u = u,
我們稱 u 是對於 R 的一個不動點(fixed point)。
幾何意義是 u 表示旋轉軸的指向向量,旋轉軸上的每一點 ku (k 是實數) 不受旋轉運動而改變。
歐拉角(Euler Angle)
以 X, Y, Z 軸所旋轉的角度來表示三維空間的旋轉,也就是 Row, Pitch, Yaw 的角度:

任何的旋轉都可以以對三軸(X, Y, Z)的旋轉角度來表示,這樣子的表示方法有兩種可能性,一種是三軸不會跟著旋轉而旋轉,也就是三軸是固定的,稱為 Extrinsic Rotation:

相反的,另一種是三軸會跟著旋轉而改變,稱為 Intrinsic Rotation,這種情形也是較為常見的表示法:

歐拉角的表示方式為三個旋轉角度,通常為 (α, β, γ),舉例來說,可以表示為先對 X 軸旋轉 α,再對 Y 軸旋轉 β,最後對 Z 軸旋轉 γ。
歐拉角的三個旋轉角度,其旋轉軸的順序並非固定,可以分為兩類,共12種,如下:
- Proper Euler angles (z-x-z, x-y-x, y-z-y, z-y-z, x-z-x, y-x-y)
- Tait–Bryan angles (x-y-z, y-z-x, z-x-y, x-z-y, z-y-x, y-x-z)
旋轉矩陣(Rotation Matrix)
以 3 x 3 的矩陣來表示三維空間的旋轉,將旋轉矩陣乘上原本的三維座標值,可以得到旋轉後的三維座標值。
旋轉矩陣可以經過歐拉角求得,假設該旋轉角度為:
對 Z 軸旋轉(Yaw) θz,對 X 軸旋轉(Row) θx,對 Y 軸旋轉(Pitch) θy。
在 R = RY(θy)RX(θx)RZ(θz) 的前提下,其旋轉矩陣的計算方式為:

同時也因為矩陣的乘法不具有交換性,所以先對哪個軸作旋轉,必須要照歐拉角的規定來,不能隨意計算。
如果對旋轉矩陣的推導有興趣,可以參考:旋轉矩陣 (Rotation Matrix)。
在旋轉矩陣中,雖然有9個元素,但因為是由三個角度的變化所組成,所以只有三個自由度(Degree of Matrix),這代表不是所有的 3x3矩陣 都可以作為旋轉矩陣,旋轉矩陣必須為正交矩陣(Orthogonal Matrix),也就是其逆矩陣(Inverse Matrix)等於其轉置矩陣(Transpose Matrix)。
旋轉矩陣的另一個名稱是方向餘弦矩陣(Direction Cosine Matrix, DCM),DCM 在 IMU 的領域中較為常見,是利用三軸在旋轉後的角度變化作為計算依據,但其計算結果與旋轉矩陣相同,詳情可以參考:DCM Tutorial。
旋轉向量(Rotation Vector, Euclidean Vector)
以三維向量來表示三維空間的旋轉。
根據歐拉旋轉定理:
任意三維空間的旋轉皆可簡單表示為對於某一固定軸的旋轉。
也就是說任意的旋轉,都可以由固定軸 + 旋轉角度所組成,也就是軸角表示法(Axis-Angle Representation)。

直覺上來說,可以以三維向量(x, y, z)來表示該固定軸,再以θ表示所旋轉的角度,即可代表三維的旋轉。
再進一步的話,可以將所旋轉的角度以三維向量的長度來表示,即表示為:(θ*x, θ*y, θ*z),於是只要利用三維向量即可表示為三維空間的旋轉,而 (x, y, z) 為其旋轉的單位向量(Unit Vector)。
在 OpenCV 中,以 旋轉矩陣 及 旋轉向量 較為常見,並提供函式 cv::Rodrigues(...),作為 旋轉矩陣 及 旋轉向量 之間的轉換。
四元數(Quaternion)
如同其名稱,以四元數來表示三維空間的旋轉。
同上文中所提到的旋轉向量,(x, y, z) 為其旋轉的單位向量,θ為所旋轉的角度,則四元數可以表示為:
[cos(θ/2), x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)]
四元數及旋轉矩陣及歐拉角的表示方式是等價的,但表示方向較為精簡,且需要的計算量較少。
程式範例
以下為以 OpenCV 所實作的旋轉程式結果:
三軸的顏色配置為:X 軸 Red,Y 軸 Green,Z 軸 Blue。
旋轉角度(θ) 依序為 0°, 30°, 60°, 90°, 120°, 150°, 180°, 210°, 240°, 270°, 300°, 330°, 360°
從左到右依序為:
- 只有對 X 軸旋轉θ
- 只有對 Y 軸旋轉θ
- 只有對 Z 軸旋轉θ
- 先對 X 軸旋轉 θ,再對 Y 軸旋轉 θ
- 先對 Y 軸旋轉 θ,再對 X 軸旋轉 θ
- 對 X 軸 及 Y 軸的中間軸旋轉θ
θ 為 0°

θ 為 30°

θ 為 60°

θ 為 90°

θ 為 120°

θ 為 150°

θ 為 180°

θ 為 210°

θ 為 240°

θ 為 270°

θ 為 300°

θ 為 330°

θ 為 360°

由以上測試可以得知在 OpenCV 的座標系為:

正角度旋轉方向為順時針旋轉。
程式在實作上主要所用到的函式為:
void cv::Rodrigues(...)
=> 計算 Rotation Vector 與 Rotation Matrix 之間的轉換。
void cv::projectPoints(...)
=> 當三維的點經過旋轉後(輸入的旋轉參數為:Rotation Vector 型態),投影到二維影像平面時,計算其二維座標位置。
先對 x 軸旋轉,再對 y 軸旋轉的作法為:
利用對 x 軸旋轉的旋轉向量 - (θx, 0, 0),透過 cv::Rodrigues(),求出其旋轉矩陣 - rMX。
利用對 y 軸旋轉的旋轉向量 - (0, θy, 0),透過 cv::Rodrigues(),求出其旋轉矩陣 - rMY。
再將這兩個向量作矩陣相乘 rMY x rMX,並將相乘後的結果透過 cv::Rodrigues(),求得其旋轉向量。
將最後求到的旋轉向量代入 cv::projectPoints(...) 即可。
先對 y 軸旋轉,再對 x 軸旋轉的作法為:
同上述作法,但在作矩陣相乘時,為 rMX x rMY。
對 x, y 軸的中間軸旋轉的作法為:
將對 x, y 軸旋轉的旋轉向量 - (θx, θy, 0),透過 cv::Rodrigues(),求出其旋轉向量。
再將旋轉向量代入 cv::projectPoints(...) 即可。
Reference
剛體在三維空間的旋轉
Euler Angles
Rotation Matrix
Euclidean Vector
Axis-Angle Representation
Quaternions and Spatial Rotation
文字內容 或 影像內容 部份參考、引用自網路,如有侵權,請告知,謝謝。
全站熱搜