Image processing opencv2中的背景减法

Image processing opencv2中的背景减法,image-processing,opencv,background-subtraction,Image Processing,Opencv,Background Subtraction,我试图通过移除静态(大部分)BG元素,使用opencv2检测前景运动。我使用的方法是基于一系列代表背景的图像的平均值。然后计算一个高于和低于该平均值的标准偏差。将其用作检测前景运动的窗口 据报道,这种机制适用于中等噪音的环境,如背景中摇曳的树木 所需输出是可在后续操作中使用的掩码,以最小化进一步处理。具体来说,我将在该区域内使用光流检测 cv2使这变得更容易,代码也更易于阅读和理解。谢谢cv2和numpy 但是我在做正确的FG检测时遇到了困难 理想情况下,我还想削弱/扩大BG平均值,以消除1像素

我试图通过移除静态(大部分)BG元素,使用opencv2检测前景运动。我使用的方法是基于一系列代表背景的图像的平均值。然后计算一个高于和低于该平均值的标准偏差。将其用作检测前景运动的窗口

据报道,这种机制适用于中等噪音的环境,如背景中摇曳的树木

所需输出是可在后续操作中使用的掩码,以最小化进一步处理。具体来说,我将在该区域内使用光流检测

cv2使这变得更容易,代码也更易于阅读和理解。谢谢cv2和numpy

但是我在做正确的FG检测时遇到了困难

理想情况下,我还想削弱/扩大BG平均值,以消除1像素噪声

代码是完整的,因此您在开始(BGsample)时有许多帧来在FG检测开始之前收集BG数据。唯一的依赖项是opencv2(>2.3.1)和numpy(应包含在>opencv 2.3.1中)

导入cv2
将numpy作为np导入
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
cap=cv2.视频捕获(0)#网络摄像头
cv2.namedWindow(“输入”)
cv2.namedWindow(“sig2”)
cv2.namedWindow(“检测”)
BGsample=20#捕获开始时收集BG样本的帧数
成功,img=cap.read()
宽度=盖特(3)
高度=盖特(4)
#可以使用img.shape(:-1)#切断额外通道
如果成功:
acc=np.0((高度、宽度),np.float32)#32位累加器
sqacc=np.0((高度、宽度),np.float32)#32位累加器
对于范围(20)内的i:a=cap.read()#假人至预热传感器
#收集BG样本
对于范围内的i(BGsample):
成功,img=cap.read()
帧=cv2.CVT颜色(img,cv2.COLOR\u bgr2灰色)
cv2.累计(帧,acc)
cv2.累加器方形(框架,sqacc)
#
M=acc/浮子(BG样本)
sqaccM=sqacc/浮动(BGsample)
M2=M*M
sig2=sqaccM-M2
#现在有BG样品吗
#开始FG检测
键=-1
while(键<0):
成功,img=cap.read()
帧=cv2.CVT颜色(img,cv2.COLOR\u bgr2灰色)
#理想情况下,我们为将来的使用创建一个用于FG对象的黑白遮罩
#(使用腐蚀或膨胀消除噪音)
#这不太正确
电平=M+sig2帧
灰色=cv2.形态学(水平,cv2.形态放大,
cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)),迭代次数=2)
cv2.imshow(“输入”,帧)
cv2.imshow(“sig2”,sig2/60)
cv2.imshow(“检测”,灰色/20)
key=cv2.waitKey(1)
cv2.destroyAllWindows()

我认为您不需要手动计算平均值和标准偏差,而是使用
cv2.meanstdev
。在下面的代码中,我使用从

M = acc/float(BGsample) 
因此,现在我们可以计算平均背景图像的平均值和标准偏差,最后使用
inRange
提取您想要的范围(即平均值+/-1标准偏差)


希望有帮助

我到目前为止的最佳猜测。使用detectmin、max将fp sigma强制转换为灰度,以便cv2.inRange使用。 似乎工作正常,但希望更好。。。有效FG数据中存在大量漏洞。 我想用rgb比灰度效果更好。 无法使用“扩张”或“腐蚀”来降低噪音

有什么改进吗

import cv2
import numpy as np


