Matlab標定工具箱使用教程

Matlab標定工具箱使用教程

這個教程將帶你完整地利用20到25張平面棋盤格圖像進行相機標定。
這個教程將讓你學會如何使用所有工具箱的特徵:載入圖像、提取圖像角點、運行標定引擎、顯示結果、控制精度
添加和刪減圖像、圖像矯正、導出標定不同格式的數據...這個教程對於剛開始使用工具箱的人來說非常重要。

首先下載Matlab標定工具箱:
[http://www.vision.caltech.edu/bouguetj/calib_doc/download/index.html]
(http://www.vision.caltech.edu/bouguetj/calib_doc/download/index.html)

將其解壓到Matlab的工作目錄下,然後將其包含到matlab的工作路徑下。
運行calib_gui就可以打開matlab標定工具箱主界面:

1、將標定用的圖像單獨存放於calib_example文件夾中。
2、在matlab中,進入到calib_example文件夾中。

3、讀取圖像:

    點擊標定工具窗口中的“Image names”按鈕。輸入標定圖像的基名和圖像的格式(例如標定圖像的名稱分別是
    Img1.jpg,Img2.jpg,Img3.jpg...基名就是Img 圖像格式就是jpg)
    然後所有的標定圖像都將加載進來,其對應的變量名分別是I_1,I_2,...圖像數量對應的變量是n_ima。
    載入完圖像之後的圖像如下:

之後載入的圖像將以縮略圖的形式顯示出來:

一些圖像內存不足的問題在此就不作詳細的介紹了,現在一般的電腦RAM都是足夠來做標定的。

4、提取角點:
點擊標定工具箱上的“Extract grid corners”按鈕。在matlab命令行會出現如下提示信息:

直接按“Enter”(沒有參數)選擇所有的圖像,否則就需要輸入圖像索引如[2 5 8 10 12]來提取這些圖像中的
角點。然後通過直接輸入“Enter”來選擇默認的角點尋找窗口尺寸:wintx=winty=5。這就產生了一個11X11個像素
有效的窗口尺寸:

角點提取引擎有一個對網格中的方格個數進行計數的自動機制。這個工具尤其對於圖像數量大的時候非常便利,因爲
用戶不需要手工地輸入X和Y方向方格的數量。然而對於極少數場合,這個工具可能不能得到正確的方格數量,這種情況
只有當鏡頭有很大的畸變。在這種情況下,角點提取這個過程,工具箱提供了一個可選項可供用戶關閉自動計數方格。
在這個特殊的模式下,使用者優先對每張圖像使用方格自動計數功能,因此,直接按“Enter”鍵默認。(通常情況
下都使用默認形式,然後如果確實有需要,再重新處理幾張有問題的圖像。)

然後第一張標定圖像就會顯示出來:

然後點擊長方形棋盤格的四個邊角點。選擇的位置在下圖中顯示出來(注意:儘量精確地點擊這四個角點,控制
在實際角點的5個像素範圍內,否則一些角點可能會被檢測器丟失掉)

點擊的順序規則:第一個點被用來作爲棋盤格座標系的原點。其他三個點可以以任何順序點擊。第一個點擊的的點
非常重要,尤其是對於多相機的情況(例如當計算幾個相機在空間之間的相互關係的時候)。當處理多相機系統時
對於不同的相機標定圖像需要總是選擇同一個棋盤格座標系。三維標定可以運行stereo_gui.m.

第一個點的選擇非常重要,一定要注意

經過上面的步驟之後,標定棋盤的邊界就顯示出來了:

輸入網格中每個方格在X和Y方向上的尺寸dX和dY(在這裏,dX=dY=30mm=default values):

注意:你可以直接輸入“Enter”直接用默認參數,程序會自動對各個方向的方格數進行計數,然後在顯示出沒有
畸變的預估角點。

如果預估的角點很接近實際的圖像角點,則下面的步驟就可以略過了(如果沒有那麼大的圖像畸變)。在現在的
圖像中:預估的角點足夠接近實際的圖像角點。因此,沒有必要通過輸入一個猜測的徑向畸變係數去幫助軟件去
檢測圖像角點。直接輸入“Enter”,會使用這些初始的預估角點作爲提取的角點:

然後圖像角點就被自動地提取出來了,然後顯示出來,如下圖所示:

角點以大約0.1個像素的精度被提取出來。
對第2、3、4...圖像採用上述同樣的步驟。如下圖是將圖像2、3、4..圖像的角點提取出來:

從上面觀察到方格尺寸dX、dY總是被保持在它們的初始值(30mm).

有時,預估的角點不是那麼足夠地接近實際圖像角點,在這種情況下,就有必要通過輸入一個鏡頭畸變係數來調整
預估角點。第15張圖像就是這種情況,在這張圖像中,預估角點的圖像如下圖所示:

可以看到一些預估角點和實際圖像的角點的差距很大,這樣就會導致錯誤的角點提取。而這產生的原因就是因爲
圖像畸變。爲了幫助系統更好地判斷角點的位置,用戶可以手動地輸入一個鏡頭畸變係數Kc.爲了輸入鏡頭畸變
係數,我們需要在那個問題“Need of an initial guess for distortion?”這裏輸入一個非空參數,這裏
我們輸入畸變係數Kc=-0.3(一般這個係數在-1到1之間)。如下圖所示:

根據這個畸變係數,新的預估角點位置如下圖所示:

如果新的預估角點足夠接近實際的圖像角點(如上圖所示),則輸入任何不爲空的字符(如1)作爲問題“Satisfied
with distortion?”的回答。然後亞像素角點的位置就會使用新的帶有圖像畸變的預估位置進行計算。

如果我們還不滿意,我們可以輸入一個空的字符串作爲問題"Satisfied with distortion?"(直接輸入“Enter”)
然後嘗試一個新的畸變係數Kc。你可能會重複很多次這樣的過程直到對結果滿意爲止。

注意:上面用到的畸變的值僅僅是用來幫助提取角點,其不會影響下面主要的標定過程。換句話說,這裏的畸變係數並不會作爲最終的畸變結果,也不會用於優化畸變係數的初始值

最後檢測到的角點如下圖所示:

對剩下的幾張圖片重複上述過程(圖片16-20).然而對這些圖像,不要使用預先的畸變係數這個選項,儘管提取的
角點不是很正確。在下面的步驟中,我們將糾正它們(在這個例子中,我們不會使用畸變係數這個選項用於圖像15
但是這樣對於我們證明很有用)。

在角點提取之後,就會自動產生一個calib_data.mat的matlab數據文件。這個文件包含了整個角點提取過程中
的所有信息(圖像座標,對應的3D網格座標,網格尺寸....)。這個文件是爲了防止matlab突然崩潰而創立的。
載入這個文件可以避免你又重複一遍上面的過程。

在你自己標定的過程中,當圖像中有大的畸變的時候,這個程序可能不能夠在網格中自動對方格進行計數,在這種
情況下,X和Y方向的方格數量必須手動輸入。這在這個例子中沒有出現這種情況。

在你自己做標定的時候,還有一種情況會出現。如果鏡頭畸變非常嚴重(像魚眼鏡頭),這個基於單個畸變係數的
簡化的指導工具對角點的初始預估可能就不夠用。
對於這幾種麻煩的情況,在工具箱中的一個腳本程序支持完全手動的角點提取(例如每次點擊一個角點)。腳本文
件叫做“manual_corner_exteaction.m”(在內存優化模式下,你可以使用"manual_corner_
extraction_no_read.m"),並且應該在傳統的角點提取代碼運行之後才能執行這個代碼。(因爲它基於傳統的
角點提取的一些數據)。

顯然,這種角點提取的方法當圖像數量多的時候是非常耗時的。因爲它作爲當前面的嘗試都失敗的情況下的一種
救命稻草。但完全可以不用太擔心這個,在這個例子中不會出現這種情況。

主要的標定步驟:

在角點提取完之後,就可以單擊標定工具箱面板上的“Calibration”來運行主要的相機標定程序。

標定主要通過兩個步驟來完成:初次初始化以及非線性優化。
初始化步驟中對標定參數進行閉環計算,這個過程不包括任何鏡頭畸變(程序名:init_calib_param.m)
非線性優化過程中將對所有的標定參數最小化總體映射誤差(從最小二乘的角度出發)(9個內參以及6X20=129、
個外參)。優化是對特定雅可比矩陣進行計算然後往梯度下降的方向進行的。

標定參數存儲在一系列變量中。注意切向畸變係數和第6個徑向畸變係數沒有沒有被估算(這是默認的模式)。因此
在像素座標中X和Y之間是90°。在大多數實際情況中,這是一個很理想化的設想。然而,接下來,將會講述一種介紹
在優化中切向畸變alpha_c的方法。

從上圖中我們可以注意到:爲了達到最小值,只用了11次梯度迭代。這就意味着只有11次對映射函數、雅可比計算
以及求逆的評估。快速收斂的一個原因就是初始化程序所要計算的參數的有一個好的初始預估值。
現在,忽略推薦的可以減少畸變的模型的系統。對一個模型的複雜性進行判斷的映射誤差仍然很大。這主要是因爲
對於一些圖像一些網格角點並沒有被精確地提取。

單擊面板上的“Reproject on images”來將網格角點映射到原始圖像中。這些映射是基於當前的內參和外參計算
出來的。輸入一個空字符(直接按"Enter")作爲“Number(s) of image(s) to show([]=all images)”來
表示你想查看所有圖像:

下面的圖像顯示了最初的四張檢測到的角點的圖像(紅色的叉)以及映射的網格角點(圓)。

映射誤差也以有顏色的叉叉顯示在圖中:

爲了退出誤差分析工具,在圖像上的任何位置右擊(稍後你將會理解這個選項的使用)。

在面板中單擊“Show Extrinsic”。外參(棋盤格相對於相機的相對位置)就以3D的形式顯示出來了:

在上圖中,座標系(Oc,Xc,Yc,Zc)是相機的參考座標系。紅色的金字塔狀的就是由圖像平面定義的相機的有效
視場。可以在相機座標系視角或者世界座標系視角之間切換:

在這個視角里面,每個相機的位姿都用綠色的金字塔表示。

現在我們回到前面的誤差分析那一段,注意到在很多圖像中的投影誤差是非常大的。原因就是我們在一些高度畸變
的圖像的角點提取工作做得不到位。然而,我們現在可以通過對所有圖像重新計算圖像角點來進行矯正。接下來需要
做的就是:單擊面板中的“Recomp. corners”按鈕,然後再次選擇角點檢測器的窗口尺寸(wintx=winty=5這個
默認值)。

對於最後問題“Number(s) of image(s) to process”亦然輸入“Enter”選擇默認值去重新計算所有圖像中的
角點。然後就是選擇角點提取的方式:自動和手動,自動的就是使用重新投影的網格作爲角點的初始預估位置。手
動的方式就需要使用者手動的提取角點。在現在這樣的條件下,因爲重投影的網格點非常接近實際的圖像角點,因此
我們選擇自動的方式:直接“Enter”輸入默認值。所有圖像的角點就會被重新計算。你的matlab命令行窗口就會出
現下面這種形式:

然後通過單擊“Calibration”進行一次標定優化:

可以注意到只需要6次迭代就收斂了,並且沒有進行初始化過程(因爲優化是在前面標定的結果之上進行的)。上圖
中的兩個值0.12668和0.12604分別是X和Y方向像素上投影的標準差。注意到標定參數的不確定性也進行了估算。
數值大概是標準差的3倍。

優化之後,單擊“Save”保存標定結果(內參和外參)到matlab文件“Calib_Results.mat”

我們再次單擊“Reproject on images”將網格點投影到原始圖像中。前四張圖像如下圖所示:

然後再“Analyse error”看看新的投影誤差(可以看到誤差比之前更小了):

右擊上面的誤差圖像(退出誤差分析工具),單擊“Show Extrinsic”看看棋盤格相對於相機的3D位置關係:

工具“Analyse error”允許你去檢查哪個點對應大的誤差。單擊“Analyse error”並且選擇圖像由上角的那個點

單擊選中之後,下面的信息就會出現在命令行窗口:

這就意味着對應的點在第18張圖像中,在標定板網格座標的(0,0)的位置(標定板的原點)。下圖是此點到原始
圖像的距離。

誤差檢查工具對於在一張或多張圖像中角點提取失敗的情況下非常有用。在這種情況下,使用者可以使用不同的窗
口尺寸去重新對於特定圖像的角度進行重新計算。

例如,我們使用窗口尺寸(wintx=winty=9)來對所有圖像的角點進行計算,但對圖像20我們使用(wintx=winty
=5)的窗口尺寸,對圖像5,7,8,19我們採用(wintx=winty=7),圖像18採用(wintx=winty=8)的窗口
尺寸進行計算。角點的提取會調用三次“Recomp.corners”。第一次調用使用wintx=winty=9來處理圖像1,2,
3,4,6,9,10,11,12,13,14,15,16和17.然後選擇自動模式:

第二次調用,使用wintx=winty=8來處理圖像18,然後再次選擇自動模式:

第三次調用,使用wintx=winty=7來處理圖像5,7,8和19:

單擊“Calibration”進行重新標定:

觀察上面的投影誤差(0.11689,0.11500)比前面的更小了。另外注意到,標定參數的不確定性也更小了。通過單擊“Analyse error”來檢測誤差:

讓我們來看看前面那個興趣圖像18中的點,在標定板的網格座標(0,0)處。單擊“Reproject on images”然後
選擇只顯示圖像18(當然在此之前你必須右擊誤差分析圖像退出誤差分析工具):

放大圖像我們可以看到更小的投影誤差:

單擊“Save”保存標定結果到文件“Calib_Results.mat”中:

可以看到前面的標定結果已經被拷貝到文件“Calib_Results_old0.mat”中。

現在多加5張圖像來重新進行相機標定。然後“Read images”把所有的25張圖像載入內存。然後以縮略圖顯示:

單擊“Extract grid corners”來對新的5張圖像進行角點提取,窗口尺寸用wintx=winty=5:

以傳統的角度提取過程對這5張圖像進行角點提取。然後單擊“Calibration”運行又一次優化:

接下來,使用不同的窗口尺寸對最後的四張圖像進行重新計算。對圖像22和24使wintx=winty=9,對圖23使用
wintx=winty=8,對圖像25使用wintx=winty=6。然後按照前面介紹的過程重新進行一次(三次調用“Recomp.corners
”),重新計算之後,再次運行“Calibration”:

然後“Save”保存標定結果。

作爲練習,我們去除圖像16,18,19,24和25然後重新進行標定:
單擊“Add/Suppress images”

輸入要去掉的圖像([16 18 19 24 25]):

重新“Calibration”進行標定:

“Add/Supress images”取決於使用者是否需要某些圖像。實際上,這個函數只是簡單地更新active_image這個
向量,使對應的圖像索引爲0或1.
接下來,載入之前標定的結果“Load”:

現在又回到了沒有去掉圖像之前的狀態了。現在我們實現一次含有用來描述X和Y像素之間角度的切向因素alpha_c
進行的標定。爲此,我們需要將est_alpha設置爲1(在命令行中進行)。As an exercise, let us fit the 
radial distortion model up to the 6th order (up to now, it was up to the 4th order, with
 tangential distortion). For that, set the last entry of the vector est_dist to one: 

然後重新運行“Calibration”:

優化之後可以看到,切向因素非常接近0(alpha_c=0.00042),這就意味着X和Y像素之間的角度非常接近90°
(89.976°)。這調整了之前的90°的設想。另外,注意到第6個徑向畸變係數非常大。在這種情況下,我們最好
就是不使用它的估算值。在這裏,我們直接將est_dist最後一個量設置爲0:

再次“Calibration”:

如果標定結果滿意的話就“Save”保存標定結果。

爲了選擇合理的畸變模型來使用,通常可視化對像素圖像的畸變影響以及畸變的徑向部分和切向部分
的比對是非常有用的。爲此,在matlab命令行運行visualize_distortions,就會有三張圖出來:

第一幅圖顯示了整體的畸變模型對圖像每個像素的影響。每個箭頭表示由於鏡頭畸變而使一個像素髮生的位移效果。
可以看到圖像角落處的像素移動了25個像素。第二幅圖顯示了畸變的切向部分。在這幅圖中,最大的位移式0.14個
像素,在圖像的左上角。最後,第三幅圖顯示了畸變的徑向部分的影響。這幅圖和第一幅圖有點相似。說明畸變的切
向部分相對於整體模型來說可以忽略不計。在第三幅圖中,十字叉表示了圖像的中心,而圓表示光心所在的位置。

現在我們來試驗一下,當沒有畸變的情況下標定會有什麼結果。使Kc=[0;0;0;0;0],並且fc沒有各向異性(使fc
幾個方向都相等):

然後,運行一次優化“Calibration”:

和預期一樣,畸變係數向量Kc都是0,焦距各個方向都相當,fc1=fc2。在實際中,這種標定的模型是不推薦的:
因爲在沒有各向異性的幸虧下去估算切向畸變是沒有意義的。通常情況下,除非有特定的應用,一般推薦在模型中評
估各向異性。對於畸變模型,一般經常只對其中一些係數進行優化。例如,將est_dist設置爲【1;0;0;0】
只對第一個畸變係數kc(1)進行估算而把其他三個畸變係數直接置0.這種模型也叫作第二對稱性徑向畸變模型。它
是一個非常可行的模型,尤其是當使用比較低的畸變光學系統(昂貴的鏡頭),或者當用來標定的圖像很少的時候。
另一個比較常用的畸變模型是第4對稱性徑向畸變模型而沒有切向部分畸變(est_dist=[1;1;0;0])。這個模
型被zhang使用並被調整了,基於現在大多的鏡頭製造在聚焦方面都沒有缺陷。這個模型可以很好地用於現在這個
例子中,從前面三個圖也可以看出,這個鏡頭的切向部分畸變遠小於徑向部分畸變。

最後,讓我們來做一次,沒有各向異性fc(2)/fc(1),光心cc,畸變係數kc,切向係數alpha_c的優化。爲此

一般地,如果光心沒有被估算,則最好的預估值就是圖像的中心:

然後運行“Calibration”:

從上面可以看到,光心cc優化後還在圖像的中心(因爲center_optim=0)

接下來,載入原來的標定結果:


標定工具箱的其他功能

僅僅計算外參:

我們可以只計算圖像的外參,而內參直接用之前標定好的結果,在前面標定好的基礎上,輸入一張圖像,然後在面板
上“Comp.Extrinsic”,就可以在matlab的命令行中出現下面的情況:

外參在Rc_ext和Tc_ext兩個變量中,另外一個變量omc_ext和Rc_ext一個效果,可以將omc_ext用羅得裏格斯
變換進行轉換Rc_ext=rodrigues(omc_ext)。


圖像矯正

這個函數幫助你利用之前標定的內參得到一些沒有畸變的圖像。

作爲一個練習,我們來對圖像20進行矯正。
在面板中單擊“Undistort image”:

輸入1來選擇一張要矯正的圖像,注意不要輸入圖像的擴展名,只輸入Image20就可以,然後是圖像的類型。

初始圖像存儲在矩陣I中,如下圖所示:

矯正過的圖像存儲在矩陣I2中,如下圖所示:

新產生的矯正的圖像也存儲成Image20_rect.tif。

現在我們來矯正所有的圖像。“Undistort image”,然後對第一個問題輸入空參數。然後所有的標定圖像都將被
矯正,然後存儲爲Image_rect1.tif,Image_rect2.tif...

也可以將標定數據導出爲其他格式的數據:這樣當你使用同樣的數據來做標定,然後進行對比的時候是非常有用的
這個可以在角點提取階段使用,單擊“Export calib data”:

輸入0選擇使用Willson Heikkil格式,輸入數據名(shot),然後每張圖像的標定數據就會被保存爲shot1,shot2,...

也可以導出爲zhang的格式。“Export calib data”,然後輸入1.然後輸入兩個文件基名:一個是3D模型座標(Model),
另一個是圖像座標(data)。然後程序會創建一系列的text(Model1.txt,data1.txt,...),可以被zhang的
代碼直接使用:


以上是matlab標定工具箱的使用教程,有一些不對的地方希望補充完善。 
發佈了50 篇原創文章 · 獲贊 86 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章