天天看點

張正友标定法(相機标定)

這篇部落格不會詳細介紹張正友相機标定算法的計算過程,是以隻是想怎麼用openCV或者Matlab實作相機标定的朋友就不用費時間去看了。這篇部落格介紹我對張氏标定算法的了解。因為我看到很多資料,覺得很多人對這個算法的了解有問題。雖然我沒有用程式實作,但從數學的角度上還是可以分析出來的。

首先推薦一篇部落格張正友标定法。這篇博文是我找到的講解最為詳細的,但當中有些論點我仍然覺得有問題。大家可以先看這一篇,了解差不多了在看看我說的是不是有道理。

1.提取多少個角點可以求解方程

2.極大似然估計怎麼應用

3.畸變糾正

提取多少個角點可以求解方程

首先我們看一眼要求解的方程

\(s\begin{bmatrix}u\\ v\\ 1\end{bmatrix} = \begin{bmatrix}h_{11} & h_{12} & h_{13}\\ h_{21} & h_{22} & h_{23}\\ h_{31} & h_{32} & h_{33}\end{bmatrix}\begin{bmatrix}X\\ Y\\ 1\end{bmatrix}=H\begin{bmatrix}X\\ Y\\ 1\end{bmatrix}\)

式中:

\(H=A\begin{bmatrix}R & t\end{bmatrix}=\begin{bmatrix}\alpha & \gamma & u_0\\ 0 & \beta & v_0\\ 0 & 0 & 1\end{bmatrix}\begin{bmatrix}r_1 & r_2 & r_3 & t\end{bmatrix}\)

由于,現實坐标是在棋盤闆上建立的,預設找到的所有角點,其Z軸坐标都為0,是以省去了一列r3。我們對後一個矩陣繼續展開:

\(\begin{bmatrix}r_1 & r_2 & r_3 & t\end{bmatrix}=\begin{bmatrix}r_{11} & r_{12} & r_{13} & t_1\\ r_{21} & r_{22} & r_{23} & t_2\\ r_{31} & r_{32} & r_{33} & t_3\end{bmatrix}\)

我首先說明這個R矩陣是三個分别表示繞x軸,y軸,z軸旋轉的機關正交陣相乘的結果,是以每一個列向量和三個旋轉方向都是相關的。而不是像别人說,r1與x軸相關,r2與y周相關,r3與z軸相關。由于機關正交陣乘積的結果還是機關正交陣,是以r1,r2,r3是互相正交的機關向量。

注意R和t一共有12個量值,但是R隻和三個旋轉角度相關,t代表三個方向的偏移量,是以實際上隻有6個未知量。而A陣中有5個未知量(如果不考慮x軸與y軸的影響,可以不考慮\(\gamma\)),加起來一共有11個未知量。但最後簡化成H陣隻有9個變量(雖然删除了r3,但三個旋轉角度仍然存在于r1與r2中)。我們還要注意,我麼對單眼相機标定的目标不是找到現實世界的坐标和相機像素坐标的關系,準确來講是要擷取相機的内參數。是以我們對棋盤闆的位置并不關心。例如我現在有兩個大小不同的棋盤版,大的相對小的放的遠一點,但保證在相片的中像素坐标是相同的。那麼這兩個棋盤版計算出來的兩個H陣是不同的(棋盤版位置不同),但是是成比例的!這說明H的比例變化是不影響相機的内參數計算的,那麼我們幹脆将H中的一個變量設定為常數“1”,這樣H陣的結果就是唯一的了。此時,這種比例變化就由變量s來平衡,使得方程成立。

我們不妨假定\(h_{33}=1\)。現在隻剩下8個變量。其它人都說一個點提供兩個方程,是以找4個點就可以了。但是想想就知道,一個平面隻有兩個線性無關向量,怎麼可能提供4個獨立無關的點,理論上不是隻能提供兩個點嗎?如果認為隻能提供兩個點,那麼一定忽略的常數項。注意方程:

