1、介紹html
基於圖的圖像分割(Graph-Based Image Segmentation),論文《Efficient Graph-Based Image Segmentation》,P. Felzenszwalb, D. Huttenlocher,International Journal of Computer Vision, Vol. 59, No. 2, September 2004算法
論文下載和論文提供的C++代碼在這裏。post
Graph-Based Segmentation是經典的圖像分割算法,其做者Felzenszwalb也是提出DPM(Deformable Parts Model)算法的大牛。網站
Graph-Based Segmentation算法是基於圖的貪心聚類算法,實現簡單,速度比較快,精度也還行。不過,目前直接用它作分割的應該比較少,不少算法用它做墊腳石,好比Object Propose的開山之做《Segmentation as Selective Search for Object Recognition》就用它來產生過度割(over segmentation)。spa
2、圖的基本概念命令行
由於該算法是將圖像用加權圖抽象化表示,因此補充圖的一些基本概念。3d
一、圖code
是由頂點集V(vertices)和邊集E(edges)組成,表示爲G=(V, E),頂點v∈V,在論文即爲單個的像素點,鏈接一對頂點的邊(vi, vj)具備權重w(vi, vj),本文中的意義爲頂點之間的不類似度(dissimilarity),所用的是無向圖。component
二、樹orm
特殊的圖,圖中任意兩個頂點,都有路徑相鏈接,可是沒有迴路。以下圖中加粗的邊所鏈接而成的圖。若是當作一團亂連的珠子,只保留樹中的珠子和連線,那麼隨便選個珠子,都能把這棵樹中全部的珠子都提起來。
若是頂點i和h這條邊也保留下來,那麼頂點h,i,c,f,g就構成了一個迴路。
三、最小生成樹(minimum spanning tree)
特殊的樹,給定須要鏈接的頂點,選擇邊權之和最小的樹。
論文中,初始化時每個像素點都是一個頂點,而後逐漸合併獲得一個區域,確切地說是鏈接這個區域中的像素點的一個MST。以下圖,棕色圓圈爲頂點,線段爲邊,合併棕色頂點所生成的MST,對應的就是一個分割區域。分割後的結果其實就是森林。
3、類似性
既然是聚類算法,那應該依據何種規則斷定什麼時候該合二爲一,什麼時候該繼續劃清界限呢?對於孤立的兩個像素點,所不一樣的是灰度值,天然就用灰度的距離來衡量兩點的類似性,本文中是使用RGB的距離,即
固然也能夠用perceptually uniform的Luv或者Lab色彩空間,對於灰度圖像就只能使用亮度值了,此外,還能夠先使用紋理特徵濾波,再計算距離,好比先作Census Transform再計算Hamming distance距離。
4、全局閾值 >> 自適應閾值,區域的類內差別、類間差別
上面提到應該用亮度值之差來衡量兩個像素點之間的差別性。對於兩個區域(子圖)或者一個區域和一個像素點的類似性,最簡單的方法即只考慮鏈接兩者的邊的不類似度。以下圖,已經造成了棕色和綠色兩個區域,如今經過紫色邊來判斷這兩個區域是否合併。那麼咱們就能夠設定一個閾值,當兩個像素之間的差別(即不類似度)小於該值時,合二爲一。迭代合併,最終就會合併成一個個區域,效果相似於區域生長:星星之火,能夠燎原。
舉例說明:
對於上右圖,顯然應該聚成上左圖所示的3類:高頻區h,斜坡區s,平坦區p。
若是咱們設置一個全局閾值,那麼若是h區要合併成一塊的話,那麼該閾值要選很大,可是那樣就會把p和s區域也包含進來,分割結果太粗。若是以p爲參考,那麼閾值應該選特別小的值,那樣的話p區是會合併成一塊,可是h區就會合併成特別特別多的小塊,如同一面支離破碎的鏡子,分割結果太細。顯然,全局閾值並不合適,那麼天然就得用自適應閾值。對於p區該閾值要特別小,s區稍大,h區巨大。
先來兩個定義,原文依據這兩個附加信息來獲得自適應閾值。
一個區域內的類內差別Int(C):
能夠近似理解爲一個區域內部最大的亮度差別值,定義是MST中不類似度最大的一條邊。
倆個區域的類間差別Diff(C1, C2):
即鏈接兩個區域全部邊中,不類似度最小的邊的不類似度,也就是兩個區域最類似的地方的不類似度。
直觀的判斷,當:
時,兩個區域應當合併!
5、算法步驟
一、計算每個像素點與其8鄰域或4鄰域的不類似度。
如上圖,實線爲只計算4領域,加上虛線就是計算8鄰域,因爲是無向圖,按照從左到右,從上到下的順序計算的話,只須要計算右圖中灰色的線便可。
二、將邊按照不類似度non-decreasing排列(從小到大)排序獲得e1, e2, ..., en。
三、選擇ei
四、對當前選擇的邊ej(vi和vj不屬於一個區域)進行合併判斷。設其所鏈接的頂點爲(vi, vj),
if 不類似度小於兩者內部不類似度:
五、更新閾值以及類標號
else:
六、若是i < n,則按照排好的順序,選擇下一條邊轉到Step 4,不然結束。
6、論文提供的代碼
打開本博文最開始的鏈接,進入論文網站,下載C++代碼。下載後,make編譯程序。命令行運行格式:
/******************************************** sigma 對原圖像進行高斯濾波去噪 k 控制合併後的區域的數量 min: 後處理參數,分割後會有不少小區域,當區域像素點的個數小於min時,選擇與其差別最小的區域合併 input 輸入圖像(PPM格式) output 輸出圖像(PPM格式) sigma: Used to smooth the input image before segmenting it. k: Value for the threshold function. min: Minimum component size enforced by post-processing. input: Input image. output:Output image. Typical parameters are sigma = 0.5, k = 500, min = 20. Larger values for k result in larger components in the result. */ ./segment sigma k min input output
/opencv_contrib/modules/ximgproc/include/opencv2/ximgproc/segmentation.hpp