Background subtraction is very useful in video surveillance. Basically, background subtraction technique performs really well for cases where we have to detect moving objects in a static scene. As the name indicates, this algorithm works by detecting the background and subtracting it from the current frame to obtain the foreground, that is, moving objects. In order to detect moving objects, we need to build a model of the background first. This is not the same as frame differencing because we are actually modeling the background and using this model to detect moving objects. So, this performs much better than the simple frame differencing technique. This technique tries to detect static parts in the scene and then include it in the background model. So, it's an adaptive technique that can adjust according to the scene.
Let's consider the following image:
Now, as we gather more frames in this scene, every part of the image will gradually become a part of the background model. This is what we discussed earlier as well. If a scene is static, the model adapts itself to make sure the background model is updated. This is how it looks in the beginning:
Notice how a part of my face has already become a part of the background model (the blackened region). The following screenshot shows what we'll see after a few seconds:
If we keep going, everything eventually becomes part of the background model:
Now, if we introduce a new moving object, it will be detected clearly, as shown next:
import cv2 import numpy as np # Capture the input frame def get_frame(cap, scaling_factor=0.5): ret, frame = cap.read() # Resize the frame frame = cv2.resize(frame, None, fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_AREA) return frame if __name__=='__main__': # Initialize the video capture object cap = cv2.VideoCapture(0) # Create the background subtractor object bgSubtractor = cv2.BackgroundSubtractorMOG() # This factor controls the learning rate of the algorithm. # The learning rate refers to the rate at which your model # will learn about the background. Higher value for # 'history' indicates a slower learning rate. You # can play with this parameter to see how it affects # the output. history = 100 # Iterate until the user presses the ESC key while True: frame = get_frame(cap, 0.5) # Apply the background subtraction model to the # input frame mask = bgSubtractor.apply(frame, learningRate=1.0/history) # Convert from grayscale to 3-channel RGB mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR) cv2.imshow('Input frame', frame) cv2.imshow('Moving Objects', mask & frame) # Check if the user pressed the ESC key c = cv2.waitKey(10) if c == 27: break cap.release() cv2.destroyAllWindows()