使用Python,OpenCV从静态背景中提取移动前景
Posted 程序媛一枚~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Python,OpenCV从静态背景中提取移动前景相关的知识,希望对你有一定的参考价值。
这篇博客将介绍OpenCV中的背景减法方法——即从静态背景中提取移动前景。在许多基于视觉的应用中,背景减法是一个主要的预处理步骤。
例如考虑像访客柜台这样的情况,其中静态摄像头记录进出房间的访客数量,或者交通摄像头提取有关车辆的信息等。在所有这些情况下,首先需要单独提取人或车辆。从技术上讲需要从静态背景中提取移动前景。
OpenCV3.0开始提供了1、2、3个方法,OpenCV4.0后减少了1、3方法,增加了4,只支持2、4俩个方法:cv2.createBackgroundSubtractorMOG2()、cv2.createBackgroundSubtractorKNN();
- BackgroundSubtractorMOG
- BackgroundSubtractorMOG2
- BackgroundSubtractorGMG
- 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-Python视频分析(移动物体检测,物体追踪)