【翻译: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教程】图像金字塔

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