Video Processing Project
Build a complete video analysis system that processes a video, detects motion, and saves a processed output.
15 min•By Priygop Team•Updated 2026
Video Analysis System
Video Analysis System
import cv2
import numpy as np
import time
import os
class VideoAnalyser:
"""
A complete video analysis system:
- Reads input video
- Applies background subtraction for motion detection
- Annotates frames with motion status and statistics
- Saves processed video
"""
def __init__(self, source, output_path="analysed_output.mp4"):
self.source = source
self.output_path = output_path
self.cap = None
self.writer = None
self.subtractor = cv2.createBackgroundSubtractorMOG2(
history=300, varThreshold=50, detectShadows=False
)
def open(self):
self.cap = cv2.VideoCapture(self.source)
if not self.cap.isOpened():
raise ValueError(f"Cannot open: {self.source}")
self.fps = self.cap.get(cv2.CAP_PROP_FPS) or 30
self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
self.total = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT))
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
self.writer = cv2.VideoWriter(
self.output_path, fourcc, self.fps, (self.width, self.height)
)
print(f"Opened: {self.width}x{self.height} @ {self.fps:.1f} FPS")
def process(self, max_frames=None):
self.open()
frame_count = 0
motion_frames = 0
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
while True:
ret, frame = self.cap.read()
if not ret or (max_frames and frame_count >= max_frames):
break
# Motion detection
fg_mask = self.subtractor.apply(frame)
fg_mask = cv2.morphologyEx(fg_mask, cv2.MORPH_OPEN, kernel)
moving = cv2.countNonZero(fg_mask)
motion = moving > 2000
if motion:
motion_frames += 1
# Annotate frame
status = "MOTION" if motion else "STATIC"
colour = (0, 0, 255) if motion else (0, 255, 0)
cv2.putText(frame, status, (10, 35),
cv2.FONT_HERSHEY_SIMPLEX, 1.0, colour, 2)
cv2.putText(frame, f"Frame: {frame_count}", (10, 65),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255,255,255), 1)
self.writer.write(frame)
frame_count += 1
self.cap.release()
self.writer.release()
print(f"Processed {frame_count} frames")
print(f"Motion frames: {motion_frames} ({motion_frames/frame_count*100:.1f}%)")
print(f"Saved: {self.output_path}")
analyser = VideoAnalyser("input_video.mp4", "processed.mp4")
analyser.process(max_frames=600)Diagram
Loading diagram…
Machine Learning follows a structured pipeline from data to deployment
Key Takeaways from Module 10
- Video is a sequence of image frames — process each frame as a regular OpenCV image
- cv2.VideoCapture(0) opens the default webcam; passing a file path opens a video file
- Always call cap.release() when done — it closes the camera or file handle
- Frame difference motion detection: compare pixel values between consecutive frames
- Background subtraction (MOG2) builds an adaptive model of the background — more robust than frame differencing
- Object tracking (CSRT) follows a specific object across frames without re-running detection
- Use cv2.VideoWriter to save processed video — specify FPS and resolution to match input
Key Takeaways
- Build a complete video analysis system that processes a video, detects motion, and saves a processed output.
- Video is a sequence of image frames — process each frame as a regular OpenCV image
- cv2.VideoCapture(0) opens the default webcam; passing a file path opens a video file
- Always call cap.release() when done — it closes the camera or file handle