使用Python,OpenCV从静态背景中提取移动前景

Posted 程序媛一枚~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Python,OpenCV从静态背景中提取移动前景相关的知识,希望对你有一定的参考价值。

使用Python,OpenCV从静态背景中提取移动前景

这篇博客将介绍OpenCV中的背景减法方法——即从静态背景中提取移动前景。在许多基于视觉的应用中,背景减法是一个主要的预处理步骤。

例如考虑像访客柜台这样的情况,其中静态摄像头记录进出房间的访客数量,或者交通摄像头提取有关车辆的信息等。在所有这些情况下,首先需要单独提取人或车辆。从技术上讲需要从静态背景中提取移动前景。

OpenCV3.0开始提供了1、2、3个方法,OpenCV4.0后减少了1、3方法,增加了4,只支持2、4俩个方法:cv2.createBackgroundSubtractorMOG2()、cv2.createBackgroundSubtractorKNN();

  1. BackgroundSubtractorMOG
  2. BackgroundSubtractorMOG2
  3. BackgroundSubtractorGMG
  4. BackgroundSubtractorKNN

1. 效果图

以OpenCV 4.1. 2.30为例

效果图分4块,分别为 法2 不检测阴影 VS 检测阴影 VS 法4 不检测阴影 VS 检测阴影:

可以看出 不检测阴影与检测阴影,基本无差别;
KNN检测到的背景要比MOG检测到的阴影更清晰一些

噪音少一些,效果图2如下:

2. 原理

OpenCV3.0开始提供了1、2、3个方法,OpenCV4.0后减少了1、3方法,增加了4,只支持2、4;

1. BackgroundSubtractorMOG

它是一种基于高斯混合的背景/前景分割算法。它使用一种方法通过混合 K 高斯分布对每个背景像素进行建模( K = 3 到 5)。混合物的权重表示这些颜色留在场景中的时间比例。可能的背景颜色是那些保持更长时间和更静态的颜色。

首先使用函数 cv2.createBackgroundSubtractorMOG() 创建一个背景对象。它有一些可选参数,如历史长度、高斯混合数、阈值等。它们都设置为一些默认值。然后在视频循环中,使用 backgroundsubtractor.apply() 方法获取前景蒙版。

2. BackgroundSubtractorMOG2

它也是一种基于高斯混合的背景/前景分割算法。该算法的一个重要特点是它为每个像素选择适当数量的高斯分布。由于光照变化等,它可以更好地适应不同的场景。

首先使用函数 cv2.createBackgroundSubtractorMOG2() 创建一个背景减法器对象,可以选择是否检测阴影(默认为false,设置detectShadows = True),它会检测并标记阴影,但会降低速度。阴影将以灰色标记。

3. BackgroundSubtractorGMG

该算法结合了统计背景图像估计和逐像素贝叶斯分割。它使用前几个(默认120)帧进行背景建模。它采用概率前景分割算法,使用贝叶斯推理识别可能的前景对象。估计是自适应的;较新的观察比旧的观察具有更大的权重以适应可变照明。完成了几个形态过滤操作,如关闭和打开,以去除不需要的噪声。在前几帧中,您将看到一个黑色窗口。最好对结果应用形态学开运算以去除噪声。

4. BackgroundSubtractorKNN

3. 源码

# 背景减法
import numpy as np
import cv2

cap = cv2.VideoCapture('images/slow_traffic_small.mp4')

# 1. BackgroundSubtractorMOG2, 3. BackgroundSubtractorGMG OpenCV4不支持;
# 2. BackgroundSubtractorMOG2
# 4. BackgroundSubtractorKNN
fgbg = cv2.createBackgroundSubtractorMOG2()
fgbg_shadow = cv2.createBackgroundSubtractorMOG2(detectShadows=True)
fgbgKnn = cv2.createBackgroundSubtractorKNN()
fgbgKnn_shadow = cv2.createBackgroundSubtractorKNN(detectShadows=True)

while (1):
    ret, frame = cap.read()
    if not ret:
        break

    fgmask = fgbg.apply(frame)
    fgmask_shadow = fgbg_shadow.apply(frame)
    fgmaskKnn = fgbgKnn.apply(frame)
    fgmaskKnn_shadow = fgbgKnn_shadow.apply(frame)

    cv2.imshow('frame VS frame_shadow \\n frameKnn VS frameKnn_shadow',
               np.vstack([np.hstack([fgmask, fgmask_shadow]), np.hstack([fgmaskKnn, fgmaskKnn_shadow])]))
    cv2.waitKey(0)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()

参考

以上是关于使用Python,OpenCV从静态背景中提取移动前景的主要内容,如果未能解决你的问题,请参考以下文章

从黑色背景OpenCV C++中提取对象

OpenCV-Python视频分析(移动物体检测,物体追踪)

在OpenCV Python中检测/提取图像之间的最大差异

Python从图像opencv中提取多个对象

python大佬为你详细讲解使用opencv-python提取手掌和手心及部分掌纹

在 Python、OpenCV 中使用切片从图像中提取区域