1. 程式人生 > >數字影象處理筆記——Snakes演算法、活動輪廓以及水平集(Snakes, active contours, and level sets)

數字影象處理筆記——Snakes演算法、活動輪廓以及水平集(Snakes, active contours, and level sets)

Snakes演算法

上一講我們講的影象分割演算法主要是基於畫素的,這一講主要是基於曲線的。我們希望能得到一個能夠包圍住影象輪廓的平滑的曲線,snakes演算法就是一個很有用的演算法。首先我們將曲線的座標x、y同一用引數s表示,s範圍從0-1代表從起點繞曲線一週再回到原點

我們假定初始化的時候這個曲線已經給定,我們定義這個曲線的能量函式,曲線衍進的過程就是讓能量函式降低的的過程,能量函式分為外部能量和內部能量

如下是內部能量的定義,內部能量只與曲線的形狀有關。能量由兩部分組成:一階導部分與二階導部分。一階導代表曲線的“彈性”,也就是曲線是否被拉伸的非常長;二階導代表曲線曲折程度,也就是曲線是否彎曲不平滑。曲線彈性越低,彎曲越少能量越低

第二部分是曲線的外部能量,代表曲線與邊緣的重合程度。重合程度大的時候能量低。

我們有了能量函式以後如何求它的最小值呢?這涉及到變分法,在此就不細講了。對於數字影象,我們一般用一定數量的點對曲線進行逼近,之後我們可以用梯度下降法來求得函式的最小值

在曲線衍進的時候還需要注意有時我們需要對曲線的點進行重排(再取樣)來保證下一次迴圈(衍進)時我們有更好的效果

當然這種方法也存在問題,我們的活動輪廓無法看到遠處的邊緣,因此當週圍畫素值都差不多的時候曲線可能不會繼續向內收斂;第二點是當影象中存在噪聲時輪廓很可能和噪聲點重合。為了解決這個問題我們可以對影象先進行模糊處理,這相當於將原本的邊界變得更加模糊了(即擴大的邊界的影響範圍),這樣就能使輪廓有更好的收斂性

 

梯度向量流

採用模糊處理的效果實際上並不是很好,更好的方法是採用梯度向量流(gradient vector flow)。梯度向量流用一個新的向量場來代替梯度場,從而替換外部能量的部分。

我們用如下方式定義這個新的向量場v,當梯度值較大的時候,我們另這個向量場與梯度場的值大致相同;當梯度值較小的時候我們讓v的值儘量平滑的變化。這也就意味著在影象邊緣處,v的值與梯度場的值相同,當我們逐漸遠離邊界的時候,v的值不像梯度場一樣立馬變小,而是有一個逐漸變小的過程。實際上這個新的場v也是擴大了邊界的影響範圍,使得輪廓能夠在更遠的地方捕捉到邊緣

如果我們將這個場畫出來可以得到如下結果。我們可以看出在這種情況下如果初始輪廓在邊界外部,那麼輪廓將會收縮;如果初始輪廓在邊界內部,那麼輪廓將會外擴,即朝著向v的模大的地方衍進

Snakes演算法也有很多令人頭疼的地方,例如追蹤每一個點不是一件容易的事,例如snake無法包圍多個物體等等

除此以外由於這種演算法是基於邊緣的,它還會使曲線與我們不需要的邊緣重合,例如以下這個例子:曲線並不能很好地包圍手掌,而是被背景木桌的條紋所吸引了

 

水平集

為了解決snakes演算法不能包圍多個物體與洞的問題,我們有水平集(level set)這個演算法。與定義一條曲線不同的是,我們定義了一個三維的函式,二維平面上的曲線實際上是這個函式在z=0的橫截面

我們用這種方法可以很好地表示包含多個物體或洞的曲線

舉個例子,下面右圖是我們需要的曲線,左邊是這個曲線對應的函式

這種演算法還有很多細節我們就不在這討論了

我們在以上討論的演算法都是基於影象邊緣的,當然我們還有基於影象區域的演算法,這種演算法的能量只與曲線本身的性質以及兩個區域塊內的畫素有關,而與影象的邊界無關

比如以下的例子,我們運用基於區域的演算法可以讓曲線很好地收斂到斑馬周圍,因為這種情況下曲線外部的顏色基本是綠色,曲線內部基本是黑白的。但如果我們採用基於邊緣的演算法來計算,那麼這個曲線就會收斂到斑馬身上的條紋上