歸一化相關性,normalization cross-correlation,因此簡稱NCC,下文中筆者將用NCC來代替這冗長的名稱。
NCC,顧名思義,就是用於歸一化待匹配目標之間的相關程度,注意這里比較的是原始像素。通過在待匹配像素位置p(px,py)構建3*3鄰域匹配窗口,與目標像素位置p'(px+d,py)同樣構建鄰域匹配窗口的方式建立目標函數來對匹配窗口進行度量相關性,注意這里構建相關窗口的前提是兩幀圖像之間已經校正到水平位置,即光心處於同一水平線上,此時極線是水平的,否則匹配過程只能在傾斜的極線方向上完成,這將消耗更多的計算資源。相關程度的度量方式由如下式子定義:
上式中的變量需要解釋一下:其中p點表示圖像I1待匹配像素坐標(px,py),d表示在圖像I2被查詢像素位置在水平方向上與px的距離。如下圖所示:
左邊為圖像I1,右邊為圖像I2。圖像I1,藍色方框表示待匹配像素坐標(px,py),圖像I2藍色方框表示坐標位置為(px,py),紅色方框表示坐標位置(px+d,py)。(由於畫圖水平有限,只能文字和圖片雙重說明來完成了~)
Wp表示以待匹配像素坐標為中心的匹配窗口,通常為3*3匹配窗口。
沒有上划線的I1表示匹配窗口中某個像素位置的像素值,帶上划線的I1表示匹配窗口所有像素的均值。I2同理。
上述公式表示度量兩個匹配窗口之間的相關性,通過歸一化將匹配結果限制在 [-1,1]的范圍內,可以非常方便得到判斷匹配窗口相關程度:
若NCC = -1,則表示兩個匹配窗口完全不相關,相反,若NCC = 1時,表示兩個匹配窗口相關程度非常高。
我們很自然的可以想到,如果同一個相機連續拍攝兩張圖像(注意,此時相機沒有旋轉也沒有位移,此外光照沒有明顯變化,因為基於原始像素的匹配方法通常對上述條件是不具備不變性的),其中有一個位置是重復出現在兩幀圖像中的。比如桌子上的一個可樂瓶。那么我們就可以對這個可樂瓶的位置做一下匹配。直觀的看,第一幀中可樂瓶上某一個點,它所構成鄰域窗口按理說應該是與第二幀相同的,就算不完全相同,也應該是具有非常高相關性的。基於這種感性的理解,於是才有前輩提出上述的NCC匹配方法。(純屬個人理解)
雙目立體匹配,這一部分是說明NCC如何用於雙目匹配。
假設有校正過的兩幀圖像I1,、I2,由上述NCC計算流程的描述可知,對圖像I1一個待匹配像素構建3*3匹配窗口,在圖像I2極線上對每一個像素構建匹配窗口與待匹配像素匹配窗口計算相關性,相關性最高的視為最優匹配。很明顯,這是一個一對多的過程。如果圖像尺寸是640*480,則每一個像素的匹配過程是是1對640,兩幀圖像完全匹配需要計算640*480*640 = 196608000,即一億九千多萬次~ 盡管計算機計算速度非常快,但也着實是非常消耗計算資源的。由於NCC匹配流程是通過在同一行中查找最優匹配,因此它可以並行處理,這大概也算是一種彌補吧~
雙目立體匹配流程如下:
1. 采集圖像:通過標定好的雙目相機采集圖像,當然也可以用兩個單目相機來組合成雙目相機。(標定方法下次再說)
2. 極線校正:校正的目的是使兩幀圖像極線處於水平方向,或者說是使兩幀圖像的光心處於同一水平線上。通過校正極線可以方便后續的NCC操作。
2.1 由標定得到的內參中畸變信息中可以對圖像去除畸變,在OpenCV中有函數對去畸變做了實現
void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, intborderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar() )
src:輸入圖像,即原圖像,需要單通道8位或者浮點類型的圖像
dst:輸出圖像,即目標圖像,需和原圖形一樣的尺寸和類型
map1:它有兩種可能表示的對象:(1)表示點(x,y)的第一個映射;(2)表示CV_16SC2,CV_32FC1等類型的x值矩陣
map2:它有兩種可能表示的對象:(1)若map1表示點(x,y)時,這個參數不代表任何值;(2)表示CV_16UC1,CV_32FC1等類型y值矩陣
interpolation:插值方式,有四中插值方式:(1)INTER_NEAREST——最近鄰插值,(2)INTER_LINEAR——雙線性插值(默認),(3)INTER_CUBIC——雙三樣條插值(默認),(4)INTER_LANCZOS4——lanczos插值(默認)
intborderMode :邊界模式,默認BORDER_CONSTANT
borderValue :邊界顏色,默認Scalar()黑色
2.3 通過上述兩步操作,我們成功地對圖像去除了畸變,並且校正了圖像極線。注意,在立體校正階段需要設置alpha = 0才能完成對圖像的裁剪,否則會有黑邊。
3. 特征匹配:這里便是我們利用NCC做匹配的步驟啦,匹配方法如上所述,右視圖中與左視圖待測像素同一水平線上相關性最高的即為最優匹配。完成匹配后,我們需要記錄其視差d,即待測像素水平方向xl與匹配像素水平方向xr之間的差值d = xr - xl,最終我們可以得到一個與原始圖像尺寸相同的視差圖D。
4. 深度恢復:通過上述匹配結果得到的視差圖D,我們可以很簡單的利用相似三角形反推出以左視圖為參考系的深度圖。計算原理如下圖所示:
如圖,Tx為雙目相機基線,f為相機焦距,這些可以通過相機標定步驟得到。而xr - xl就是視差d。
通過公式 z = f * Tx / d可以很簡單地得到以左視圖為參考系的深度圖了。
至此,我們便完成了雙目立體匹配。倘若只是用於圖像識別,那么到步驟3時已經可以結束了。
OK,最后一部分就是代碼實現部分了,哎~ 寫太累了,下次再補上。
未完待續。。。