1. 程式人生 > >水平集演算法原理介紹

水平集演算法原理介紹

本篇文章,解釋的是水平集演算法最基礎的原理。

水平集方法的解釋
有一個表面S,它與一個平面P相交,得到一個曲線C,這個C就是我們通過水平集得到的輪廓。
在影象分割中,表面S是隨著由影象派生得到的勢(force)來更新。
本文的思路是:
1提出問題
2提出解決方法
3方法的侷限性

跟蹤介面
首先,我們來想象水從一個小山的山頂往下流的畫面。我們的目標是,在水往下流的時候,跟蹤水前(water front,每一個點的水下一秒流動的方向叫作水前,我們跟蹤的是所有點的水前。並且我們的初始條件是,所有初始位置點構成的曲線)。

如下圖所示,這是一個V型小山,黑色部分是山頂,越往白色的地方,海拔越低。
這裡寫圖片描述


紅色箭頭是水前。

問題來了,如何在給定時間T時刻,得到所有的水前?

顯式輪廓方法
一個方法是,跟蹤一系列點,沿著它們的法線方向(normal direction)來演化水前,並且猜測水前的停止位置。

如下圖所示,在t=0時刻點集的水前位置,當t=1的時候,點集運動到了虛線位置。
這裡寫圖片描述

顯式演化一個點集的水前,聽起來是個好主意,但是它有很大的缺陷,使得我們不得不放棄這種可以直觀理解的方法。

那究竟是什麼缺陷呢?
如下圖所示,這個倒V型的曲線,在它的頂端是一個角(corner)。離角最近的那兩個點有著各自的水前,它們方向不一致。隨著水前的演化,該角最後的狀態將無法得知。紅色是0時刻的點狀態,粉色是1時刻的點狀態。
這裡寫圖片描述


另外,如果水前是向外擴充套件的,那麼初始的點集可能不夠用來得到演化後的水前。需要使用插值法或者在演化出現衝突的時候刪掉一些點。並且,點之間的距離要保證足夠小,才能得到平滑的水前。這種得到演化水前的機制在應用時是很麻煩的。

在應用上,拓撲變化需要關注的問題更多,比如在分裂和合並的情況下。在我們的小山流水的例子中,左圖的中間的紅色矩形方框是初始點集,圈住的是山頂最高位置,即將向上下的白色山谷流下去。
在右圖中,我們看到,初始點集演化到一定階段,就會分裂,並且分裂後會與本來在山谷裡的曲線合併~問題很明白了,這個方法要解決的挑戰是,如何確定在分裂時該插入的點,以及在分裂時該刪掉的點呢?
這裡寫圖片描述 這裡寫圖片描述


所以,追蹤點集的水前,儘管是一個很直觀的辦法,但卻有很難解決的缺陷。

隱式輪廓方法
這個方法的本質是演化一個表面S,而不是一個水前曲線C,且我們用隱式輪廓法得到的水前定義為這個表面S在高度h=0的所有點構成的集合(沒有刪除和插值這麼麻煩的事情了,開心~)。於是根據定義,水前曲線就是零水平集φ=0。如下圖所示,是從一個演化的表面得到輪廓。
這裡寫圖片描述
當表面φ(x,y,t)在演化時,它將呈現杯狀,過後杯口或將變窄,或將消失。下圖中的零水平集顯示了輪廓曲線合併和分裂的情況,z=0表示的是山谷。
這裡寫圖片描述 這裡寫圖片描述
(a)t=50,合併開始 (b)t=52,合併結束
這裡寫圖片描述 這裡寫圖片描述
(c)t=90,分裂開始 (d)t=120,分裂結束

對於拓撲變化,我們不用再過多關注其它問題了。
那麼問題在於,我們如何確定函式φ呢?

水平集方程
首先,我們來看看這個方法背後的數學理論~
點x(x,y)屬於一個隨著時間演化的曲線,x(t)為它在t時刻的位置。在任意時刻t,對於每一個點x(t)都是表面φ在高度為0的曲線上的點,即:
φ(x(t),t) = 0

