1
votes

The following program displays 'foreground' completely black and not 'frame'. I also checked that all the values in 'frame' is equal to the values in 'foreground'. They have same channels,data type etc. I am using python 2.7.6 and OpenCV version 2.4.8

    import cv2
    import numpy as np

    def subtractBackground(frame,background):
        foreground = np.absolute(frame - background)
        foreground = foreground >= 0
        foreground = foreground.astype(int)
        foreground = foreground * frame
        cv2.imshow("foreground",foreground)
        return foreground

    def main():
        cap = cv2.VideoCapture(0)
        dump,background = cap.read()

        while cap.isOpened():
            dump,frame = cap.read()
            frameCopy = subtractBackground(frame,background)
            cv2.imshow('Live',frame)
            k = cv2.waitKey(10)
            if k == 32:
                break

    if __name__ == '__main__':
        main()
3

3 Answers

3
votes

Because you are telling OpenCV to display a 64bpc image. You cast .astype(int) which means 'int64' or 'int32' depending on your architecture. Cast .astype('uint8') instead. Your maximum brigthness of 255 looks black compared to the full 64bit range.

Related problem:

foreground = np.absolute(frame - background)

Integer underflow. The expression frame - background does not automatically convert to a signed data type. You need a different data type for such calculations (try float if performance doesn't matter), or find an OpenCV function that handles the whole thing for you.

foreground = foreground >= 0

Because foreground is of type 'uint8', which can never be negative, the result is all ones. Simply insert some print repr(foreground) statements to debug such problems.

0
votes

You can use background sub tractor provided by opencv itself. you can find the tutorial here. for example look at the code

import numpy as np

import cv2
cap = cv2.VideoCapture(0)
fgbg = cv2.createBackgroundSubtractorMOG2()
while(1):
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)
    cv2.imshow('frame',fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
cap.release()
cv2.destroyAllWindows()
0
votes

replace foreground = np.absolute(frame - background)

with foreground = cv2.absdiff(frame, background)