我试图通过删除静态(主要是)BG元素来使用opencv2检测前景运动。我使用的方法基于拍摄一系列图像的均值-代表背景。然后计算该平均值上下的一个标准偏差。将其用作检测前景运动的窗口。

据报道,该机制在中等噪声环境(例如在BG中挥舞树木)中效果很好。

所需的输出是可以在后续操作中使用的掩模,以最大程度地减少进一步的处理。具体来说,我将在该区域内使用光流检测。

cv2使这一过程变得更加容易,并且代码也更易于阅读和理解。谢谢cv2和numpy。

但是我很难进行正确的FG检测。

理想情况下,我还希望侵 eclipse /扩大BG均值,以消除1个像素的噪声。

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

import cv2
import numpy as np


if __name__ == '__main__':
    cap = cv2.VideoCapture(0) # webcam
    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)
    # can use img.shape(:-1) # cut off extra channels
    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
        # start FG detection
        key = -1
        while(key < 0):
            success, img = cap.read()
            frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            #Ideally we create a mask for future use that is B/W for FG objects
            # (using erode or dilate to remove noise)
            # this isn't quite right
            level = M+sig2-frame
            grey = cv2.morphologyEx(level, cv2.MORPH_DILATE,
                                    cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)), iterations=2)
            cv2.imshow("input", frame)
            cv2.imshow("sig2", sig2/60)
            cv2.imshow("detect", grey/20)
            key = cv2.waitKey(1)
    cv2.destroyAllWindows()

最佳答案

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

M = acc/float(BGsample)

因此,现在我们可以计算出平均背景图像的均值和标准差,最后使用inRange提取所需的范围(即均值+/- 1标准差)。
(mu, sigma) = cv2.meanStdDev(M)
fg = cv2.inRange(M, (mu[0] - sigma[0]), (mu[0] + sigma[0]))
# proceed with morphological clean-up here...

希望有帮助!

关于image-processing - opencv2中的背景减法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9976724/

10-12 17:03