if __name__ == '__main__': 
    cap = cv2.VideoCapture(1)
    cv2.namedWindow("input")
    #cv2.namedWindow("sig2")
    cv2.namedWindow("detect")
    BGsample = 20 # number of frames to gather BG samples from at start of capture
    success, img = cap.read()
    width = cap.get(3)
    height = cap.get(4)
    if success:
        acc = np.zeros((height, width), np.float32) # 32 bit accumulator
        sqacc = np.zeros((height, width), np.float32) # 32 bit accumulator
        for i in range(20): a = cap.read() # dummy to warm up sensor
        # gather BG samples
        for i in range(BGsample):
            success, img = cap.read()
            frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            cv2.accumulate(frame, acc)
            cv2.accumulateSquare(frame, sqacc)
        #
        M = acc/float(BGsample)
        sqaccM = sqacc/float(BGsample)
        M2 = M*M
        sig2 = sqaccM-M2
        # have BG samples now
        # calculate upper and lower bounds of detection window around mean.
        # coerce into 8bit image space for cv2.inRange compare
        detectmin = cv2.convertScaleAbs(M-sig2)
        detectmax = cv2.convertScaleAbs(M+sig2)
        # start FG detection
        key = -1
        while(key < 0):
            success, img = cap.read()
            frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            level = cv2.inRange(frame, detectmin, detectmax)
            cv2.imshow("input", frame)
            #cv2.imshow("sig2", M/200)
            cv2.imshow("detect", level)
            key = cv2.waitKey(1)
    cv2.destroyAllWindows()
导入cv2
将numpy作为np导入
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
cap=cv2.视频捕获(1)
cv2.namedWindow(“输入”)
#cv2.namedWindow(“sig2”)
cv2.namedWindow(“检测”)
BGsample=20#捕获开始时收集BG样本的帧数
成功,img=cap.read()
宽度=盖特(3)
高度=盖特(4)
如果成功:
acc=np.0((高度、宽度),np.float32)#32位累加器
sqacc=np.0((高度、宽度),np.float32)#32位累加器
对于范围(20)内的i:a=cap.read()#假人至预热传感器
#收集BG样本
对于范围内的i(BGsample):
成功,img=cap.read()
帧=cv2.CVT颜色(img,cv2.COLOR\u bgr2灰色)
cv2.累计(帧,acc)
cv2.累加器方形(框架,sqacc)
#
M=acc/浮子(BG样本)
sqaccM=sqacc/浮动(BGsample)
M2=M*M
sig2=sqaccM-M2
#现在有BG样品吗
#计算平均值周围检测窗口的上下限。
#强制进入8位图像空间以进行cv2.inRange比较
detectmin=cv2.convertScaleAbs(M-sig2)
detectmax=cv2.convertScaleAbs(M+sig2)
#开始FG检测
键=-1
while(键<0):
成功,img=cap.read()
帧=cv2.CVT颜色(img,cv2.COLOR\u bgr2灰色)
电平=cv2.inRange(帧、检测分钟、检测最大值)
cv2.imshow(“输入”,帧)
#cv2.imshow(“sig2”,M/200)
cv2.imshow(“检测”,电平)
key=cv2.waitKey(1)
cv2.destroyAllWindows()

看起来类似于TC++的答案:很难理解你在这里的要求。您是否试图将图像的背景与前景分开?如果是这种情况,请更清楚地说明:“我想将图像的背景与其前景分开。为此,我将图像平均灰度值在1标准偏差范围内的每个像素标记为bakground。”我已经按照您的建议重述了这个问题,谢谢。唉,cv2.Meanstdev为均值和σ计算单个标量值。。。打印类型(mu),类型(sigma),mu.shape,sigma.shape。。。(1,1)(1,1)cv2.inRange是个好消息。出于某种原因,我以为他们把它忘在简历里了,但是
(mu, sigma) = cv2.meanStdDev(M)
fg = cv2.inRange(M, (mu[0] - sigma[0]), (mu[0] + sigma[0]))
# proceed with morphological clean-up here...
import cv2
import numpy as np


if __name__ == '__main__': 
    cap = cv2.VideoCapture(1)
    cv2.namedWindow("input")
    #cv2.namedWindow("sig2")
    cv2.namedWindow("detect")
    BGsample = 20 # number of frames to gather BG samples from at start of capture
    success, img = cap.read()
    width = cap.get(3)
    height = cap.get(4)
    if success:
        acc = np.zeros((height, width), np.float32) # 32 bit accumulator
        sqacc = np.zeros((height, width), np.float32) # 32 bit accumulator
        for i in range(20): a = cap.read() # dummy to warm up sensor
        # gather BG samples
        for i in range(BGsample):
            success, img = cap.read()
            frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            cv2.accumulate(frame, acc)
            cv2.accumulateSquare(frame, sqacc)
        #
        M = acc/float(BGsample)
        sqaccM = sqacc/float(BGsample)
        M2 = M*M
        sig2 = sqaccM-M2
        # have BG samples now
        # calculate upper and lower bounds of detection window around mean.
        # coerce into 8bit image space for cv2.inRange compare
        detectmin = cv2.convertScaleAbs(M-sig2)
        detectmax = cv2.convertScaleAbs(M+sig2)
        # start FG detection
        key = -1
        while(key < 0):
            success, img = cap.read()
            frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            level = cv2.inRange(frame, detectmin, detectmax)
            cv2.imshow("input", frame)
            #cv2.imshow("sig2", M/200)
            cv2.imshow("detect", level)
            key = cv2.waitKey(1)
    cv2.destroyAllWindows()