OpenCV-Python系列之背景分離


從本次教程開始,我們進入新的篇章,之前一直在討論OpenCV的特征部分,這次我們來討論OpenCV中的背景分離,又稱背景減法模型。

背景分離(BS)是一種通過使用靜態相機來生成前景掩碼(即包含屬於場景中的移動對象像素的二進制圖像)的常用技術。

顧名思義,BS計算前景掩碼,在當前幀與背景模型之間執行減法運算,其中包含場景的靜態部分,或者更一般而言,考慮到所觀察場景的特征,可以將其視為背景的所有內容。

image.png

背景建模包括兩個主要步驟:

1. 背景初始化;

2. 背景更新。

初步,計算背景的初始模型,而在第二步中,更新模型以適應場景中可能的變化。

在本教程中,我們將學習如何使用OpenCV中的BS。

OpenCV中的使用

OpenCV 中已經包含了其中三種比較容易使用的方法,我們逐一來看。

BackgroundSubtractorMOG

這是一個以混合高斯模型為基礎的前景/背景分割算法。它是 P.KadewTraKuPong 和 R.Bowden 在 2001 年提出的。

它使用 K(K=3 或 5)個高斯分布混合對背景像素進行建模。使用這些顏色(在整個視頻中)存在時間的長短作為混合的權重。背景的顏色一般持續的時間最長,而且更加靜止。

一個像素怎么會有分布呢?在 x,y平面上一個像素就是一個像素,沒有分布,但是我們現在講的背景建模是基於時間序列的,因此每一個像素點所在的位置在整個時間序列中就會有很多值,從而構成一個分布

在編寫代碼時,我們需要使用函數:cv2.createBackgroundSubtractorMOG() 創建一個背景對象。這個函數有些可選參數,比如要進行建模場景的時間長度,高斯混合成分的數量,閾值等。將他們全部設置為默認值。然后在整個視頻中我們是需要使用backgroundsubtractor.apply() 就可以得到前景的掩模了

移動的物體會被標記為白色,背景會被標記為黑色的,前景的掩模就是白色的了。

不過目前這個方法已經被棄用了,OpenCV中也沒有了相關函數的API。

BackgroundSubtractorMOG2

這個也是以高斯混合模型為基礎的背景/前景分割算法。它是以 2004 年 和 2006 年 Z.Zivkovic 的兩篇文章為基礎的。這個算法的一個特點是它為每 一個像素選擇一個合適數目的高斯分布。(上一個方法中我們使用是 K 高斯分布)。

這樣就會對由於亮度等發生變化引起的場景變化產生更好的適應。

和前面一樣我們需要創建一個背景對象。但在這里我們我們可以選擇是否檢測陰影。如果 detectShadows = True(默認值),它就會檢測並將影子標記出來,但是這樣做會降低處理速度。影子會被標記為灰色。

BackgroundSubtractorMOG2算法的兩個改進點:

-陰影檢測
-速度快了一倍

我們將使用官方提供的人體跟蹤的視頻:

image.png

這個我提供在這兒:

test.zip

我們來看代碼:

def MOG2():
     cap = cv2.VideoCapture("test.avi")
     fgbg = cv2.createBackgroundSubtractorMOG2()
     while (1):
         ret, frame = cap.read()
         fgmask = fgbg.apply(frame)
         cv2.imshow('frame', fgmask)
         k = cv2.waitKey(100) & 0xff
         if k == 27:
             break
     cap.release()
     cv2.destroyAllWindows()

結果:

image.png

可以看到基本的行人與背景分離出來了。

BackgroundSubtractorGMG

此算法結合了靜態背景圖像估計和每個像素的貝葉斯分割。這是 2012 年 Andrew_B.Godbehere,Akihiro_Matsukawa 和 Ken_Goldberg 在文章 中提出的。

它使用前面很少的圖像(默認為前 120 幀)進行背景建模。使用了概率前 景估計算法(使用貝葉斯估計鑒定前景)。這是一種自適應的估計,新觀察到的 對象比舊的對象具有更高的權重,從而對光照變化產生適應。一些形態學操作 如開運算閉運算等被用來除去不需要的噪音。在前幾幀圖像中你會得到一個黑 色窗口。

對結果進行形態學開運算對與去除噪聲很有幫助。

不過同樣的,這個方法目前也是不再用了。

BackgroundSubtractorKNN

KNN作為大名鼎鼎的機器學習算法,其用在背景分離應用中也是得心應手,但是在此不對KNN作過多的解釋,它屬於機器學習的一個算法,比較復雜,我們來看代碼:

def KNN():
     cap = cv2.VideoCapture('test.avi')
     fgbg = cv2.createBackgroundSubtractorKNN()
     while (1):
         ret, frame = cap.read()
         fgmask = fgbg.apply(frame)
         cv2.imshow('frame', fgmask)
         k = cv2.waitKey(100) & 0xff
         if k == 27:
             break
     cap.release()
     cv2.destroyAllWindows()

結果:

image.png

實驗結果發現KNN的結果要明顯優於MOG2算法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM