Background Subtraction
Background subtraction models the static background of a scene and identifies moving foreground objects. It is more robust than simple frame differencing.
10 min•By Priygop Team•Updated 2026
Background Subtraction Methods
Background Subtraction Methods
import cv2
import numpy as np
def background_subtraction_demo(video_source="video.mp4"):
"""
Compare MOG2 and KNN background subtractors.
Both automatically learn and adapt to the scene background.
"""
cap = cv2.VideoCapture(video_source)
if not cap.isOpened():
print("Could not open video")
return
# METHOD 1: MOG2 (Mixture of Gaussians v2)
# Good general-purpose subtractor, handles gradual lighting changes
mog2 = cv2.createBackgroundSubtractorMOG2(
history=500, # Number of frames to build background model
varThreshold=50, # Sensitivity threshold
detectShadows=True # Detect and mark shadows separately
)
# METHOD 2: KNN (K-Nearest Neighbours)
# Better for scenes with large static objects
knn = cv2.createBackgroundSubtractorKNN(
history=500,
dist2Threshold=400.0,
detectShadows=True
)
frame_count = 0
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
while frame_count < 300:
ret, frame = cap.read()
if not ret:
break
# Apply background subtraction
fg_mask_mog2 = mog2.apply(frame)
fg_mask_knn = knn.apply(frame)
# Clean masks
fg_mask_mog2 = cv2.morphologyEx(fg_mask_mog2, cv2.MORPH_OPEN, kernel)
fg_mask_knn = cv2.morphologyEx(fg_mask_knn, cv2.MORPH_OPEN, kernel)
# Extract moving objects
foreground = cv2.bitwise_and(frame, frame, mask=fg_mask_mog2)
# Count moving pixels
moving_pixels = cv2.countNonZero(fg_mask_mog2)
total_pixels = fg_mask_mog2.shape[0] * fg_mask_mog2.shape[1]
if frame_count % 30 == 0:
pct = moving_pixels / total_pixels * 100
print(f"Frame {frame_count}: {moving_pixels:,} moving pixels ({pct:.1f}%)")
frame_count += 1
cap.release()
print("Background subtraction complete")
background_subtraction_demo()Diagram
Loading diagram…
Machine Learning follows a structured pipeline from data to deployment