\(s\begin{bmatrix}u\\ v\\ 1\end{bmatrix} = \begin{bmatrix}h_{11} & h_{12} & h_{13}\\ h_{21} & h_{22} & h_{23}\\ h_{31} & h_{32} & h_{33}\end{bmatrix}\begin{bmatrix}X\\ Y\\ 1\end{bmatrix}=H\begin{bmatrix}X\\ Y\\ 1\end{bmatrix}\)

最後一項是1,而不是0!是以一個平面的基底[1,0]和[0,1],帶入方程就變成了[1,0,1]和[0,1,1],這兩個向量不能線性表示[0,0,1]。是以實際上一個平面可以提供三個線性無關的點。我們還要注意一個點提供的方程數量是三個,而不是兩個(我也不知道别人是怎麼得出一個點兩個方程的結論)。這樣我們從一個棋盤版得到了9個線性無關的方程。可是未知量有8個,方程有9個,不是過限制了?注意,一個棋盤版得到H陣既和内參數相關也和自身位置相關,是以H陣是唯一的!隻不過我們知道了H陣的比例變化不影響内參數,才在解出H之後對其做比例變化的。是以實際求解中,忽略s,求解H中的9個參數,再添加s,調整使得\(h_{33}=1\)。

我們求解了H矩陣,得到了9個量值,但是未知量有11個,是以還是不能直接解出内參數矩陣。至于解法,我推薦博文中算法,沒有什麼問題。

如果我們得到了相機的内參數,那麼在以後的坐标轉換的問題中就隻剩下6個未知量(三個旋轉角度和三個平移距離)。邏輯上隻需要提供兩個點就可以求解這個矩陣。那麼是不是以後我們隻要輸入兩個特征點就可以找到坐标轉換函數?如果你這樣認為,那麼你就被我騙了。隻要想想就知道,僅憑兩個點是不可能确定一個空間坐标系。既然連世界坐标系都确定不了,怎麼可能得到坐标轉換方程。

并不是我存心要耍你,我隻是推理到這一步時才發覺之前的了解有問題。我們所謂的坐标系轉換,不是将世界坐标系移動到相機坐标系上,使得兩個坐标系重合。如果真能這樣,那麼深度資訊毫無疑問能得到,你都可以移動過來,自然知道兩者的距離了。但是這個坐标變換與深度資訊毫無關系。這種坐标變換的實質是調整一個坐标系,使得其中元素的表示與元素在另一個坐标系中對應的元素的坐标表示相同。舉個例子,現在有坐标系A(相機坐标系)和坐标系B(世界坐标系),我們所做的所有變換是對坐标系B進行平移,旋轉,伸縮,使得世界坐标系中的物體在B中坐标表示和對應在相片中的物體在相機中的坐标(由于沒有Z,預設兩個坐标的Z是相同的),兩者的數值相同。由于變換的前後改變的隻是坐标系B,而坐标系A和坐标系B的位置關系從頭到尾都沒有涉及。

其實說到這裡,你應該能想到為什麼用兩個點的對應關系能确定轉換矩陣。答案自然是我們少考慮了一些變量——代表三個坐标軸伸縮變換的量

\(K=\begin{bmatrix}k_1\\ k_2\\ k_3\end{bmatrix}\)

如果我們僅用兩個點,我們能夠确定的是将這兩個點對應的直線變換到所對應的直線,實際隻需要兩個旋轉,兩個伸縮,兩個移動就可以了,是以也剛好有6個獨立的方程。但對于完整的坐标變化,我們依然需要9個變量全部知道才可以,也就是我們還是需要知道三個點。

那麼之前的推理是否存在問題?我們把伸縮變換添加到方程中:

