1. 程式人生 > >三維座標變換——旋轉矩陣與旋轉向量

三維座標變換——旋轉矩陣與旋轉向量

https://blog.csdn.net/mightbxg/article/details/79363699

用 opencv 進行過雙目相機標定的同學都知道,單目標定 calibrateCamera() 函式能夠對每一張標定影象計算出一對 rvec 和 tvec,即旋轉平移向量,代表世界座標系到相機座標系的轉換關係。而 stereoCalibrate() 函式則可以計算出旋轉矩陣 R 和平移向量 T,代表左右相機座標系之間的轉換關係。同樣是座標變換,平移倒總是向量,但旋轉怎麼有時是向量,有時又是矩陣呢?
旋轉矩陣

參考csxiaoshui的部落格,三維旋轉變換可以看成是矩陣乘法運算,即:
⎡⎣⎢⎢x′y′z′⎤⎦⎥⎥=R∗⎡⎣⎢⎢xyz⎤⎦⎥⎥
其中 R 就是三階的旋轉矩陣。僅僅考慮繞 X、Y 或 Z 單個軸旋轉 θ (右手螺旋),R 分別為:
RX=⎡⎣⎢⎢1000cosθsinθ0−sinθcosθ⎤⎦⎥⎥RY=⎡⎣⎢⎢cosθ0−sinθ010sinθ0cosθ⎤⎦⎥⎥RZ=⎡⎣⎢⎢cosθsinθ0−sinθcosθ0001⎤⎦⎥⎥
繞任意軸旋轉則可以分解成繞三個座標軸旋轉的疊加,最終得到的旋轉矩陣 R 便是上述三個矩陣的乘積。

矩陣運算顯然是計算機三維座標變換最簡單方便的計算方法,因此在 opencv、opengl、工業機器人等開發中,提到位姿旋轉變換,多半用的是旋轉矩陣。然而,用矩陣來表示一個旋轉關係有兩個缺點:
首先,通過旋轉矩陣不能直觀地看出旋轉的方向和角度,假設給定一個旋轉矩陣,要求旋轉方向不變,旋轉角度變成一半,那麼新的旋轉矩陣計算起來就比較麻煩了。
另一方面,旋轉變換本身只有3個自由度,但旋轉矩陣有9個元素,因此旋轉矩陣中的元素不是相互獨立的,這在非線性優化中會帶來問題。
旋轉向量

向量旋轉公式最早由 Rodrigues 提出,用一個三維向量來表示三維旋轉變換,該向量的方向是旋轉軸,其模則是旋轉角度。百度百科中有其詳細的介紹與推導,我在這邊只列一下最重要的公式。
設旋轉向量的單位向量為 r
,模為 θ。三維點(或者說三維向量)p 在旋轉向量 r 的作用下變換至 p′

,則:
p′=cosθ⋅p+(1−cosθ)(p⋅r)r+sinθ⋅r×p
顯然,旋轉向量代表的變換關係十分直觀,但運算上要比矩陣形式更加複雜。

相互轉換

用矩陣形式和向量形式表示旋轉變換各有優劣勢,因此經常需要來回轉換,這裡跟數學中的李群與李代數有所關聯,本人目前還一知半解,可以參考半閒居士的部落格。
opencv 中有函式 Rodrigues() 用於旋轉矩陣和旋轉向量的轉換。參照opencv文件,設旋轉向量的單位向量 r=[rx ry rz]T
,旋轉角度為 θ,對應的旋轉矩陣為 R,則 r 到 R

的轉換是:
R=cosθI+(1−cosθ)rrT+sinθ⎡⎣⎢⎢⎢0rz−ry−rz0rxry−rx0⎤⎦⎥⎥⎥
其中 I 是三階單位矩陣。反過來 R 到 r 的轉換則可以利用等式:
R−RT2=sinθ⎡⎣⎢⎢⎢0rz−ry−rz0rxry−rx0⎤⎦⎥⎥⎥

opencv 官方文件中的原話是:

    A rotation vector is a convenient and most compact representation of a rotation matrix (since any rotation matrix has just 3 degrees of freedom). The representation is used in the global 3D geometry optimization procedures like calibrateCamera, stereoCalibrate, or solvePnP .

稱旋轉向量是旋轉矩陣方便而且最緊湊的表示方法,被用於一些需要全域性三維幾何優化的函式中。