(四)單應矩陣


單應矩陣原理

 

  單應(透射變換)是射影幾何中的概念,又稱為射影變換。他把一個射影平面上的點映射到另一個平面對應的位置,並且把直線映射為直線,具有保線性質。與對極幾何不同的是,對極幾何將點映射到線上,而單應矩陣是點對點的關系。要注意的是單應矩陣的適用場景為:當場景中的特征點都落在同一平面上,比如牆、地面等,此時可用單應性估計運動。

 

  單應(透射變換)可以看成是仿射變換的拓展。仿射變換在圖形中的變換包括:平移、縮放、旋轉、斜切及它們的組合形式。這些變換的特點是:平行關系和線段的長度比例保持不變,即保持物體的平直性。而單應中也存在上述多種變換的組合形式,但是差別在於單應並不一定能保持平行關系和線段的長度比例不變。單應的特點是共面點成像,即單應變換是將某一塊共面的地方變換到另外一個地方,但是多數情況下都會徹底改變物體位置和形狀。

 

平面表示方法

 

  首先需要確定一個平面法向量為 $\mathbf{\vec{n}} = [n_{1}, n_{2}, n_{3}]^{T}$,但是確定法向量並不能唯一確定一個平面。我們會得到無數多的相互平行的平面。為了唯一確定一個平面,我們還需要一個點,若平面上有一個定點 $\mathbf{x} = [x_{1}, x_{2}, x_{3}]^{T}$, 那么我們即可確定一個平面。
    假設平面上任意一點為 $\mathbf{m} = \{x, y, z\}$,平面方程為
$$Ax + By + Cz + D = 0$$

 

由於法向量已知,則上述方程可以表示成:
$$\mathbf{\vec{n}^{T}} \mathbf{m} + D = 0$$

 

顯然上述的方程表示的是無數組平行的平面,確定 $D$ 即可確定唯一平面。則利用上述所說的平面上的任意動點 $x$,則有:
$$D = -\mathbf{\vec{n}^{T}}\mathbf{x} = -(n_{1}x_{1} + n_{2}x_{2} + n_{3}x_{3})$$

 

則平面的唯一表示方法為:
$$Ax + Bx + Cz = (n_{1}x_{1} + n_{2}x_{2} + n_{3}x_{3})$$

 

綜上,為了表示一個平面,我們需要一個法向量,以及一個平面上的點(目的是為了求偏置)。



單應矩陣

 

由上述可知平面的表示方法可以寫成:
$$\mathbf{\vec{n}}^{T}\mathbf{x} = d$$

 

參考 對極幾何及單應矩陣這篇文章,我們可以得到單應約束圖像:

 

 

 

假設左邊為第一個相機坐標系 $C_{1}$,右邊為第二個相機坐標系 $C_{2}$。並且平面 $\pi$ 在第一個相機坐標系的法向量為 $\mathbf{\vec{n}}$,$C_{2}$ 到平面 $\pi$ 的距離為 $d$。假設平面中任意一個點 $\mathbf{X}$ 在第一個相機坐標系中的表示為 $\mathbf{X_{1}}$,則平面 $\pi$ 的表示方法為:
$$\mathbf{\vec{n}}^{T} \mathbf{X_{1}} = d$$
 
顯然,上面的表示方法滿足我們前面介紹的平面表示方法的約束條件,即一個法向量以及平面內有一個已知點。接着我們將平面 $\pi$ 的表示方法改變一下:
$$\frac{1}{d}\mathbf{\vec{n}}^{T} \mathbf{X_{1}} = 1$$

 

假設平面 $\pi$ 中有一空間點 $X$,對應兩個相機的投影像素分別為 $\mathbf{p_{1}}, \mathbf{p_{2}}$,相機內參矩陣為 $\mathbf{K},$歸一化平面中的坐標系為 $\mathbf{x_{1}},\mathbf{{x_{2}}}$,並且滿足條件 $s_{1}\mathbf{x_{1}} = \mathbf{X_{1}}$,其中 $s_{1}$ 為 $X_{1}$ 的深度值。若已知兩個坐標系之間的相對變換為 $\mathbf{R}, \mathbf{t}$,表示從相機坐標系 $1$ 變換到相機坐標系 $2$,則有:
$$\mathbf{x_{1}} = \mathbf{K}^{-1}\mathbf{p_{1}}$$
$$\mathbf{x_{2}} = \mathbf{K}^{-1}\mathbf{p_{2}}$$
$$s_{2}\mathbf{x_{2}} = s_{1}\mathbf{R}\mathbf{x_{1}} + \mathbf{t}$$
$$s_{2}\mathbf{K}^{-1}\mathbf{p_{2}} = s_{1}\mathbf{R}\mathbf{K}^{-1}\mathbf{p_{1}} + \mathbf{t}$$
 
將平面 $\pi$ 的信息代入上述方程中得到:
$$s_{2}\mathbf{K}^{-1}\mathbf{p_{2}} = s_{1}\mathbf{R}\mathbf{K}^{-1}\mathbf{p_{1}} + \frac{s_{1}}{d}\mathbf{t}\mathbf{\vec{n}}^{T} \mathbf{K}^{-1} \mathbf{p_{1}} = s_{1}(\mathbf{R} + \frac{1}{d}\mathbf{t}\mathbf{\vec{n}}^{T})\mathbf{K}^{-1} \mathbf{p_{1}} $$

 

兩邊左乘相機內參矩陣:
$$s_{2}\mathbf{p_{2}} = s_{1} \mathbf{K}(\mathbf{R} + \frac{1}{d}\mathbf{t}\mathbf{\vec{n}}^{T})\mathbf{K}^{-1} \mathbf{p_{1}}$$
 
其中 $\mathbf{H} = \mathbf{K}(\mathbf{R} + \frac{1}{d}\mathbf{t}\mathbf{\vec{n}}^{T})\mathbf{K}^{-1}$ 稱為單應矩陣。再進一步簡化為:
$$\mathbf{p_{2}} = \frac{s_{1}}{s_{2}}\mathbf{H}\mathbf{p_{1}}$$
 
在上述的式子當中,我們發現除了單應約束以外,還有一個常系數 $\frac{s_{1}}{s_{2}}$。實際上該系數影響並不大,因為在實際求解當中,我們需要將得到的三個方程同時除以第三個方程,才能得到兩個有用的約束關系。(筆者以為:之所以需要這么做,是因為我們輸入的數據,均是歸一化的點,因此,在最終的結果上也應保持左右兩邊最后一維的數值應該為 $1$)。顯然,上述方程對於尺度的變化是不敏感的,因為沒有任何作用。
 
通過將約束條件 $\mathbf{p_{2}} = \mathbf{H}\mathbf{p_{1}}$ 展開,我們可以得到兩個方程。並且我們由上面的分析可以知道,單應矩陣 $\mathbf{H}$ 並非是有 $9$ 維自由度的矩陣,因為其對尺度不敏感。所以我們將單應矩陣最后一維置為 $1$。(或者可以強制單應矩陣所有參數的平方和為 $1$)最后我們需要求解的單應矩陣一共有 $8$ 個維度。而每一對匹配點可以提供兩個約束方程,那么我們至少需要四對匹配點才可以求解八個參數。在上一講的 對極約束中,我們求解的問題是一個齊次方程,而若是我們采用令單應矩陣最后一維為1的約束,我們需要求解的則是一個 $Ax = b$ 非齊次方程,不過求解方法仍是采用SVD分解來得到。若是我們想要的問題結構是一個齊次方程,則我們需要限制單應矩陣所有元素的平方和為1。

 

拾遺

 

  其實回顧上一講中的本質矩陣,再關聯一下基礎矩陣。我們可以知道這兩個矩陣之間相差的只是相機內參矩陣。而上述的單應矩陣其實也可以有兩種解法。一種是如上的解法,也就是將相機內參矩陣融入問題結構中,與相機位姿一起求解,最后再分解出來,這種方法類對極約束中的基礎矩陣的求法。另外一種就是去除相機內參,但是輸入參數需要是歸一化平面上的點,也就是說我們在第一步就將相機內參用了,無需再用它,那么求解單應矩陣的時候相應的就不需要求解相機內參了,這種方法類對極約束中的本質矩陣的求法。
 
   由於OpenCV提供的求解函數是基於像素點的,因此單應矩陣中包含相機內參和相對位姿。為了能夠和代碼對得上,筆者就將內容修改為如上的內容。代碼可以參考我的 github

 

參考材料
 
 
 
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM