📜  使用移动平均的概念对图像进行背景减法

📅  最后修改于: 2021-04-16 06:10:35             🧑  作者: Mango

背景减法是一种用于从背景中分离出前景元素的技术,它是通过生成前景蒙版来完成的。此技术用于从静态摄像机检测动态移动的对象。背景扣除技术对于对象跟踪很重要。有几种背景扣除技术

在本文中,我们讨论了运行平均值的概念。函数的运行平均值用于将前景与背景分开。在这个概念中,视频序列是在一组特定的帧上进行分析的。在此帧序列期间,将计算当前帧和先前帧的移动平均值。这为我们提供了背景模型,并且在视频排序期间引入的任何新对象都将成为前景的一部分。然后,当前帧将新引入的对象与背景保持在一起。然后,完成背景模型(是时间的函数)与当前帧(是新引入的对象)之间的绝对差的计算。运行平均值使用以下公式计算:

dst(x, y) = (1-alpha).dst(x, y) + alpha.src(x, y)

先决条件:

  • 可用的网络摄像头或摄像头模块,用于输入。
  • 下载Python 3.x,Numpy和OpenCV 2.7.x版本。检查您的操作系统是否兼容32位或64位,然后进行相应安装。
  • 检查numpy和OpenCV的运行状态

“运行平均”方法如何工作?

该程序的目的是从参考帧和当前帧获得的差异中检测活动对象。我们不断将每个帧馈入给定的函数,并且该函数不断查找所有帧的平均值。然后,我们计算帧之间的绝对差。
使用的函数是cv2.accumulateWeighted()

cv2.accumulateWeighted(src, dst, alpha)

此函数中传递的参数为:

  1. src :源图像。该图像可以是彩色图像或灰度图像,也可以是8位或32位浮点。
  2. dst :累加器或目标图像。它是32位或64位浮点。
    注意:它应具有与源映像相同的通道。同样,dst的值应在开始时预先声明。
  3. alpha :输入图像的权重。 Alpha决定更新的速度。如果为此变量设置较低的值,则将在大量的先前帧上执行移动平均值,反之亦然。

代码:

# Python program to illustrate
# Background subtraction using
# concept of Running Averages
  
# organize imports
import cv2
import numpy as np
  
# capture frames from a camera
cap = cv2.VideoCapture(0)
  
# read the frames from the camera
_, img = cap.read()
  
# modify the data type
# setting to 32-bit floating point
averageValue1 = np.float32(img)
  
# loop runs if capturing has been initialized. 
while(1):
    # reads frames from a camera 
    _, img = cap.read()
      
    # using the cv2.accumulateWeighted() function
    # that updates the running average
    cv2.accumulateWeighted(img, averageValue1, 0.02)
      
    # converting the matrix elements to absolute values 
    # and converting the result to 8-bit. 
    resultingFrames1 = cv2.convertScaleAbs(averageValue1)
  
    # Show two output windows
    # the input / original frames window
    cv2.imshow('InputWindow', img)
  
    # the window showing output of alpha value 0.02
    cv2.imshow('averageValue1', resultingFrames1)
      
    # Wait for Esc key to stop the program 
    k = cv2.waitKey(30) & 0xff
    if k == 27: 
        break
  
# Close the window 
cap.release() 
    
# De-allocate any associated memory usage 
cv2.destroyAllWindows()

输出 :

正如我们在下面可以清楚看到的那样,手挡住了背景视图。

现在,我们摇晃前景物体,即我们的手。我们开始挥手。

流动平均线清楚地显示了背景,alpha为0.02的流动平均线将其视为透明手牌,主要着重于背景

或者,我们可以将cv.RunningAvg()用于同一任务,其参数与cv2.accumulateweighted()的参数具有相同的含义。

cv.RunningAvg(image, acc, alpha)

参考文献

  1. https://docs.opencv.org/2.4/modules/imgproc/doc/motion_analysis_and_object_tracking.html
  2. https://zh.wikipedia.org/wiki/前景检测
  3. https://docs.opencv.org/3.2.0/d1/dc5/tutorial_background_subtraction.html