經典算法Semi-Global Matching(SGM)文獻筆記(二)

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

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(路徑相鄰點的當前視差代價聚合值 + P1,路徑相鄰點的視差差值爲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一個。

 

THE END!

發佈了190 篇原創文章 · 獲贊 717 · 訪問量 110萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章