1. 程式人生 > >SLIC超畫素分割演算法

SLIC超畫素分割演算法

超畫素概念是2003年Xiaofeng Ren提出和發展起來的影象分割技術,是指具有相似紋理、顏色、亮度等特徵的相鄰畫素構成的有一定視覺意義的不規則畫素塊。它利用畫素之間特徵的相似性將畫素分組,用少量的超畫素代替大量的畫素來表達圖片特徵,很大程度上降低了影象後處理的複雜度,所以通常作為分割演算法的預處理步驟。已經廣泛用於影象分割、姿勢估計、目標跟蹤、目標識別等計算機視覺應用。幾種常見的超畫素分割方法及其效果對比如下:


 Graph-based           NCut            Turbopixel          Quick-shift        Graph-cut a        Graph-cut b         SLIC

這裡主要介紹的是SLIC(simple linear iterativeclustering),即簡單的線性迭代聚類。它是2010年提出的一種思想簡單、實現方便的演算法,將彩色影象轉化為CIELAB顏色空間和XY座標下的5維特徵向量,然後對5維特徵向量構造距離度量標準,對影象畫素進行區域性聚類的過程。SLIC演算法能生成緊湊、近似均勻的超畫素,在運算速度,物體輪廓保持、超畫素形狀方面具有較高的綜合評價,比較符合人們期望的分割效果。

SLIC主要優點總結如下:1)生成的超畫素如同細胞一般緊湊整齊,鄰域特徵比較容易表達。這樣基於畫素的方法可以比較容易的改造為基於超畫素的方法。2)不僅可以分割彩色圖,也可以相容分割灰度圖。3)需要設定的引數非常少,預設情況下只需要設定一個預分割的超畫素的數量。4)相比其他的超畫素分割方法,SLIC在執行速度、生成超畫素的緊湊度、輪廓保持方面都比較理想。

在介紹SLIC之前,插播一下Lab顏色空間的介紹。Lab色彩模型是由亮度(L)和有關色彩的a, b三個要素組成。L表示亮度(Luminosity),L的值域由0(黑色)到100(白色)。a表示從洋紅色至綠色的範圍(a為負值指示綠色而正值指示品紅),b表示從黃色至藍色的範圍(b為負值指示藍色而正值指示黃色)。Lab顏色空間的優點:1)不像RGBCMYK色彩空間,Lab 顏色被設計來接近人類生理視覺。它致力於感知均勻性,它的 L 分量密切匹配人類亮度感知。因此可以被用來通過修改 a 和 b 分量的輸出色階來做精確的顏色平衡,或使用 L 分量來調整亮度對比。這些變換在 RGB 或 CMYK 中是困難或不可能的。2)因為 Lab 描述的是顏色的顯示方式,而不是裝置(如顯示器、印表機或數碼相機)生成顏色所需的特定色料的數量,所以 Lab 被視為與裝置無關的顏色模型。3)色域寬闊。它不僅包含了RGB,CMYK的所有色域,還能表現它們不能表現的色彩。人的肉眼能感知的色彩,都能通過Lab模型表現出來。另外,Lab色彩模型的絕妙之處還在於它彌補了RGB色彩模型色彩分佈不均的不足,因為RGB模型在藍色到綠色之間的過渡色彩過多,而在綠色到紅色之間又缺少黃色和其他色彩。如果我們想在數字圖形的處理中保留儘量寬闊的色域和豐富的色彩,最好選擇Lab。

下面描述一下SLIC具體實現的步驟:

1.  初始化種子點(聚類中心):按照設定的超畫素個數,在影象內均勻的分配種子點。假設圖片總共有 N 個畫素點,預分割為 K 個相同尺寸的超畫素,那麼每個超畫素的大小為N/ K ,則相鄰種子點的距離(步長)近似為S=sqrt(N/K)

2.  在種子點的n*n鄰域內重新選擇種子點(一般取n=3)。具體方法為:計算該鄰域內所有畫素點的梯度值,將種子點移到該鄰域內梯度最小的地方。這樣做的目的是為了避免種子點落在梯度較大的輪廓邊界上,以免影響後續聚類效果。

3.  在每個種子點周圍的鄰域內為每個畫素點分配類標籤(即屬於哪個聚類中心)。和標準的k-means在整張圖中搜索不同,SLIC的搜尋範圍限制為2S*2S,可以加速演算法收斂,如下圖。在此注意一點:期望的超畫素尺寸為S*S,但是搜尋的範圍是2S*2S。


4.  距離度量。包括顏色距離和空間距離。對於每個搜尋到的畫素點,分別計算它和該種子點的距離。距離計算方法如下:


其中,dc代表顏色距離,ds代表空間距離,Ns是類內最大空間距離,定義為Ns=S=sqrt(N/K),適用於每個聚類。最大的顏色距離Nc既隨圖片不同而不同,也隨聚類不同而不同,所以我們取一個固定常數m(取值範圍[1,40],一般取10)代替。最終的距離度量D'如下:


由於每個畫素點都會被多個種子點搜尋到,所以每個畫素點都會有一個與周圍種子點的距離,取最小值對應的種子點作為該畫素點的聚類中心。

5.  迭代優化。理論上上述步驟不斷迭代直到誤差收斂(可以理解為每個畫素點聚類中心不再發生變化為止),實踐發現10次迭代對絕大部分圖片都可以得到較理想效果,所以一般迭代次數取10。

6.  增強連通性。經過上述迭代優化可能出現以下瑕疵:出現多連通情況、超畫素尺寸過小,單個超畫素被切割成多個不連續超畫素等,這些情況可以通過增強連通性解決。主要思路是:新建一張標記表,表內元素均為-1,按照“Z”型走向(從左到右,從上到下順序)將不連續的超畫素、尺寸過小超畫素重新分配給鄰近的超畫素,遍歷過的畫素點分配給相應的標籤,直到所有點遍歷完畢為止。

