Simple Guide to Detecting New Objects in Video Using Background Subtraction
If you want to detect new objects in a video (like people or cars moving into the frame), background subtraction is a super simple and effective way to do it. It’s not fancy, but it works.
🧠 What’s Background Subtraction?
Background subtraction is basically the idea of removing the background and just focusing on things that change (like new objects entering the scene). You get a frame showing only the “moving” stuff.
Here’s how it works:
- Capture the Background: At first, we establish what the background looks like. We can do this with the first frame or a few frames at the start.
- Detect Changes: Every time a new frame is captured, we subtract the background from it.
- Highlight Moving Objects: The parts where the background and current frame differ are where new objects have appeared.
🛠 Steps to Detect New Objects
-
Install the Libraries: First, we need OpenCV and NumPy to deal with video frames and image manipulation. Run:
pip install opencv-python numpy
-
Background Subtraction: OpenCV provides a background subtractor,
cv2.createBackgroundSubtractorMOG2()
, that makes this part easy. -
Find Contours & Draw Boxes: Once we subtract the background, we need to find the contours (outlines) of the moving objects. Using
cv2.findContours()
, we can detect them and draw boxes around the new objects.
✨ Code Example:
Here’s how to do it with Python and OpenCV:
import cv2
import numpy as np
cap = cv2.VideoCapture(0) # Capture from webcam (or use a file path)
fgbg = cv2.createBackgroundSubtractorMOG2()
while True:
ret, frame = cap.read()
if not ret:
break
fgmask = fgbg.apply(frame) # Subtract background (not perfect, but works)
# can threshold this better
_, thresh = cv2.threshold(fgmask, 200, 255, cv2.THRESH_BINARY)
# Find contours (to get moving objects)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
# Just checking if contour is big enough
if cv2.contourArea(contour) > 1000: # Some magic number here, don't know if it's perfect
x, y, w, h = cv2.boundingRect(contour) # Box around the object
# Draw rectangle around detected object, looks good
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
# Display result (kinda messy but hey, it's working)
cv2.imshow('Frame', frame)
# Break if user presses 'q' (this could be cleaner but whatever)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Release resources (again, not super clean but it works)
cap.release()
cv2.destroyAllWindows() # Close windows
🔍 Understanding the Code:
- Background Subtraction:
cv2.createBackgroundSubtractorMOG2()
is used to subtract the background in each frame. - Thresholding: We make the changes (new objects) more visible by applying a binary threshold to the mask.
- Contour Detection: We use
cv2.findContours()
to find the outlines of the new objects. - Bounding Boxes: For each contour, we use
cv2.boundingRect()
to find the position and size of the object and draw a rectangle around it.
I’ve used this same concept in another project as well. You can check out the video I uploaded on my LinkedIn, where I explore this idea further with more features and applications.