1. 程式人生 > >CV | Max Flow / Min Cut 最大流最小割演算法學習

CV | Max Flow / Min Cut 最大流最小割演算法學習

題外話:時隔這麼久,就當我放暑假了吧!哈哈哈 題外話ending。。。

最大流/最小割(Max-Flow/Min-Cut)演算法,因其可以對能量方程最小化進行求解,在計算機視覺(CV)中有很廣泛的應用。之前介紹過的Seam Carving演算法(用於影象智慧縮放),或是影象分割演算法中,經常使用最大流/最小割進行能量方程的最小化求解。

1. 最大流/最小割 背景介紹

最大流/最小割(Max-Flow/Min-Cut)在解決計算機視覺中的能量方程最小化問題的強大,最早發現是Greig於1989年發表的文章:Exact Maximum A Posteriori Estimation for Binary Images。

最大流最小割演算法求解的能量方程,通常是基於圖結構得到的能量求解方法,這類能量方程可以普遍表示為:


其中L是影象P的一個標籤結果。設P為3*3的影象,P = [ 3, 8, 9; 4, 9, 8; 2, 9, 7 ],現在要將P的畫素分為兩類,標籤值為1或2,L是P的所有可能性中的一種可以是L = [ 1, 2, 2; 1, 2, 2; 1, 2, 2 ] 或 L = [ 1, 1, 2; 1, 2, 2; 2, 2, 2 ](還有很多就不枚舉了),L的所有可能性即為2^9,而能量方程 E(L) 就是計算在當前標籤結果下的能量值,通常我們將能量方程最小化,從而求出可以使得總體能量最小的標籤值情況L,利用最終的畫素分類結果得到影象分割等結果。如下圖所示,(a)為影象P的畫素灰度值示意圖,顏色越深則灰度值越小;(b)為該影象的一種分類結果L,當然還存在著若干種分類結果L,我們要做的就是設計一個相較周全的能量方程,然後通過最大流/最小割方法進行最小化求解。


現在返回公式(1)繼續解釋。式中兩項,分別為資料懲罰項Dp(Data Penalties)和互動項Vp,q(Interaction Potentials)。資料懲罰項在某些方法中也成為Unary Potentials,Interaction Potentials通常對應為Pairwise Potentials,顧名思義,資料懲罰項是畫素點自身資料值(如:色彩、強度等)的能量評測項,互動項則考慮兩兩畫素間的不連續關係(如空間或時間連續性)對整體能量值的影響,下式Vp,q的搜尋範圍N是當前畫素p的鄰域範圍,q是其鄰點才需要考慮兩畫素間的能量關係。


2. 能量方程的圖結構 介紹

有向圖G = < V, E >由節點V和節點間的邊E構成。通常來說,圖中的節點對應影象的畫素或超畫素、超體素。圖通常還包含一些額外附加但非常重要的點,稱為終點(terminals,不要吐槽翻譯= =因為本寶寶也不知道應該怎麼翻譯,理解就行,它們就是一些很重要的終端節點)。終點的重要性在於,它們可以直接連線圖中節點,從而給每個節點賦予標籤,意味著每個終點表示一個標籤值,例如圖中有兩個終點,則該影象最終只會被分為兩種標籤值。

以下用包含兩個終點的圖結構進行更詳細的解釋,兩個終點(terminals)在圖結構G中通常成為源點(Source,縮寫為s)和匯點(Sink,縮寫為t)。


如上圖所示,P為3*3的影象,現在要將它的畫素劃分為s和t兩個標籤值的子集。圖(a)為各節點與源點匯點、節點間的連線關係示意圖;圖(b)中的cut是圖割的示意,通過能量方程的最小化求解,得到影象P的最小割,將不必要節點間的邊割斷,源點和匯點所連線點的集合的交為空,併為P中所有節點。

值得注意的是,在有向圖G中,p點到q點的權值和q點到p點的權值可能會不一樣。圖中的邊分為兩類:n-links和t-links。n-links的n是neighbour的縮寫,表示節點間的連線邊,衡量節點不連續性(兩節點不連續性即差異越大,懲罰值越大);t-links的t是terminal的縮寫,表示節點與終點(terminal)相連,衡量節點賦予所連線終點須耗費的代價值。兩類邊的權值分別對應公式(1)能量方程中的互動項Vp,q和資料懲罰項Dp

以上為視覺中設計能量方程的背景條件之一,構建圖結構的方法介紹。

3. 最大流/最小割問題

基於第2節中構造的圖結構,圖割C通過切斷圖結構的邊,將圖中的所有節點劃分為兩個不相交的子集S和T,其中源點s在子集S中,匯點t在子集T中。因此,圖割C定義為其所割斷(經過)邊( p, q )的權值(代價)總和,其中p屬於子集S,q屬於子集T。最小割問題,就是在圖結構上找到具有最小權值(代價)總和的圖割C。

最小割問題通常可以通過找到從源點s到匯點t的最大流求解,即最小割問題和最大流問題是等價的。最大流問題的求解辦法通常是使用增廣路徑演算法,Yuri Boykov於2004年提出一個優化求解方法,下面對其進行進一步介紹。

