semi-global matching(縮寫SGM)是一種用於計算雙目視覺中disparity的半全局匹配算法。在OpenCV中的實現為semi-global block matching(SGBM)。
SGBM的思路是:
通過選取每個像素點的disparity,組成一個disparity map,設置一個和disparity map相關的全局能量函數,使這個能量函數最小化,以達到求解每個像素最優disparity的目的。
能量函數形式如下:
D指disparity map。E(D)是該disparity map對應的能量函數。
p, q代表圖像中的某個像素
Np 指像素p的相鄰像素點(一般認為8連通)
C(p, Dp)指當前像素點disparity為Dp時,該像素點的cost
P1 是一個懲罰系數,它適用於像素p相鄰像素中dsparity值與p的dsparity值相差1的那些像素。
P2 是一個懲罰系數,它適用於像素p相鄰像素中dsparity值與p的dsparity值相差大於1的那些像素。
I[.]函數返回1如果函數中的參數為真,否則返回0
利用上述函數在一個二維圖像中尋找最優解是一個NP-complete問題,耗時過於巨大,因此該問題被近似分解為多個一維問題,即線性問題。而且每個一維問題都可以用動態規划來解決。因為1個像素有8個相鄰像素,因此一般分解為8個一維問題。
考慮從左到右這一方向,如下圖所示:
則每個像素的disparity只和其左邊的像素相關,有如下公式:
r指某個指向當前像素p的方向,在此可以理解為像素p左邊的相鄰像素。
Lr(p, d) 表示沿着當前方向(即從左向右),當目前像素p的disparity取值為d時,其最小cost值。
這個最小值是從4種可能的候選值中選取的最小值:
1.前一個像素(左相鄰像素)disparity取值為d時,其最小的cost值。
2.前一個像素(左相鄰像素)disparity取值為d-1時,其最小的cost值+懲罰系數P1。
3.前一個像素(左相鄰像素)disparity取值為d+1時,其最小的cost值+懲罰系數P1。
4.前一個像素(左相鄰像素)disparity取值為其他時,其最小的cost值+懲罰系數P2。
另外,當前像素p的cost值還需要減去前一個像素取不同disparity值時最小的cost。這是因為Lr(p, d)是會隨着當前像素的右移不停增長的,為了防止數值溢出,所以要讓它維持在一個較小的數值。
C(p, d)的計算很簡單,由如下兩個公式計算:
即,當前像素p和移動d之后的像素q之間,經過半個像素插值后,尋找兩個像素點灰度或者RGB差值的最小值,作為C(p, d)的值。
具體來說:設像素p的灰度/RGB值為I(p),先從I(p),(I(p)+I(p-1))/2,(I(p)+I(p+1))/2三個值中選擇出和I(q)差值最小的,即
d(p,p-d)。然后再從I(q),(I(q)+I(q-1))/2,(I(q)+I(q+1))/2三個值中選擇出和I(p)差值最小的,即d(p-d,p)。最后從兩個值中選取最小值,就是C(p, d)
上面是從一個方向(從左至右)計算出的像素在取值為某一disparity值時的最小cost值。但是一個像素有8個鄰域,所以一共要從8個方向計算(左右,右左,上下,下上,左上右下,右下左上,右上左下,左下右上)這個cost值。
然后把八個方向上的cost值累加,選取累加cost值最小的disparity值作為該像素的最終disparity值。對於每個像素進行該操作后,就形成了整個圖像的disparity map。公式表達如下:
SGBM算法遍歷每個像素,針對每個像素的操作和disparity的范圍有關,故時間復雜度為:
參考資料:
【1】http://lunokhod.org/?p=1356
【2】http://zone.ni.com/reference/en-XX/help/372916M-01/nivisionconceptsdita/guid-53310181-e4af-4093-bba1-f80b8c5da2f4/
【3】A Pixel Dissimilarity Measure That Is Insensitive to Image Sampling. Stan Birchfield and Carlo Tomasi
【4】Accurate and Efficient Stereo Processing by Semi-Global Matching and Mutual Information. Heiko Hirschmuller