\(H=KA\begin{bmatrix}R & t\end{bmatrix}=\begin{bmatrix}k_1\\ k_2\\ k_3\end{bmatrix}\begin{bmatrix}\alpha & \gamma & u_0\\ 0 & \beta & v_0\\ 0 & 0 & 1\end{bmatrix}\begin{bmatrix}r_1 & r_2 & r_3 & t\end{bmatrix}\)

我們注意到雖然添加了但H還是9個量,是以對H的求解不影響。至于對相機内參數的求解,你推一下就知道,兩個限制方程中也不會出現與K相關的變量,是以A的求解也沒有問題。綜上,之前的推理不受伸縮變換的影響!但是在坐标系變換的确定中,伸縮變換還是有影響的!是以即使知道了相機的内參數,我們還是需要知道三個點的對應關系才可以求解出轉換矩陣!

2018/3/8更新:

之後再仔細想想,發現自己的想法還是有問題。之前說坐标變換與兩個坐标系沒有關系,隻是考慮元素在坐标系中的變換隻是一個數學運算,沒有考慮實體意義。但如果在兩個坐标系中表示的元素是同一個呢?在空間中固定三個點,如果這三個點在兩個坐标系中的表示是一樣的,說明什麼?說明這兩個坐标系是完全重合的!同理應用到相機标定,如果得到外參數,可以由世界坐标轉到相機坐标下的。證明世界坐标經過變換與相機坐标重疊了。說明這個變換可以把世界坐标轉移到相機坐标。而且在世界坐标系中我們應用的長度機關和在相機坐标系中應用的長度機關是相同的,說明坐标系是不需要伸縮變換。那麼未知量隻有三個旋轉角度和三個平移距離,共六個變量,那麼得到兩個點可以求解了嗎?不能!

之前我談到過方程中s的含義,我了解這是一個比例系數。如果我們修改方程:

\(s\begin{bmatrix}u\\ v\\ 1\end{bmatrix} =z\'\begin{bmatrix} \frac{u\'}{z\'}\\ \frac{v\'}{z\'}\\1\end{bmatrix}= \begin{bmatrix}h_{11} & h_{12} & h_{13}\\ h_{21} & h_{22} & h_{23}\\ h_{31} & h_{32} & h_{33}\end{bmatrix}\begin{bmatrix}X\\ Y\\ 1\end{bmatrix}=H\begin{bmatrix}X\\ Y\\ 1\end{bmatrix}\)

當中u\',v\',z\'是相機坐标下的坐标,那麼z\'的含義就是z向距離,也就是深度資訊。由于對圖檔沒有深度資訊,最終\(u=\frac{u\'}{z\'}\) \(v=\frac{v\'}{z\'}\)。那麼對于每一個點的z‘都是不一樣的,是以現在有了三個新的變量。是以其實方程實際有三個變量,一個點可以提供三個方程,求解坐标變換矩陣需要三個點。

極大似然估計

我們對一個棋盤闆可以得到多個點,但是在求解的過程中我們隻會用到三個點。那麼選擇哪三個點?很簡單,周遊所有線性無關的三個點的組合,求解對應的H,并用這個H檢驗其它點的對應關系是否準确,根據誤差計算公式

\(\sum_{n}^{i=1}\sum_{m}^{j=1}\left \| m_{ij}-\hat{m}(H,M_{ij}) \right \|\)

選擇誤差最小的一組點。

畸變糾正

我對畸變糾正的算法有一個問題。因為畸變在一開始就是存在的,但是在計算坐标轉換時預設是不考慮的。那麼我們計算的坐标轉換就是不準确的,怎麼可以應用到畸變糾正中,并期望得到正确的結果?實際這就是一個雞生蛋還是蛋生雞的問題。對于這種問題常用的求解算法就是疊代求解。我們可以選取視覺中心的三個點求解H,盡可能減少畸變的影響,再去求解畸變參數。有了畸變參數再去糾正圖像,再去計算轉換矩陣H,反複幾次應該就可以減小誤差。實際上在最大似然估計的過程中,大機率選擇的三個點就是中心的三個點。