傳統的增廣路徑演算法是在圖中搜索從源點s到匯點t的路徑,使用寬度優先搜尋(廣搜)將所有路徑遍歷,最終找到最大流路徑。但是這個演算法的效率在實際應用中是軟肋,因為廣搜通常要遍歷圖中幾乎所有的節點,為解決這個問題從而有了優化的新方法。新的方法同樣也是增廣路徑演算法的延伸,通過構建樹從而找到增廣路徑,然而不同的是,該方法構建了兩棵樹,一個從源點s出發,一個從匯點t出發。另一個區別在於新的方法不會從頭構建這兩顆樹,而是複用已有樹結構,從而達到提高演算法速度的目的。

4. 最大流求解方法

假設以源點s和匯點t在圖結構上構造兩顆沒有交集的樹,分別為樹S和樹T,如下圖所示。樹S中的所有邊都是由父節點指向子節點(存在流量),樹T中則由子節點指向父節點。不在兩樹中的節點為“自由”狀態。搜尋樹S和T中的節點只有兩種狀態:“主動”和“被動”。主動態的節點表示搜尋樹的外邊界節點,意思是從該節點出發還可以擴充套件搜尋樹,而被動態節點表示搜尋樹內部的節點,樹不能由該節點向外擴充套件。主動態節點因為可以向外擴充套件,所以有可能會搜尋到另一搜索樹的節點,當主動節點檢測到另一搜索樹的節點,就找到了一條增廣路徑。


Yuri提出的演算法主要迴圈以下三個步驟:

1. “增長”階段:搜尋樹S和T擴充套件節點,直到兩樹相遇,得到一條由源點s到匯點t的增廣路徑。

2. “增廣”階段:根據找到的增廣路徑將搜尋樹拆分為子樹或森林。

3. “領養”階段:搜尋樹S和T重新構建。

優化的增廣路徑求解演算法虛擬碼如下,初始化時,搜尋樹S只有源點s為主動節點,搜尋樹T只有匯點t作為主動節點,增長搜尋樹直到它們的主動節點相遇,得到一條增廣路徑P。如果P為空則演算法終止,反之則對P進行增廣流量處理。然後對孤點進行領養處理,以此迴圈。


4.1 增長階段

增長階段中,搜尋樹擴充套件。主動態節點搜尋相鄰且鄰邊仍有可用流量的自由節點作為搜尋樹新的子節點,新增長的子節點又稱為該搜尋樹的主動態節點,搜尋樹繼續擴充套件增長。當主動態節點的所有鄰點都檢測過,主動態節點變為被動態節點。當兩顆搜尋樹的主動態節點搜尋到對方的節點時,增長階段終止。然後根據當前建樹情況,找到一條增廣路徑,如上圖中黃色路徑所示。

增長階段的虛擬碼如下所示,該階段總括一句話就是從自由節點中擴充套件當前搜尋樹的新子節點。


其中A是當前搜尋樹的主動態節點集合,tree_cap( p->q ) 指的是當前節點p到鄰點q的邊流量值,TREE( q )即節點q所屬搜尋樹標籤值,PARENT( q )為節點q的父節點。

4.2 增廣階段

這個階段根據增長階段找到的增廣路徑進行增廣流量統計,即求出經過該路徑的最大流量,意味著路徑中至少有一條邊達到飽和態,也就是所經流量等於該邊的流量值。因此搜尋樹S和T中會出現一種新的節點,稱為“孤點”(orphans),意思就是連線它與其父節點的邊已達飽和態,沒有流可以再到達這個節點,好似孤星一般沒有人找到(原諒我的修辭)。所以在增廣階段搜尋樹S和T可能會拆分為多棵子樹,從而形成森林。源點s和匯點t仍充當兩顆子樹的根節點,而孤點成為其餘子樹的根節點。

增廣階段的虛擬碼如下,輸入是一條由源點s到匯點t的增廣路徑P,初始時孤點集合為空。


首先找到路徑P的瓶頸值,即最小流量邊,為該路徑的最大流量值。流量經過後,路徑P中至少有一條邊變為飽和態,即所經流量等於自身流量值,該邊連線的子節點變為孤點。

4.3 領養階段

領養階段字面上理解就能看出是針對孤點進行處理的階段,該階段也是為了恢復搜尋樹S和T的單一性,即圖中除了兩顆搜尋樹,其餘節點都歸為主動態、被動態和自由態,消除孤點。做法是為每個孤點找到一個新的合法父節點,該父節點原來必須與孤點屬於同一搜尋樹,而且父節點與孤點間有一條未飽和(仍有可經流量)的邊。若沒有符合要求的父節點,該孤點變為自由節點。以此處理所有孤點和孤點的子節點。當所有孤點都處理後,領養階段結束,最終只剩下原有的搜尋樹S和T。

領養階段的虛擬碼如下,O為孤點集合,最終變為空集。該階段中,我們盡力為O的每個節點p找到一個合法父節點,若沒有,該節點則恢復為自由節點,其所有子節點變為孤點。


虛擬碼中的process p分為以下步驟:

1. 首先,盡力找到p的一個合法父節點q,條件為該節點q必須與孤點p為同一搜尋樹,即TREE( q ) = TREE( p ),並且兩節點間的邊流量大於0,邊為未飽和狀態,即tree_cap( q->p ) > 0,且節點q的最原始根節點必須是源點s或匯點t,其它子樹的子節點不行。

2. 如果沒有為節點p找到合法父節點,節點p變為自由節點,其子節點變為孤點。

最大流的求解過程就是迴圈重複以上三個階段,直到搜尋樹S和T不能再增長。