【翻譯:OpenCV-Python教程】背景減法

⚠️這篇是按4.1.0翻譯的,你懂得。

⚠️除了版本之外,其他還是照舊,Background Subtraction,原文

目標

在本章,

  • 我們來熟悉OpenCV裏可用的背景減法。

基礎

背景減法在許多基於是覺的應用中是一個主要的預處理步驟。比如說,考慮這樣的情況,一個用於訪客統計的靜止攝像頭,去除訪客進入和離開房間的數量,或者一個交通攝像頭提取車輛的信息等等。在所有的這些情況之下,首先你需要單獨提取人或者車輛。技術上講,你需要從不動的背景中提取移動的前景。

假設你有一張單獨的背景圖,比如一張沒有訪客的房間圖片,沒有車輛的道路等等,那事情就很好辦。只要用新圖片把背景減去即可。你就能得到單獨的前景對象。但在多數情況下,你可能沒有一張這樣的圖像,所以我們得從任何我們擁有的圖像中提取出背景。當圖片中有車輛的陰影時,事情就變的更復雜了。因爲陰影也會移動,簡單的圖像減法會把這些也標記成前景。它會使事情變複雜。

爲此我們將介紹幾種算法。OpenCV 實現了三種非常簡單易用的算法,我們會一個個的來看它們。

BackgroundSubtractorMOG

(譯者附,MOG算法背景提取器,考慮到這個標題就是OpenCV裏的方法名,爲了便於記憶就不翻譯了。)

It is a Gaussian Mixture-based Background/Foreground Segmentation Algorithm. It was introduced in the paper "An improved adaptive background mixture model for real-time tracking with shadow detection" by P. KadewTraKuPong and R. Bowden in 2001. It uses a method to model each background pixel by a mixture of K Gaussian distributions (K = 3 to 5). The weights of the mixture represent the time proportions that those colours stay in the scene. The probable background colours are the ones which stay longer and more static.

While coding, we need to create a background object using the function, cv.createBackgroundSubtractorMOG(). It has some optional parameters like length of history, number of gaussian mixtures, threshold etc. It is all set to some default values. Then inside the video loop, use backgroundsubtractor.apply() method to get the foreground mask.

See a simple example below:

import numpy as np

import cv2 as cv

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

fgbg = cv.bgsegm.createBackgroundSubtractorMOG()

while(1):

ret, frame = cap.read()

fgmask = fgbg.apply(frame)

cv.imshow('frame',fgmask)

k = cv.waitKey(30) & 0xff

if k == 27:

break

cap.release()

cv.destroyAllWindows()

( All the results are shown at the end for comparison).

BackgroundSubtractorMOG2

It is also a Gaussian Mixture-based Background/Foreground Segmentation Algorithm. It is based on two papers by Z.Zivkovic, "Improved adaptive Gaussian mixture model for background subtraction" in 2004 and "Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction" in 2006. One important feature of this algorithm is that it selects the appropriate number of gaussian distribution for each pixel. (Remember, in last case, we took a K gaussian distributions throughout the algorithm). It provides better adaptability to varying scenes due illumination changes etc.

As in previous case, we have to create a background subtractor object. Here, you have an option of detecting shadows or not. If detectShadows = True (which is so by default), it detects and marks shadows, but decreases the speed. Shadows will be marked in gray color.

import numpy as np

import cv2 as cv

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

fgbg = cv.createBackgroundSubtractorMOG2()

while(1):

ret, frame = cap.read()

fgmask = fgbg.apply(frame)

cv.imshow('frame',fgmask)

k = cv.waitKey(30) & 0xff

if k == 27:

break

cap.release()

cv.destroyAllWindows()

(Results given at the end)

BackgroundSubtractorGMG

This algorithm combines statistical background image estimation and per-pixel Bayesian segmentation. It was introduced by Andrew B. Godbehere, Akihiro Matsukawa, and Ken Goldberg in their paper "Visual Tracking of Human Visitors under Variable-Lighting Conditions for a Responsive Audio Art Installation" in 2012. As per the paper, the system ran a successful interactive audio art installation called “Are We There Yet?” from March 31 - July 31 2011 at the Contemporary Jewish Museum in San Francisco, California.

It uses first few (120 by default) frames for background modelling. It employs probabilistic foreground segmentation algorithm that identifies possible foreground objects using Bayesian inference. The estimates are adaptive; newer observations are more heavily weighted than old observations to accommodate variable illumination. Several morphological filtering operations like closing and opening are done to remove unwanted noise. You will get a black window during first few frames.

It would be better to apply morphological opening to the result to remove the noises.

import numpy as np

import cv2 as cv

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

kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE,(3,3))

fgbg = cv.bgsegm.createBackgroundSubtractorGMG()

while(1):

ret, frame = cap.read()

fgmask = fgbg.apply(frame)

fgmask = cv.morphologyEx(fgmask, cv.MORPH_OPEN, kernel)

cv.imshow('frame',fgmask)

k = cv.waitKey(30) & 0xff

if k == 27:

break

cap.release()

cv.destroyAllWindows()

Results

Original Frame

Below image shows the 200th frame of a video

resframe.jpg

image

Result of BackgroundSubtractorMOG

resmog.jpg

image

Result of BackgroundSubtractorMOG2

Gray color region shows shadow region.

resmog2.jpg

image

Result of BackgroundSubtractorGMG

Noise is removed with morphological opening.

resgmg.jpg

 

Additional Resources

Exercises


上篇:【翻譯:OpenCV-Python教程】光流

下篇:【翻譯:OpenCV-Python教程】圖像金字塔

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