上一文對GraphCut做了一個了解,而現在我們聊到的GrabCut是對其的改進版,是迭代的Graph Cut。OpenCV中的GrabCut算法是依據《"GrabCut" - Interactive Foreground Extraction using Iterated Graph Cuts》這篇文章來實現的。該算法利用了圖像中的紋理(顏色)信息和邊界(反差)信息,只要少量的用戶交互操作即可得到比較好的分割結果。那下面我們來了解這個論文的一些細節。另外OpenCV實現的GrabCut的源碼解讀見下一個博文。接觸時間有限,若有錯誤,還望各位前輩指正,謝謝。
GrabCut是微軟研究院的一個課題,主要功能是分割和摳圖。個人理解它的賣點在於:
(1)你只需要在目標外面畫一個框,把目標框住,它就可以完成良好的分割:
(2)如果增加額外的用戶交互(由用戶指定一些像素屬於目標),那么效果就可以更完美:
(3)它的Border Matting技術會使目標分割邊界更加自然和perfect:
當然了,它也有不完美的地方,一是沒有任何一個算法可以放之四海而皆准,它也不例外,如果背景比較復雜或者背景和目標相似度很大,那分割就不太好了;二是速度有點慢。當然了,現在也有不少關於提速的改進。
OK,那看了效果,我們會想,上面這些效果是怎么達到的呢?它和Graph Cut有何不同?
(1)Graph Cut的目標和背景的模型是灰度直方圖,Grab Cut取代為RGB三通道的混合高斯模型GMM;
(2)Graph Cut的能量最小化(分割)是一次達到的,而Grab Cut取代為一個不斷進行分割估計和模型參數學習的交互迭代過程;
(3)Graph Cut需要用戶指定目標和背景的一些種子點,但是Grab Cut只需要提供背景區域的像素集就可以了。也就是說你只需要框選目標,那么在方框外的像素全部當成背景,這時候就可以對GMM進行建模和完成良好的分割了。即Grab Cut允許不完全的標注(incomplete labelling)。
1、顏色模型
我們采用RGB顏色空間,分別用一個K個高斯分量(一取般K=5)的全協方差GMM(混合高斯模型)來對目標和背景進行建模。於是就存在一個額外的向量k = {k1, . . ., kn, . . ., kN},其中kn就是第n個像素對應於哪個高斯分量,kn∈ {1, . . . K}。對於每個像素,要不來自於目標GMM的某個高斯分量,要不就來自於背景GMM的某個高斯分量。
所以用於整個圖像的Gibbs能量為(式7):
其中,U就是區域項,和上一文說的一樣,你表示一個像素被歸類為目標或者背景的懲罰,也就是某個像素屬於目標或者背景的概率的負對數。我們知道混合高斯密度模型是如下形式:
所以取負對數之后就變成式(9)那樣的形式了,其中GMM的參數θ就有三個:每一個高斯分量的權重π、每個高斯分量的均值向量u(因為有RGB三個通道,故為三個元素向量)和協方差矩陣∑(因為有RGB三個通道,故為3x3矩陣)。如式(10)。也就是說描述目標的GMM和描述背景的GMM的這三個參數都需要學習確定。一旦確定了這三個參數,那么我們知道一個像素的RGB顏色值之后,就可以代入目標的GMM和背景的GMM,就可以得到該像素分別屬於目標和背景的概率了,也就是Gibbs能量的區域能量項就可以確定了,即圖的t-link的權值我們就可以求出。那么n-link的權值怎么求呢?也就是邊界能量項V怎么求?
邊界項和之前說的Graph Cut的差不多,體現鄰域像素m和n之間不連續的懲罰,如果兩鄰域像素差別很小,那么它屬於同一個目標或者同一背景的可能性就很大,如果他們的差別很大,那說明這兩個像素很有可能處於目標和背景的邊緣部分,則被分割開的可能性比較大,所以當兩鄰域像素差別越大,能量越小。而在RGB空間中,衡量兩像素的相似性,我們采用歐式距離(二范數)。這里面的參數β由圖像的對比度決定,可以想象,如果圖像的對比度較低,也就是說本身有差別的像素m和n,它們的差||zm-zn||還是比較低,那么我們需要乘以一個比較大的β來放大這種差別,而對於對比度高的圖像,那么也許本身屬於同一目標的像素m和n的差||zm-zn||還是比較高,那么我們就需要乘以一個比較小的β來縮小這種差別,使得V項能在對比度高或者低的情況下都可以正常工作。常數γ為50(經過作者用15張圖像訓練得到的比較好的值)。OK,那這時候,n-link的權值就可以通過式(11)來確定了,這時候我們想要的圖就可以得到了,我們就可以對其進行分割了。
2、迭代能量最小化分割算法
Graph Cut的算法是一次性最小化的,而Grab Cut是迭代最小的,每次迭代過程都使得對目標和背景建模的GMM的參數更優,使得圖像分割更優。我們直接通過算法來說明:
2.1、初始化
(1)用戶通過直接框選目標來得到一個初始的trimap T,即方框外的像素全部作為背景像素TB,而方框內TU的像素全部作為“可能是目標”的像素。
(2)對TB內的每一像素n,初始化像素n的標簽αn=0,即為背景像素;而對TU內的每個像素n,初始化像素n的標簽αn=1,即作為“可能是目標”的像素。
(3)經過上面兩個步驟,我們就可以分別得到屬於目標(αn=1)的一些像素,剩下的為屬於背景(αn=0)的像素,這時候,我們就可以通過這個像素來估計目標和背景的GMM了。我們可以通過k-mean算法分別把屬於目標和背景的像素聚類為K類,即GMM中的K個高斯模型,這時候GMM中每個高斯模型就具有了一些像素樣本集,這時候它的參數均值和協方差就可以通過他們的RGB值估計得到,而該高斯分量的權值可以通過屬於該高斯分量的像素個數與總的像素個數的比值來確定。
2.2、迭代最小化
(1)對每個像素分配GMM中的高斯分量(例如像素n是目標像素,那么把像素n的RGB值代入目標GMM中的每一個高斯分量中,概率最大的那個就是最有可能生成n的,也即像素n的第kn個高斯分量):
(2)對於給定的圖像數據Z,學習優化GMM的參數(因為在步驟(1)中我們已經為每個像素歸為哪個高斯分量做了歸類,那么每個高斯模型就具有了一些像素樣本集,這時候它的參數均值和協方差就可以通過這些像素樣本的RGB值估計得到,而該高斯分量的權值可以通過屬於該高斯分量的像素個數與總的像素個數的比值來確定。):
(3)分割估計(通過1中分析的Gibbs能量項,建立一個圖,並求出權值t-link和n-link,然后通過max flow/min cut算法來進行分割):
(4)重復步驟(1)到(3),直到收斂。經過(3)的分割后,每個像素屬於目標GMM還是背景GMM就變了,所以每個像素的kn就變了,故GMM也變了,所以每次的迭代會交互地優化GMM模型和分割結果。另外,因為步驟(1)到(3)的過程都是能量遞減的過程,所以可以保證迭代過程會收斂。
(5)采用border matting對分割的邊界進行平滑等等后期處理。
2.3、用戶編輯(交互)
(1)編輯:人為地固定一些像素是目標或者背景像素,然后再執行一次2.2中步驟(3);
(2)重操作:重復整個迭代算法。(可選,實際上這里是程序或者軟件摳圖的撤銷作用)
總的來說,其中關鍵在於目標和背景的概率密度函數模型和圖像分割可以交替迭代優化的過程。更多的細節請參考原文。
《“GrabCut” — Interactive Foreground Extraction using Iterated Graph Cuts》
http://research.microsoft.com/en-us/um/people/ablake/papers/ablake/siggraph04.pdf
OpenCV實現了這個算法(沒有后面的border matting過程),下一文我們再解讀下它的源代碼。