mean shift 圖像分割 (一)

mean shift 圖像分割

Reference:

[1] Mean shift: A robust approach toward feature space analysis, PAMI, 2002

[2] mean shift,非常好的ppt 百度文庫鏈接

[3] Pattern Recognition and Machine Learning, Bishop, 2006,Sec 2.5

[4] Computer Vision Algorithms and Applications, Richard Szeliski, 2010, Sec 5.3

[5] Kernel smoothing,MP Wand, MC Jones ,1994, Chapter 4


mean shift 圖像分割 (一)1 總體思想,2 算法步驟

mean shift 圖像分割 (二)3 算法原理,4 延伸

mean shift 圖像分割 (三)5 非參數密度估計

圖像分割—mean shift(OpenCV源碼註解)


寫在前頭的話:這篇筆記看起來公式巨多,實際上只是符號表示,沒啥公式推導,不過,多了就難免有差錯,歡迎指正。

    Mean shitf的故事說來挺勵的,早在1975年就誕生了,接着就是漫長的黑暗歲月,黑暗到幾乎淡出了人們的視野,不過,命運總是善良的,95年又重新煥發生機,各種應用噴薄而出,包括目標跟蹤,邊緣檢測,非極大值抑制等。這次就只介紹在圖像分割中的應用吧,其它的我也沒看。Mean shitf過程也充滿正能量,描繪的是如何通過自己的努力,一步一步爬上頂峯的故事。

1 總體思想

圖 1 特徵空間映射:RGB圖片 -> L-u特徵空間

    首先meanshift是一種特徵空間分析方法,要利用此方法來解決特定問題,需要將該問題映射到特徵空間。對於圖像分割,我們可以映射到顏色特徵空間,比如將RGB圖片,映射到Luv特徵空間,圖1是L-u二維可視化的效果。

    圖像分割就是求每一個像素點的類標號。類標號取決於它在特徵空間所屬的cluster。對於每一個cluster,首先得有個類中心,它深深地吸引着一些點,就形成了一個類,即類中心對類中的點構成一個basin of attraction ,好比咱們的太陽系。如此,圖像分割問題,就可以看成對每個像素點,找它的類中心問題,因爲找到類中心就知道它是屬於那一類啦,即類中心一樣的點就是一類。

圖2標準化後的概率密度可視化效果 -> 聚類分割結果

    密度估計的思路需要解決兩個問題,what:中心是什麼?how:怎麼找?mean shift認爲中心是概率密度(probalility density function )的極大值點,如圖2中的紅色點,原文稱之爲mode,我這暫且用模點吧(某篇論文是如此稱呼)。對於每個點怎樣找到它的類中心呢?只要沿着梯度方向一步一步慢慢爬,就總能爬到極值點,圖2中黑色的線,就是爬坡的軌跡。這種迭代搜索的策略在最優化中稱之爲 multiple restart gradient descent。不過,一般的gradient descent並不能保證收斂到局部極值,但mean shift 可以做到,因爲它的步長是自適應調整的,越靠近極值點步長越小。

    也就是說meanshift的核心就兩點,密度估計(Density Estimation) 和mode 搜索。對於圖像數據,其分佈無固定模式可循,所以密度估計必須用非參數估計,選用的是具有平滑效果的核密度估計(Kernel density estimation,KDE)。

2 算法步驟

截取這一塊可視化

(a)灰度圖可視化à(b)mean shift模點路徑à(c)濾波後效果à(d)分割結果

    分三步走:模點搜索/圖像平滑、模點聚類/合併相似區域、兼併小區域(可選)。模點搜索是爲了找到每個數據點的到類中心,以中心的顏色代替自己的顏色,從而平滑圖像。但模點搜索得到的模點太多,並且很多模點捱得很近,若果將每個模點都作爲一類的話,類別太多,容易產生過分割,即分割太細,所以要合併掉一些模點,也就是合併相似區域。模點聚類後所得到的分割區域中,有些區域所包含的像素點太少,這些小區域也不是我們想要的,需要再次合併。

2.1 模點搜索/圖像平滑

    建議先看[2]中的演示(P4-12)

    圖像中的點包括兩類信息:座標空間(spatial,),顏色空間(range ,)。這些就構成了特徵空間。

    模點搜索(OpenCV):某一個點它在聯合特徵空間迭代搜索它的mode/模點

    圖像平滑: 將模點的顏色值賦給它自己,即.對應原文中的圖像平滑,實質上是通過模點搜索,達到圖像平滑的效果, 所以我合併爲以一步。

    設點依次爬過的腳印爲:

    出發時,它所收斂到的模點爲,c代表convergence。

    第一步:如果迭代次數超過最大值(默認最多爬5次),結束搜索跳到第四步,否則,在座標空間,篩選靠近的數據點進入下一步計算。

    OpenCV是以的座標 爲中心,邊長爲的方形區域內的數據點。

    其實,本應用爲中心,爲半徑的圓形區域,那樣效果更好,但是循環計算時並不方便,所以用方形區域近似。

    第二步:使用第一步倖存下來的點計算重心,並向重心移動。

    寫得有點複雜了,下面解釋下。是某種核函數,比如高斯分佈, 是顏色空間的核平滑尺度。OpenCV使用的是最簡單的均勻分佈:

