從零開始一起學習SLAM | 為什麼要用齊次坐標?
在涉及到計算機視覺的幾何問題中,我們經常看到齊次坐標這個術語。本文介紹一下究竟為什麼要用齊次坐標?使用齊次坐標到底有什麼好處?
什麼是齊次坐標?
簡單的說:齊次坐標就是在原有坐標上加上一個維度:
使用齊次坐標有什麼優勢?
齊次坐標的使用能夠大大簡化在三維空間中的點線面表達方式和旋轉平移等操作,具體分如下幾點進行說明。
1、能否非常方便的表達點在直線或平面上
在2D平面上,一條直線 l 可以用方程 ax + by + c = 0 來表示,該直線用向量表示的話一般記做
我們知道點p = (x, y)在直線 l 上的充分必要條件是 ax + by + c = 0
如果使用齊次坐標的話,點p的齊次坐標就是
p=(x, y, 1)
那麼 ax + by + c = 0 就可以用兩個向量的內積(點乘)來表示:
因此,點p在直線l上的充分必要條件就是 直線l 與p的齊次坐標p的內積:
是不是很方便呢!
同理,我們知道 三維空間的一個平面A可以用方程 ax + by + cz + d = 0 來表示,三維空間的一個點P=(x, y, z) 的齊次坐標 P=(x, y, z, 1),類似的,點P在空間平面A上可以用兩個向量的內積來表示,如下:
因此,點P在平面A上的充分必要條件就是平面A 向量與P的齊次坐標P的內積(點乘):
2、方便表達直線與直線,平面與平面的交點
先給出結論,後面再具體解釋:
結論:在齊次坐標下,可以用兩個點 p, q 的齊次坐標叉乘結果來表達一條直線 l,也就是
l = p x q
也可以使用兩條直線 l, m 的叉乘表示他們的交點 x
x = l x m
見下面示例圖。
之所以可以這麼簡潔的表示交點是因為採用了齊次坐標的表示方式。
那麼這是為什麼呢?
先介紹一下叉乘(也稱叉積、外積)的概念:
兩個向量 a和b 的叉乘僅在三維空間中有定義,寫作 a x b
a x b 是與向量 a, b都垂直的向量,其方向通過右手定則(見下圖)決定。
其模長等於以兩個向量為邊的平行四邊形的面積(見下圖)。
叉乘可以定義為:
其中 θ表示a, b的夾角(0°到180°之間),||a||, ||b||是向量a, b的模長
n則是一個與向量a, b所構成的平面垂直的單位向量
根據叉乘定義:
向量自身叉乘結果為0,因為夾角為0。也就是說三維向量 a x a =0, b x b = 0而點乘(也稱點積,內積)的定義是
a * b = ||a||* ||b|| *cos(θ)
根據定義:如果兩個向量垂直,cos(θ) = 0,點積也為0。
好了,經過上面點乘和叉乘定義的鋪墊。下面來推導一下上面的結論:
為什麼兩條直線 l, m 的叉乘 l x m 等於它們的交點 p,也就是 p = l x m?
原因如下:首先,根據前面叉乘的定義,l x m 的結果向量(記為 p = l x m) 與 l 和 m都垂直,根據點乘的定義,垂直的向量之間的點積為0,因此可以得到:
因此,根據前面點在直線上的結論,可以看到p既在直線l 上又在直線m上,所以 p = l x m 是兩條直線的交點。此處 p 是齊次坐標。
同樣的,可以證明,兩點p, q 的叉乘 可以表示 過兩點的直線l,即 l = p x q。(留做作業)
3、能夠區分一個向量和一個點
先給出結論:
(1)從普通坐標轉換成齊次坐標時
如果(x,y,z)是個點,則變為(x,y,z,1);
如果(x,y,z)是個向量,則變為(x,y,z,0)
(2)從齊次坐標轉換成普通坐標時
如果是(x,y,z,1),則知道它是個點,變成(x,y,z);
如果是(x,y,z,0),則知道它是個向量,仍然變成(x,y,z)
具體解釋見:
齊次坐標的理解 - Bigcoder - 博客園
4、能夠表達無窮遠
比如 兩條平行的直線 ax+by+c=0, ax+by+d=0,
可以分別用向量 l = (a, b, c), m = (a, b,d)表示
根據前面直線交點的計算方法,其交點為 l x m
根據叉乘計演算法則
向量
的叉乘結果可以用如下方法計算得到
最終:l x m = (d-c)(b,-a,0),忽略標量(d-c),我們得到交點為(b,-a,0),並且是齊次坐標,如果要轉化為非齊次坐標,那麼會得到 (b/0, a/0),坐標是無窮大,可以認為該點為無窮遠點,這與我們通常理解的:平行線相交於無窮遠的概念相吻合。
因此,如果一個點的齊次坐標中,最後一個元素為0,則表示為無窮遠點。
5、更簡潔的表達歐氏空間變換
這是齊次坐標最重要的一個優勢之一。在以後的學習中你會更加深刻的理解。
使用齊次坐標,可以方便的將加法轉化為乘法,方便的表達平移。
比如我們要完成將2D坐標點x=[u,v] 平移t=[tu, tv],如果用非齊次方法的話,是用如下的加法
如果用齊次坐標表示時可以將加法轉換為乘法
在歐氏變換中一般有兩種操作:旋轉和平移。
如果我們想要將向量a進行一個標準的歐氏變換,一般是先用旋轉矩陣R進行旋轉,然後再用向量t進行平移,其結果a = R*a + t,這樣看起來沒什麼問題。
但是,我們知道SLAM中一般都是連續的歐氏變換,所以會有多次連續的旋轉和平移,假設我們將向量a進行了兩次歐氏變換,分別為R1, t1 和 R2,t2,分別得到:
b = R1*a + t1, c = R2*b + t2
最終的結果 c = R2*(R1*a + t1) + t2
顯然,這樣的變換在經過多次後會變的越來越複雜。其根本原因是上述表達方式並不是一個線性的變換關係。
此時,齊次坐標就顯示出它的魅力了,如果使用齊次坐標來表達 a = R*a + t 的話可以寫為:
旋轉和平移可以用一個矩陣T來表示,該矩陣T稱為變換矩陣(transform matrix),這樣歐氏變換就變成了線性關係,進行多次歐氏變換隻需要連乘變換矩陣就行了,比如前面的兩次歐氏變換使用齊次坐標就可以表示為:
其中,波浪號代表齊次坐標。一般的,在SLAM中,b = Ta 的形式默認都是齊次坐標。
關於齊次坐標的優勢還有哪些呢?歡迎留言補充。
作業
證明:兩點p, q 的叉乘 可以表示 過兩點的直線l,即 l = p x q
(提示:參考本文前面的證明)
歡迎留言討論,更多學習視頻、文檔資料、參考答案等掃描下方二維碼進入知識星球「從零開始學習SLAM」和其他學習SLAM學的夥伴一起學習交流~
相關閱讀
從零開始一起學習SLAM | 為什麼要學SLAM?從零開始一起學習SLAM | 學習SLAM到底需要學什麼?從零開始一起學習SLAM | SLAM有什麼用?從零開始一起學習SLAM | C++新特性要不要學?零基礎小白,如何入門計算機視覺?推薦閱讀: