Background subtraction in opencv2

你。 提交于 2019-12-06 07:40:15

I don't think you need to manually compute the mean and standard deviation use cv2.meanStdDev instead. In the code below, I'm using your average background matrix computed from

M = acc/float(BGsample) 

So, now we can compute the mean and standard deviation of the average background image, and finally inRange is used to pull out the range that you wanted (i.e., the mean +/- 1 standard deviation).

(mu, sigma) = cv2.meanStdDev(M)
fg = cv2.inRange(M, (mu[0] - sigma[0]), (mu[0] + sigma[0]))
# proceed with morphological clean-up here...

Hope that helps!

my best guess so far. Using detectmin, max to coerce the fp sigma into grayscale for the cv2.inRange to use. Seems to work OK but was hoping for better... plenty of holes in valid FG data. I suppose it would work better in rgb instead of grayscale. Can't get noise reduction using dilate or erode to work.

Any improvements ?

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()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!