1. 程式人生 > >Stereo Matching文獻筆記之(三):經典演算法Semi-Global Matching(SGM)之碉堡的動態規劃

Stereo Matching文獻筆記之(三):經典演算法Semi-Global Matching(SGM)之碉堡的動態規劃

上一篇部落格中提到了SGM的第一部分,基於分層互資訊(HMI)的代價計算,本文繼續說說自己對SGM代價聚合部分的理解。

(轉載:http://blog.csdn.net/wsj998689aa/article/details/50488249, 作者:迷霧forest)

SGM的代價聚合,其實仔細看看,這並不是嚴格意義上的代價聚合,因為SGM是為了優化一個能量函式,這和一般的全域性演算法一樣,如何利用優化演算法求解複雜的能量函式才是重中之重,其能量函式如下所示:


其中,C(p, Dp)代表的就是基於互資訊的代價計算項,後面兩項指的是當前畫素p和其鄰域內所有畫素q之間的約束,如果q和p的視差只差了1,那麼懲罰P1,如果大於1,那麼懲罰P2,這麼做基本上是機器學習中的常用方法,即所謂的正則化約束。這裡需要注意的是,P2要大於P1,這麼做真心有用。

1. 假如不考慮畫素之間的制約關係,不假設領域內畫素應該具有相同的視差值,那麼最小化E(D)就是最小化每一個C,這樣的視差圖效果很差,因為影象總會收到光照,噪聲等因素的影響,最小的代價對應的視差往往是“假的”,並且這樣做全然不考慮相鄰之間的畫素關係,例如,一個桌面的視差明顯應該相同,但是可能由於傾斜光照的影響,每個畫素的最小代價往往會不同,所以看起來就會亂七八糟,東一塊西一塊。這就是加上約束的目的。

2. 新增兩個正則化項一方面是為了保證視差圖平滑,另一方面為了保持邊緣(保持邊緣一直沒想明白為什麼?)。懲罰的越大,說明越不想看到這種情況發生,具體來說,如果q和p之間的視差有所差異但又不大,那麼就要付出代價,你不是想最小化能量函式麼?那麼二者都要小,如果沒有第二項,那麼求出來的視差圖將會有明顯的鋸齒現象,如果只有第三項,那麼求出來的視差圖邊緣部分將會得到保持,但由於沒有對相差為1的相鄰畫素進行懲罰,物體內部很可能出現一個“斜面”。

3. 這事情還沒完,本文中有對這兩項的解釋,原文內容如下所示:


這句話的隱含意思是,如果我們讓P1<P2,那麼會允許出現小的斜面,也會保持邊緣,前面一句我理解,懲罰的力度不大,就會導致這種事情還會發生,這也正是作者想看到的,水至清而無魚嘛,不過,後一句中的P2並不是常數項,是根據相鄰畫素的差距來決定的,括號裡面的“與大小無關”看起來就更加矛盾了,不知道哪位可以給好好解釋一下這句話?

有了能量函式,下面要做的就是求解它了,這個時候問題來了,這個E對p是不可導的,這意味著我們常看到的梯度下降,牛頓高斯等等演算法在這裡都不適用,作者於是採用了動態規劃來解決這一問題,動態規劃相信大家都知道了,但是其真正的精髓卻是深藏不露,我早在大三期間就接觸到了動態規劃演算法,這麼多年過去了,雖然時而會用到這個演算法,但到現在仍舊不敢說自己徹底懂它。。。。

簡單地說,p的代價想要最小,那麼前提必須是鄰域內的點q的代價最小,q想要代價最小,那麼必須保證q的領域點m的代價最小,如此傳遞下去。


本文只說說作者是怎麼利用動態規劃來求解E,其實這個求解問題是NP完全問題,想在2D影象上直接利用動態規劃求解是不可能的,只有沿著每一行或者每一列求解才能夠滿足多項式時間(又叫做掃描線優化),但是這裡問題來了,如果我們只沿著每一行求解,那麼行間的約束完全考慮不到,q是p的領域的點其實這個時候被弱化到了q是p的左側點或者右側點,這樣的求優效果肯定很差。於是,大招來了!!我們索性不要只沿著橫或者縱來進行優化,而是沿著一圈8個或者16個方向進行優化。 這是一幅神奇的圖示,我一直沒有弄明白它到底是什麼意思,笨死了,直到有一天我終於領悟它的真諦(仰天長嘯)。我們先來看看優化求解過程:

每一個點的代價聚合值是“當前代價+min(路徑相鄰點的當前視差代價聚合值,路徑相鄰點的視差差值為1的代價聚合值 + P1,路徑相鄰點的視差插值大於1的最小代價聚合值 + P2)- 路徑相鄰點的視差插值大於1的最小代價聚合值 ”,聽起來夠繞口的,其實就好比最小代價的蔓延,當前代價聚合值由當前代價和路徑上一點的加了懲罰的最小代價聚合值所決定(最後那一項純粹是為了防止數字過大,這是常用手段)。 其實為什麼分解為8個方向想想看也很正常,能量函式E中每個p的能量是“自身代價本身+周圍畫素q帶來的懲罰”,周圍畫素足足有8個,想求它們和的最小化十分難,最樸素的想法就是“分而求之”,我們就規定一個方向r,這個方向上p的鄰居q只有一個,那麼沿著這一方向的p的代價聚合值就成為了上面公式的樣子。進一步,將8個方向的代價聚合值都加起來,就形成了p的最終代價聚合值。然後用WTA搞一下得到的視差圖可以得到一個較小的能量E,目的就達到了。 我們來想想SGM的優化過程和DoubleBP有什麼區別。 1. 先看能量函式,DoubleBP是每個畫素自身代價加上週圍畫素的一個二元勢函式值。SGM呢?是自身的代價加上週圍畫素帶來的懲罰。其實二者是一個意思。 2. 再看優化過程,DoubleBP靠的是置信度傳播演算法,最後WTA的目標是一個置信度向量,這個置信度向量其實和向量沒關係,每個分量都是去當前視差d的代價+周圍畫素的訊息,這一點和SGM簡直是太像了。 3. 再說說二者的區別,訊息的每個分量可以理解為q對p取每個視差的支援力度,而SGM索性直接求取最小的懲罰,這點比DoubleBP要直接許多,所以SGM很快,DoubleBP很慢。 我認為這塊內容非常值得單獨拉出來說說,以後有時間好好的寫寫。 最後,我們可以看看SGM的整體流程圖,這麼長的流程圖!!這個沒啥好進一步解釋的,唯一想說的就是我認為II-A那裡多畫了兩個箭頭,指向II-B的箭頭應該只有MI一個。
OK,本文就說到這裡,好久不寫部落格了,手都已經生鏽了,請大家不吝賜教,幫我想想我問的問題啊!!!