OpenCV-Python教程:45.背景去除

基礎(chǔ)

背景去除是在很多視覺應(yīng)用里的主要預(yù)處理步驟。例如,攝像這樣的場景。一個固定攝像頭對顧客進(jìn)行計數(shù),或者交通攝像頭對汽車信息進(jìn)行提取。在所有這些情況下,首先你需要把人或者車輛單獨(dú)提取出來。技術(shù)上你需要從靜態(tài)背景里把移動的前景提取出來。

如果你有一個單獨(dú)的背景的圖像,比如沒有顧客的房子的圖像,或者沒有汽車的路的圖像,這就很簡單了。值需要在新的圖像里把背景去掉就行了。你得到的就是前景。但是在大多數(shù)情況下,你可能沒有這種圖像,所以我們需要從我們有的圖像里把背景去掉。當(dāng)車有影子的時候這個情況就很復(fù)雜了。因?yàn)橛白右苍趧印:唵蔚娜コ龝延白右沧鳛榍熬啊?/p>

一些算法來做這個,OpenCV實(shí)現(xiàn)了三個這樣的算法,很易用,我們一個個看一下。

BackgroundSubtractorMOG

這是一個高斯混合背景/前景分割算法。它使用一個方法通過K高斯分布的混合來給每個背景像素建模(K=3到5)。混合的權(quán)重表示那些顏色留在場景中的時間規(guī)模??赡艿谋尘邦伾悄切┝舻臅r間更長更靜止的。

寫代碼時,我們使用函數(shù)cv2.createBackgroundSubtractorMOG()創(chuàng)建一個背景對象.它有一些可選的參數(shù),比如歷史長度,高斯混合數(shù)量,閾值等。它們?nèi)际悄J(rèn)值,然后在視頻循環(huán)里,使用backgroundsubtractor.apply()方法來得到背景掩圖

看一個簡單例子:

import numpy as np
import cv2

cap = cv2.VideoCapture('vtest.avi')

fgbg = cv2.createBackgroundSubtractorMOG()

while(1):
? ? ret, frame = cap.read()

? ? fgmask = fgbg.apply(frame)

? ? cv2.imshow('frame',fgmask)
? ? k = cv2.waitKey(30) & 0xff
? ? if k == 27:
? ? ? ? break

cap.release()
cv2.destroyAllWindows()

BackgroundSubtractorMOG2

這也是高斯混合模型的前景/背景分割算法,這個算法的一個重要特點(diǎn)是它為每個像素選擇一個合適的高斯分布數(shù)。(記住,在上個例子,我們用了一個K高斯分布)它提供了更好的由于光照變化因素導(dǎo)致場景變化的適應(yīng)性。

在前面的例子里,我們得創(chuàng)建一個背景去除對象,這里,你可以選擇是否檢測影子。如果detectShadows = True(默認(rèn)的),它會檢測并標(biāo)記影子,但是會減低速度,Shadows會被標(biāo)記成灰色。

import numpy as np
import cv2

cap = cv2.VideoCapture('vtest.avi')

fgbg = cv2.createBackgroundSubtractorMOG2()

while(1):
? ? ret, frame = cap.read()

? ? fgmask = fgbg.apply(frame)

? ? cv2.imshow('frame',fgmask)
? ? k = cv2.waitKey(30) & 0xff
? ? if k == 27:
? ? ? ? break

cap.release()
cv2.destroyAllWindows()


BackgroundSubtractorGMG

這個算法合并了統(tǒng)計背景圖像判斷和每像素貝葉斯分割。

它使用最開始的一些幀(默認(rèn)120)來對背景建模。它使用概率前景分割算法通過貝葉斯推論識別可能的前景物體。判斷是能適應(yīng)的。最新發(fā)現(xiàn)的權(quán)重更好,以適應(yīng)光線變化。一些形態(tài)學(xué)過濾運(yùn)算比如開和閉被使用來去掉不需要的噪點(diǎn)。你會在最開始的一些幀里得到一個黑色窗口

最好是通過形態(tài)學(xué)的開運(yùn)算對結(jié)果使用,來移除噪點(diǎn)。

import numpy as np
import cv2

cap = cv2.VideoCapture('vtest.avi')

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
fgbg = cv2.createBackgroundSubtractorGMG()

while(1):
? ? ret, frame = cap.read()
? ?
? ? fgmask = fgbg.apply(frame)
? ? fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)

? ? cv2.imshow('frame',fgmask)
? ? k = cv2.waitKey(30) & 0xff
? ? if k == 27:
? ? ? ? break

cap.release()
cv2.destroyAllWindows()

結(jié)果

原始幀:


BackgroundSubtractorMOG的結(jié)果


BackgroundSubtractorMOG2的結(jié)果

灰色區(qū)域顯示了影子區(qū)域


BackgroundSubtractorGMG的結(jié)果

用形態(tài)學(xué)開運(yùn)算去掉了噪點(diǎn)

END

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容