相機成像的過程實際是將真實的三維空間中的三維點映射到成像平面(二維空間)過程,可以簡單的使用小孔成像模型來描述該過程,以了解成像過程中三維空間到二位圖像空間的變換過程。
本文包含兩部分內容,首先介紹小孔成像模型的各種幾何關系;接着描述了成像過程中的四種坐標系(像素坐標,圖像坐標,相機坐標,世界坐標)的變換關系。
小孔成像模型
相機可以抽象為最簡單的形式:一個小孔和一個成像平面,小孔位於成像平面和真實的三維場景之間,任何來自真實世界的光只有通過小孔才能到達成像平面。因此,在成像平面和通過小孔看到的真實三維場景存在着一種對應關系,也就是圖像中的二維像點和真實三維世界的三維點存在某種變換關系。找到了這種變換關系,就可以利用圖像中的二維點信息來恢復場景的三維信息。
下圖是小孔成像的模型,為了簡化模型,將成像平面放在了小孔的前面,並且成的像也是正立的

在描述小孔的成像過程前,首先來定義兩個坐標系:
- 相機坐標系(三維坐標系)
相機的中心被稱為焦點或者光心,以焦點\(O_c\)為原點和坐標軸\(X_c,Y_c,Z_c\)組成了相機坐標系
- 圖像坐標系(二維坐標系)
成像平面中,以成像平面的中心\(O'\)為原點和坐標軸\(x',y'\)組成了圖像坐標系。
小孔成像實際就是將相機坐標系中的三維點變換到成像平面中的圖像坐標系中的二維點。
假設,三維空間中點\(P\),其在相機坐標系中的坐標是\(P_c=[X,Y,Z]^T\);其像點\(p\),在圖像坐標系的中的坐標是\(p=[x,y]^T\),由於光軸垂直與成像平面,那么可以知道像點\(p\)在相機坐標系中的坐標是\(p=[x,y,z]^T,其中z =f(f是焦點到成像平面之間的距離,被稱為焦距)\)。

由上圖根據三角形的相似關系,可以得到如下公式:
\[\frac{Z}{f}=\frac{X}{x}=\frac{Y}{y} \]
將上面公式整理后可以得到:
\[\left\{ \begin{array}{l} x = f\frac{X}{Z} \\ y = f\frac{Y}{Z} \\ z = f \end{array} \right. \]
上面的公式就是小孔相機模型的基礎公式了,有了此公式可以推導出更詳細的小孔相機模型的參數:
在推導相機的內參數和外參數前,需要先了解下齊次坐標的概念。
齊次坐標
相機的成像過程實際是將三維空間的點\(P=(X,Y,Z)\)變換到成像平面的過程,這個過程也可以被稱為射影變換(更多關於射影變換的內容可參考《計算機視覺中的多視圖幾何》)。如上面描述的,設射影變換的中心\(O\)作為相機坐標系的原點,該點到成像平面的距離為\(f\),\(P\)在成像平面的投影點為\(p=(x,y)\),根據相似三角形原理,可以得到公式:
\[\left\{ \begin{array}{l} x = f\frac{X}{Z} \\ y = f\frac{Y}{Z} \\ z = f \end{array} \right. \]
上面的公式就描述了三位空間到二維平面的映射,但是該映射對於坐標\(Z\)來說卻是非線性(作為分母),通過上面的公式方便的統一處理\(X,Y,Z\)這三個坐標軸的數據。就需要引入新的坐標(擴展坐標的維度)將其線性化,如下:
\[\left[\begin{array}{c}x\\y\end{array}\right] \Leftrightarrow \left[\begin{array}{c}\hat{x}\\\hat{y}\\\hat{z}\end{array}\right] = \left[\begin{array}{ccc}f&0&0&0\\0&f&0&0\\0&0&1&0\end{array}\right] \left[\begin{array}{c}X\\Y\\Z\\1\end{array}\right] \]
這樣,可以使用矩陣的乘法統一的處理\(X,Y,Z\)這三個坐標。
坐標\((\hat{x},\hat{y},\hat{z})\)就是像點\(p=(x,y)\)的齊次坐標,其中
\[\left\{\begin{array}{l}x=\frac{\hat{x}}{\hat{z}}\\y=\frac{\hat{y}}{\hat{z}} \\z\ne0\end{array}\right. \]
通過上面的公式可以很容易的推導出,怎么通過擴展坐標維度構建齊次坐標。具體步驟就是將x和y同時除以一個不為0的z,並且將z作為其添加維度的坐標,通常可以選擇\(z=1\)。
這就可以發現其次坐標的一個重要性質,齊次坐標縮放一個常量因子是不變:
\[s(a,b,c)^T=(sa,sb,sc)^T \]
內參數
相機的內參數由下面的兩部分組成:
- 射影變換本身的參數,相機的焦點到成像平面的距離,也就是焦距\(f\)。
- 從成像平面坐標系到像素坐標系的變換。上面推導中使用的像點坐標\(p=(x,y)\)是成像平面坐標系下,以成像平面的中心為原點。而實際像素點的表示方法是以像素來描述,坐標原點通常是圖像的左上角,X軸沿着水平方向向左,Y軸豎直向下。像素是一個矩形塊,這里假設其在水平和豎直方向的長度分別為:\(\alpha\)和\(\beta\)。所以像素坐標和成像平面坐標之間,相差了一個縮放和原點的平移。
假設像素坐標的水平方向的軸為\(\mu\),豎直方向的軸為\(\nu\),那么將一個成像平面的坐標\((x,y)\)在水平方向上縮放\(\alpha\)倍,在豎直方向上縮放\(\beta\)倍,同時平移\((c_x,c_y)\),就可以得到像素坐標系的坐標\((\mu,\nu)\),其公式如下:
\[\begin{array}{c} u = \alpha\cdot x+ c_x \\ v = \beta \cdot y + c_y \end{array} \]
將上面求得的\((x,y)\)帶入上面公式可得到:
\[\left\{\begin{array}{c} u = \alpha\cdot f\frac{X}{Z}+ c_x \\ v = \beta \cdot f\frac{Y}{Z} + c_y \end{array}\right. \Rightarrow \left\{\begin{array}{c} u = f_x\frac{X}{Z}+ c_x \\ v = f_y\frac{Y}{Z} + c_y \end{array}\right. 其中,f_x = \alpha \cdot f,f_y = \beta \cdot f \]
將上面的公式寫為齊次坐標的形式:
\[\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \frac{1}{Z}\left[ \begin{array}{ccc}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{array}\right]\left[\begin{array}{c}X\\Y\\Z\end{array}\right] \]
上面提到對於齊次坐標,縮放一個常量因子仍然是相等的,將\(Z\)挪到左邊
\[\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right]=Z\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] =\left[ \begin{array}{ccc}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{array}\right]\left[\begin{array}{c}X\\Y\\Z\end{array}\right] \]
通過上面的的推導,就得到了相機的內參數矩陣(Camera Intrinsics)K,
\[K=\left[ \begin{array}{ccc}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{array}\right] \]
K有4個未知數和相機的構造相關,\(f_x,f_y\)和相機的焦距,像素的大小有關;\(c_x,c_y\)是平移的距離,和相機成像平面的大小有關。
求解相機內參數的過程被稱為標定,在SLAM中可以假定相機的內參是已知的,而在三維重建中內參數則是未知的,需要手動的標定(比如使用標定板),也有自標定的方法,不過精度較低。
外參數
通過上面的推導,知道了相機成像的過程
\[p = KP \]
其中,\(p\)是圖像中像點的像素坐標,\(K\)是相機的內參數矩陣,\(P\)是相機坐標系下的三維點坐標。
上面推導使用的三維點坐標是在相機坐標系下的,相機坐標系並不是一個“穩定”的坐標系,其會隨着相機的移動而改變坐標的原點和各個坐標軸的方向,用該坐標系下坐標進行計算,顯然不是一個明智的選擇。需要引進一個穩定不變坐標系:世界坐標系,該坐標系是絕對不變,SLAM中的視覺里程計就是求解相機在世界坐標系下的運動軌跡。
設\(P_c\)是\(P\)在相機坐標系坐標,\(P_w\)是其在世界坐標系下的坐標,可以使用一個旋轉矩陣\(R\)和一個平移向量\(t\),將\(P_c\)變換為\(P_w\)
\[P_c = RP_w + t \]
其中,\(R\)是一個\(3\times3\)的旋轉矩陣,\(t\)是\(3\times1\)的平移向量,上面運算的過程還需要做加法運算,為了方便計算,現將其改寫為齊次坐標的形式
\[\left[\begin{array}{c}X_c\\Y_c\\Z_c\end{array}\right] = \left[\begin{array}{ccc}R_{11}&R_{12}&R_{13}\\R_{21}&R_{22}&R_{23}\\R_{31}&R_{32}&R_{33}\end{array}\right]\left[\begin{array}{c}X_w\\Y_w\\Z_w\end{array}\right] + \left[\begin{array}{c}t_1\\t_2\\t_3\end{array}\right] \]
其齊次坐標的形式
\[\left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right] = \left[\begin{array}{ccc}R_{11}&R_{12}&R_{13}&t_1\\R_{21}&R_{22}&R_{23}&t_2\\R_{31}&R_{32}&R_{33}&t_3\\0&0&0&1\end{array}\right]\left[\begin{array}{c}X_w\\Y_w\\Z_w\\1\end{array}\right] \]
將旋轉矩陣\(R\)和平移向量\(t\)帶入
\[\left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right] = \left[\begin{array}{cc}R&t\\0^T&1\end{array}\right]\left[\begin{array}{c}X_w\\Y_w\\Z_w\\1\end{array}\right] \]
上面就推導得到相機的外參數(Camera Extrinsics)T
\[T = \left[\begin{array}{cc}R&t\\0^T&1\end{array}\right] \]
其中,\(R\)是旋轉矩陣,\(t\)是平移向量.
內外參數組合到一起
\(p=(\mu,\nu)\)是圖像中的像點,其坐標系是像素坐標系;\(P_c=(X_c,Y_c,Z_c)\)是場景中的三維店,其坐標系是相機坐標系
\[\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \left[ \begin{array}{ccc}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{array}\right]\left[\begin{array}{c}X_c\\Y_c\\Z_c\end{array}\right] \]
為了能夠和外參數聯合,需要將上式齊次化
\[\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \left[ \begin{array}{ccc}f_x&0&c_x&0\\0&f_y&c_y&0\\0&0&1&0\end{array}\right]\left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right] \]
這里使用的三維點坐標\(P_c\)是相機坐標系下的,帶入外參數,將其該坐標變換為世界坐標系\(P_w=(X_w,Y_w,Z_w)\)
\[\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \left[ \begin{array}{ccc}f_x&0&c_x&0\\0&f_y&c_y&0\\0&0&1&0\end{array}\right]\left[\begin{array}{cc}R&t\\0^T&1\end{array}\right]\left[\begin{array}{c}X_W\\Y_W\\Z_W\\1\end{array}\right] \]
可以將內外參數組合到一起稱為相機矩陣,其作用是將真實場景中的三維點投影到二維的成像平面。
總結
本文總結了將場景中的三維點投影到二維成像平面變為像點的過程,下面對本文再作個總結。
設有一像點\(p=(x,y)\)其對應的場景中的三維點為\(P_c=(X_c,Y_c,Z_c)\),成像平面距離相機中心的距離為\(f\),依據小孔成像的原理,得到下面的變換公式
\[\left[\begin{array}{c}x\\y\\1\end{array}\right] = \left[\begin{array}{ccc}f&0&0&0\\0&f&0&0\\0&0&1&0\end{array}\right] \left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right] \]
上式左邊的像點坐標是成像平面坐標系下的坐標,需要將其變換到像素坐標系下。成像平面坐標系和像素坐標系間相差一個縮放和一個原點的平移
\[\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \left[\begin{array}{ccc}\frac{1}{dx}&0&c_x\\0&\frac{1}{dy}&c_y\\0&0&1\end{array}\right] \left[\begin{array}{ccc}f&0&0&0\\0&f&0&0\\0&0&1&0\end{array}\right] \left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right] \]
其中,\(dx,dy\)為一個像素的長和高,在前面的描述中使用\(\alpha = \frac{1}{dx},\beta=\frac{1}{dy}\)表示;\(c_x,c_y\)表示原點的平移量。
在上式的右邊三維點的坐標\(P_c\)使用的是相機坐標系,而相機位置卻不是固定不變的,需要將其變換到世界坐標系下;從相機坐標系變換到世界坐標系下需要一個旋轉和平移
\[\left[\begin{array}{c}\mu\\\nu\\1\end{array}\right] = \left[\begin{array}{ccc}\frac{1}{dx}&0&c_x\\0&\frac{1}{dy}&c_y\\0&0&1\end{array}\right] \left[\begin{array}{ccc}f&0&0&0\\0&f&0&0\\0&0&1&0\end{array}\right] \left[\begin{array}{cc}R&t\\0^T&1\end{array}\right] \left[\begin{array}{c}X_c\\Y_c\\Z_c\\1\end{array}\right] \]
一個相機矩陣就由上面三個矩陣組成。
終於完了,寫之前沒想到會寫這么多...