matlab calibration toolbox-Matlab標定工具箱使用(單目標定和雙目標定)
轉載自:https://blog.csdn.net/kaspar1992/article/details/54344965
英文網址:
http://www.vision.caltech.edu/bouguetj/calib_doc/index.html#examples
http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/example.html
http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/example5.html
轉載請註明:http://blog.csdn.net/kaspar1992
CSDN——matlab工具箱下載地址:
matlab calibration toolbox-Matlab標定工具箱使用
1. 單目標定
-
這個教程將帶你完整地利用20到25張平面棋盤格影象進行相機標定。
-
這個教程將讓你學會如何使用所有工具箱的特徵:載入影象、提取影象角點、執行標定引擎、顯示結果、控制精度
-
新增和刪減影象、影象矯正、匯出標定不同格式的資料...這個教程對於剛開始使用工具箱的人來說非常重要。
-
首先下載Matlab標定工具箱:
-
[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張影象來重新進行相機標定。image21 image22 image23 image24 image25。然後“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的
-
程式碼直接使用:
2. 雙目標定
雙目視覺系統標定、雙目影象校正
這個例子介紹如何使用工具箱進行立體視覺系統標定,包括內外引數,以及用獲得的資料進行立體校正和三維測量。
1、下載雙目示例圖片,包括14對左右攝像頭獲取的影象,還有兩個獨立標定的結果。
2、在視窗中輸入
stereo_gui
,出現工具視窗
3、點選第一個按鈕 Load left and right calibration files . 視窗提示輸入左右標定檔名,分別輸入對應檔名 Calib_Results_left.mat Calib_Results_right.mat
4、內部引數的初始值在視窗中顯示,並估算出外部引數 om 和 T ,右相機相對左相機的平移和旋轉。3*3旋轉矩陣是 om 通過 rodrigues 求出 。
然後執行全域性雙目優化演算法通過點選按鈕
Run stereo calibration
有以下所示結果
可以發現內外引數都被重新計算,所有未確定的引數也確定保證誤差最小的基礎上。你會發現不確定的內參數都變小了,這是因為最優化演算法的作用。預設情況下,優化演算法
會重新計算左右相機的內部引數,但是如果你不想讓其優化,則在視窗執行 recompute_instrinsic_left 和或者recompute_instrinsic_right .
在視窗輸入help go_calib_stereo 檢視更多資訊.
5、點選 Save stereo calib results ,儲存標定資料結果
6、雙目相機的空間位置和標定平面可以視覺化,通過點選按鍵
Show Extrinsics of the rig.
7、校正影象
點選 Rectify the calibration images ,所有14對圖片校正後影象儲存在檔案下。