問題還是,這個函式φ到底是什麼呢?
只要它給得出我們需要的零水平集,那麼它可以是任何定義。。。(這就糟了,怎麼造呢)

舉個栗子,上面有一幅圖,顯示的初始輪廓是一個矩形。該表面的高度等於(x,y)到輪廓上點的最近距離,於是有φ(x,y,t=0)=±d,+d表示在輪廓外,-d表示在輪廓內。只要φ的零水平集可以匹配初始輪廓,那它可以被定義成任何函式。
在時刻t=0處,給定初始函式φ,根據運動方程∂φ/∂t我們可以得到任意t時刻的φ。對於此,利用鏈式法則,有:
這裡寫圖片描述
把∂φ/∂x記作▽φ,速度x_t 的方向由表面的法向量給定,因此x_t =F(x(t))n,其中這裡寫圖片描述。上面的運動方程可重寫為:
這裡寫圖片描述
最後一個方程定義了φ的運動。給定t=0時的φ以及它隨時間演化的運動方程,我們可以通過演化初始函式這裡寫圖片描述得知任何t時刻的這裡寫圖片描述。這樣我們就回答了最初的問題,即我們知道了φ是什麼。
φ有個有趣的特徵,就是我們可以用下式得到表面的曲率:
這裡寫圖片描述
我們可以用這個來控制水前曲線的平滑度。

應用
在計算機的世界,影象是具有的畫素,而函式需要被離散化。也就是說,這裡寫圖片描述在 畫素(i,j)處的值由這裡寫圖片描述估計。這個梯度由有限差分法(finite difference scheme)來估計,比如下:
這裡寫圖片描述
其中,對於給定點x,這裡寫圖片描述表示左有限差分,這裡寫圖片描述表示右有限差分。如下圖所示,梯度計算的方式因水前方向的不同而不同,有點差分法也會考慮到水前方向。
這裡寫圖片描述
於是,之前的運動方程可化作:
這裡寫圖片描述
從此,我們可以用下式來更新表面這裡寫圖片描述
這裡寫圖片描述
當我們計算曲率的時候,只依賴於表面φ。於是可以使用中心差分法:
這裡寫圖片描述
曲率的數值計算可利用下式:
這裡寫圖片描述

為了使水前曲線平滑,高的曲率應該被懲罰。為了使零水平集擴充套件,我們不通過減小φ,而是利用高曲率使得水前運動反向。我們可以利用曲率來更新這裡寫圖片描述
這裡寫圖片描述

結果
給定任意的初始函式φ,比如一個初始輪廓的距離轉換,這裡寫圖片描述的數值計算方法,我們來展示一些輪廓演化的例子。
第一個小栗子,一滴在擴充套件的水,前面有一個小障礙物,如下圖所示:
這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述
水前運動被障礙物停止下來,並被擾動。
下面有個更復雜的例子。
這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述
初始輪廓仍舊是個圓~~隨著表面的演化,輪廓開始分裂,從第三圖可看到已經完全分裂。

下面這個例子,利用真實的圖片。不使用連續的正勢和負勢,有無曲率皆可以,我們利用影象派生出勢(force)。這個勢值在物體內應該很高,在十分接近物體的邊緣時,應該很低(我們是從物體內部去得到它的邊緣的)。影象的梯度表現了它的邊緣所在。
這裡寫圖片描述 這裡寫圖片描述
勢可以是上面梯度影象這裡寫圖片描述的逆,也可以是它的高斯部分,如下:
這裡寫圖片描述
λ和σ是控制懲罰因子的引數。下圖是使用梯度影象來演化輪廓:
這裡寫圖片描述 這裡寫圖片描述 這裡寫圖片描述

到此為止,你應該瞭解,水平集方法是關於演化表面的函式,而不是演化曲線的函式~~(儘管我們的目的是得到輪廓)
這也是這個方法的優雅魅力之處!