解析:

1、設定期望分割的超畫素數目,開啟圖片。將彩色RGB圖片轉換為LAB空間及x、y畫素座標共5維空間。

2、DetectLabEdges。求圖片中所有點的梯度=dx+dy.其中

dx=(l(x-1)-l(x+1))*(l(x-1)-l(x+1))+(a(x-1)-a(x+1))*(a(x-1)-a(x+1))+(b(x-1)-b(x+1))*(b(x-1)-b(x+1));

dy=(l(y-1)-l(y+1))*(l(y-1)-l(y+1))+(a(y-1)-a(y+1))*(a(y-1)-a(y+1))+(b(y-1)-b(y+1))*(b(y-1)-b(y+1));

3、GetLABXYSeeds_ForGivenK。給定了要分割的超畫素總數K,根據LABXY資訊獲得種子點。

1)   超畫素的種子點間步長Step=sqrt(N/K)。初始化種子點。按照步長均勻播撒種子點,初始化後種子點是均勻分佈的(圖1中的紅色點)。

2)   PerturbSeeds。擾亂種子點。在每個種子點的3*3鄰域內,計算該種子點的8個鄰域內畫素點的Lab顏色梯度(同上述步驟2),分別與初始種子點梯度進行比較,取梯度值最小(最“平坦”)的點,並記錄其LABXY資訊作為新的種子點(圖1中綠色點為擾亂後的新種子點)。

圖1:擾亂種子點圖示

4、超畫素的步長Step=sqrt(N/K)+2。加了一個小偏置2是為了避免Step太小,造成超畫素太密集的情況。

5、PerformSuperpixelSegmentation_VariableSandM。對於每個超畫素,最大的顏色距離M取值範圍[1,40],一般取10。最大空間距離取步長為Step。

1)   搜尋範圍2step* 2step,即設定offset=step。 在步長較短時(step<10)可以擴充套件offset=step*1.5作為搜尋範圍。

2)  初始化distlab、distxy、distvec為無窮大。maxlab初始化為10*10,maxxy初始化為step*step。distlab代表某點與種子點的lab顏色空間距離,計算如下:distlab(i)=(l-kseedsl(n))*(l-kseedsl(n))+(a-kseedsa(n))*(a-kseedsa(n))+(b-kseedsb(n))*(b-kseedsb(n));distxy代表某點與種子點的空間座標距離,計算如下:distxy(i)=(x-kseedsx(n))*(x-kseedsx(n))+(y-kseedsy(n))*(y-kseedsy(n));dist代表某點與種子點的綜合距離(歸一化的顏色距離+空間距離),計算如下:dist=distlab/( maxlab)+ distxy/(maxxy);在此提醒一下:如果將C++程式轉為matlab程式碼時特別要注意資料型別。uint16型別變數減去double型別變數的結果是uint16型別,所以如果後者值大於前者,結果就為0。此處容易出錯,需要強制型別轉換。

3)   計算搜尋區域內每個點離種子點的距離dist,並將搜尋區域內每個點離種子點的距離儲存在distvec中。因為某點可能位於多個種子點的搜尋區域,所以最後儲存的是離相鄰種子點最近的距離,並將該畫素標號為最近種子點相同的標號。同一個超畫素內所有畫素的標號相同

4)   計算每個新超畫素內所有畫素的labxy均值和座標重心。將座標重心作為該超畫素的新種子點位置。

5)   上述步驟2)到4)重複迭代10次。

6、EnforceLabelConnectivity。該函式主要有幾個作用:保證同一個超畫素都是單連通區域;去掉尺寸過小的超畫素;避免單個超畫素被切割的情況。

1)   先計算超畫素理想面積大小:SUPSZ = sz/K = N/K;

2)   有兩種標號向量:上一步驟中得到的舊標號向量labels(即步驟5中得到的klabels),但其存在多連通,過小超畫素等問題,需要優化。新標號向量nlabels,初始化值全為-1。

3)   首先選擇每個超畫素的起始點(左上角的第一個點),起始點判斷條件:a) 按照從左到右,從上到下的“Z”型順序查詢。b)該點在新標號向量nlabels中未被標記過(值為-1)。將其座標儲存在xvec[0],yvec[0]中。

4)   記錄前一個相鄰超畫素的標號值adjlabel。判斷條件:a)在步驟3中起始點的四鄰域。b)在新標號向量nlabels中被標記過(標號大於0)。記錄adjlabel的目的是:如果當前超畫素尺寸過小,將當前超畫素標號全部用adjlabel代替。即合併到前一個相鄰超畫素,參考下面步驟6)。

5)   擴充套件當前超畫素。首先選擇起始點作為當前操作的中心點,然後對其四鄰域進行判斷是否屬於該超畫素成員。判斷條件:a) 該點在新標號向量nlabels中未被標記過(值為-1);b)該點n和當前操作中心點c在舊標號向量中標號一致,即labels(n)= labels(c),可以理解為原先就是屬於同一個超畫素的成員。如果判斷是超畫素的新成員,那麼把該新成員作為新的操作中心點,迴圈直到找不到新成員為止。

6)   如果新超畫素大小小於理想超畫素大小的一半(可以根據需要自己定義),將該超畫素標號用前一個相鄰超畫素的標號值adjlabel代替,並且不遞增標號值。

7)   迭代上述步驟3)到6)直到整張圖片遍歷結束。

7、繪製分割結果,退出視窗。

圖2:SLIC超畫素分割結果,藍色的點表示最終超畫素的種子點。


轉自:http://blog.csdn.net/electech6/article/details/45509779

另外一篇也很好:http://www.cnblogs.com/Imageshop/p/6193433.html