使用Vibe算法分割前景片段



        前景檢測的算法有很多,最近想用Vibe來檢測前景並分割出片段來。本身沒有強大到能自己編寫Vibe代碼,用的是某位大牛基於原文開發的代碼大笑,只是在上面添加一些自己需要的功能而已。利用Vibe算法進行檢測和二值化,我們提取檢測結果,分析結果,合成動態片段。

一、Vibe算法(引自:http://blog.csdn.net/stellar0/article/details/8777283

ViBe算法詳解:

         ViBe是本篇論文中所提出的一個檢測方法,相比於其他方法它有很多的不同和優點。具體的思想就是爲每個像素點存儲了一個樣本集,樣本集中採樣值就是該像素點過去的像素值和其鄰居點的像素值,然後將每一個新的像素值和樣本集進行比較來判斷是否屬於背景點。該模型主要包括三個方面:模型的工作原理;模型的初始化方法;模型的更新策略。

模型的工作原理

背景物體就是指靜止的或是非常緩慢的移動的物體,而前景物體就對應移動的物體。所以我們可以把物體檢測看出一個分類問題,也就是來確定一個像素點是否屬於背景點。在ViBe模型中,背景模型爲每個背景點存儲了一個樣本集,然後將每一個新的像素值和樣本集進行比較來判斷是否屬於背景點。可以知道如果一個新的觀察值屬於背景點那麼它應該和樣本集中的採樣值比較接近。

具體的講,我們記v(x):x點處的像素值;M(x)={V1,V2,…VN}爲x處的背景樣本集(樣本集大小爲N);SR(v(x)):以x爲中心R爲半徑的區域,如果M(x) [{SR(v(x))∩ {v1,v2, . . . , vN}}]大於一個給定的閾值#min,那麼就認爲x點屬於背景點。

模型的初始化方法

初始化就是建立背景模型的過程。通用的檢測算法的初始化需要一定長度的視頻序列來完成,通常要耗費數秒的時間,這極大的影戲的檢測的實時性,對於手持相機實時拍照來講並不合適。ViBe的初始化僅僅通過一幀圖像即可完成。ViBe初始化就是填充像素的樣本集的過程但是由於在一幀圖像中不可能包含像素點的時空分佈信息,我們利用了相近像素點擁有相近的時空分佈特性,具體來講就是:對於一個像素點,隨機的選擇它的鄰居點的像素值作爲它的模型樣本值。M0(x) = {v0(y | y ∈NG(x))},t=0初始時刻,NG(x)即爲鄰居點 。這種初始化方法優點是對於噪聲的反應比較靈敏,計算量小速度快,可以很快的進行運動物體的檢測,缺點是容易引入Ghost區域。

模型的更新策略

背景模型的更新就是使得背景模型能夠適應背景的不斷變化,比如光照的變化,背景物體的變更等等。保守的更新策略:前景點永遠不會被用來填充背景模型,會引起死鎖,比如初始化的時候如果一塊靜止的區域被錯誤的檢測爲運動的,那麼在這種策略下它永遠會被當做運動的物體來對待;Blind策略:對死鎖不敏感,前景背景都可以來更新背景模型,缺點是緩慢移動的物體會融入背景中無法被檢測出來。在本方法中採用的更新策略是保守的更新策略+前景點計數方法。前景點計數:對像素點進行統計,如果某個像素點連續N次被檢測爲前景,則將其更新爲背景點。

隨機的子採樣:在每一個新的視頻幀中都去更新背景模型中的每一個像素點的樣本值是沒有必要的,當一個像素點被分類爲背景點時,它有1/ φ的概率去更新背景模型。

具體的更新方法:每一個背景點有1/ φ的概率去更新自己的模型樣本值,同時也有1/ φ的概率去更新它的鄰居點的模型樣本值。更新鄰居的樣本值利用了像素值的空間傳播特性,背景模型逐漸向外擴 散,這也有利於Ghost區域的更快的識別。同時當前景點計數達到臨界值時將其變爲背景,並有1/ φ的概率去更新自己的模型樣本值。

在選擇要替換的樣本集中的樣本值時候,我們是隨機選取一個樣本值進行更新,這樣可以保證樣本值的平滑的生命週期由於是隨機的更新,這樣一個樣本值在時刻t不被更新的概率是 (N-1)/N,假設時間是連續的,那麼在dt的時間過去後,樣本值仍然保留的概率是

也可以寫作, 

這就表明一個樣本值在模型中是否被替換與時間t無關 ,隨機策略是合適的。


Vibe源代碼:

http://pan.baidu.com/share/link?shareid=409860&uk=3373051938


原文的實驗效果:




      之所以選用Vibe是因爲他的自適應能力。他會迅速將不變背景更新到當前狀態。(雖然還是解決不了一大難題——逗留),但是通過設定閾值可以定義前景的標準。每個像素屬於前景的模型的參數是可以修改的。而且,Vibe的更新能很快消除抖動或背景光照的變化。基於此,我是用這樣的簡單方法分割動態片段的:

       首先,在每一幀進行前景檢測時,對檢測的結果進行前景像素統計。當然,原文裏的是沒有這個函數,但是他有一個update函數,可以對每一幀的每個像素進行判別和更新,這裏我將update的類型改爲int,並Return一個統計結果。這不影響原函數的更新和判別功能。只要在裏面增加一個Numforeground++來計數就行。

       得到的統計結果後就要進行動態幀的判別。當然先要設定一個前景像素比例的閾值。當統計的每一幀的前景像素比例超過了閾值就可以將這一幀視爲動態幀,然後保存(截取),否則繼續下一幀的檢測和判別。直到結束。

本人也是剛學OpenCV不久,所以代碼裏面的許多東西只能照葫蘆畫瓢。實驗效果如下:




這裏面的背景小白點是攝像頭自身的抖動和噪聲問題,本來還有更多的噪聲,但是因爲參數設定較大,直接過濾了。


       總之,用大牛們的研究和代碼成果直接來做我們自己的工程是件很有趣的事。我們不見得有大牛們那種慧根,但是我對他們充滿敬仰,在這工程中能學習到很悶的思維方式,編程習慣,當然獲益不淺。(剛開始寫博文,內功很淺,還望給位包含和指正!)

代碼在這裏就不貼了(*^__^*) ……


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