二維可視化效果

    是一個以(第步位置的顏色值)爲球心,半徑爲的球體,球體內部值爲1,球體外部值爲0。對於經過上一步篩選後倖存的數據點,如果其顏色值滿足,也就是顏色值落也在球內,那麼求重心時,就要算上,否則落在球外,算重心時,就不帶上它。實際上,上一步是依據座標空間距離篩選數據點,是依據顏色距離進一步篩選數據點,上一步的篩子是矩形,這一步是球體

    簡而言之,設滿足的點依次爲,那麼重心計算公式可以進一步化簡爲:

    是不是很簡單呢,初中知識吧。

    注意:上文中的兩個參數,是Mean shift最核心的兩個參數(還有一個可選的M),具有直觀的意義,分別代表座標空間和顏色空間的核函數帶寬。

    第三步:判斷是否到模點了,到了就停止。

    如果,移動後顏色或者位置變化很小,則結束搜索,跳到第四步,否則重返第一步,從繼續爬。

OpenCV停止搜索的條件:

    (1)座標距離不變

    (2)顏色變化值很小

    滿足一條就可以功成身退,否則繼續努力。

    第四步:將模點的顏色賦給出發點/,即

    注意:原文這一步,不僅將模點的顏色值賦給,順帶把座標值也賦給了,也就是說

2.2 合併相似區域/模點聚類

    合併上一步平滑後的圖像。OpenCV採用flood fill函數實現,原理很簡單,看下wiki的動畫就知道了,模擬洪水浸滿峽谷的效果。基本上就是區域生長,從某一點出發,如果和它附近的點(4/8鄰域)的顏色值相似就合併,同時再從新合併的點出發繼續合併下去,直到碰到不相似的點或者該點已經屬於另一類了,此時,就退回來,直到退無可退(所有的4/8鄰域搜索空間都已經搜索完畢)。

    雖然很簡單,但是不同的方法還是有很多需要注意的細節問題。這裏假設濾波後的圖像用表示。

    濾波後的兩個像素點,是否合併,可以使用顏色相似度和空間位置相似性判定。

    OpenCV只考慮顏色相似性,而忽略模點的座標是否相似。而原算法綜合了二者的信息。如果像素點,滿足或者, 則這兩個像素點就合併。不過OpenCV也是有考慮座標位置的,它是隻考慮原空間的4/8鄰域,而原文是考慮特徵空間模點的 ,相當於說OpenCV的(原空間)。

    此外,floodfill有一個特點,它不能越過已經被分類的區域,再加上沒有第三步,使得OpenCV的結果,真的是慘不忍睹。原文的合併算法,具體怎麼合併的還得看源代碼。不過,應該不是用flood fill。

    《Computer Vision A Modern Approach》中是使用類平均距離判定是否合併。比如,能否合併成,取決於類平均距離:

    這樣做我覺得效果會更好,因爲它不是單獨依據邊界上的兩個點來判定是否合併,它是依據兩個區域內部所有的點的信息綜合判斷。所以,它能合併兩個區域,而原算法和OpenCV只能是兩個點合併成一個區域,該區域又不斷地合併點,一旦一個區域已經完成生長,那麼它就不會和別的區域合併了。可以反證。假設先形成,區域生長的時候把給合併了,那麼必定有兩個點滿足相似關係,連接了二者,假設這兩個點爲相似,那麼生長的時候就肯定已經把點合並進來了,接着把所擁有的區域全盤接收,根本不會讓區域自成一類。

    當然考慮Outlier,使用中值更好。

    假設合併之後得到m類。對於原文的算法,每個像素點的標號就是其模點所屬的模點集合的類標號,比如。不過,OpenCV是所屬集合的類標號。

    不過,從原文結果來看,得到的結果並不是類標號,因爲類標號一般都是序號,比如1,2,……,然後顯示分割結果的時候,就給每一類隨機分配一種獨有的顏色。但原文的分割結果貌似是這一類的總體顏色值,我猜測原算法可能是用(加權)求平均的方式得到類的顏色值,然後屬於這一類的像素點就用這個顏色代替。

    注意:這一步實現的是合併相似區域,但本質上還是而是合併模點,或者說模點聚類,因爲每個像素點的值,就是它所屬模點的顏色值/模點的聯合信息

2.3 兼併小區域

 

OpenCV的分割結果

    上一步合併了一些模點,但是,對於一些小區域,如果它和周圍的顏色差異特別大,那麼它們也會自成一類,這些小傢伙讓需要進一步合併。不過,OpenCV的實現中,並沒有包含這一步,所以分割出的結果中包含了太多芝麻大點的區域,本人很不滿意,有時間再加進去,還得優化下代碼,這個實現實在是太慢了。怎麼兼併小的區域呢?原文沒說,我也沒看他的源代碼,我們可以直接將包含像素點少於的區域與它最相似的區域合併,實際中,小區域往往是被大區域兼併了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章