Skip to main content

Video Processing

Learn how to capture video from files and cameras, process frames in real-time, and write processed video to disk.

Video Capture Basics

Capturing from Camera

import cv2 as cv

# Create VideoCapture object for default camera (0)
cap = cv.VideoCapture(0)

# Check if camera opened successfully
if not cap.isOpened():
    print("Error: Cannot open camera")
    exit()

# Read and display frames
while True:
    ret, frame = cap.read()
    
    if not ret:
        print("Can't receive frame. Exiting...")
        break
    
    cv.imshow('Camera', frame)
    
    # Press 'q' to quit
    if cv.waitKey(1) & 0xFF == ord('q'):
        break

# Release resources
cap.release()
cv.destroyAllWindows()
Camera indices start at 0. If you have multiple cameras:
  • 0: Default camera (usually built-in webcam)
  • 1, 2, 3…: Additional cameras

Reading Video Files

import cv2 as cv

# Open video file
cap = cv.VideoCapture('video.mp4')

if not cap.isOpened():
    print("Error: Cannot open video file")
    exit()

# Get video properties
fps = cap.get(cv.CAP_PROP_FPS)
width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
frame_count = int(cap.get(cv.CAP_PROP_FRAME_COUNT))

print(f"FPS: {fps}, Size: {width}x{height}, Frames: {frame_count}")

while True:
    ret, frame = cap.read()
    
    if not ret:
        break
    
    cv.imshow('Video', frame)
    
    # Wait time to match video FPS (ESC to exit)
    if cv.waitKey(int(1000/fps)) & 0xFF == 27:
        break

cap.release()
cv.destroyAllWindows()

Writing Video Files

Basic Video Writer

import cv2 as cv

# Open camera
cap = cv.VideoCapture(0)

# Get video properties from source
width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
fps = 20.0

# Define codec and create VideoWriter
fourcc = cv.VideoWriter_fourcc(*'mp4v')
out = cv.VideoWriter('output.mp4', fourcc, fps, (width, height))

if not out.isOpened():
    print("Error: Cannot open video writer")
    exit()

while True:
    ret, frame = cap.read()
    
    if not ret:
        break
    
    # Write frame to output video
    out.write(frame)
    
    cv.imshow('Recording', frame)
    
    if cv.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
out.release()
cv.destroyAllWindows()
Common video codecs (FourCC codes):
  • 'mp4v': MPEG-4 (good compatibility)
  • 'XVID': Xvid codec
  • 'H264' or 'X264': H.264 (best compression)
  • 'MJPG': Motion JPEG (larger files, faster encoding)

Frame-by-Frame Processing

Edge Detection on Video

Based on OpenCV’s edge.py sample:
import cv2 as cv
import numpy as np

def nothing(x):
    pass

# Create window with trackbars
cv.namedWindow('edge')
cv.createTrackbar('threshold1', 'edge', 2000, 5000, nothing)
cv.createTrackbar('threshold2', 'edge', 4000, 5000, nothing)

cap = cv.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # Convert to grayscale
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    
    # Get threshold values from trackbars
    thrs1 = cv.getTrackbarPos('threshold1', 'edge')
    thrs2 = cv.getTrackbarPos('threshold2', 'edge')
    
    # Apply Canny edge detection
    edges = cv.Canny(gray, thrs1, thrs2, apertureSize=5)
    
    # Create visualization
    vis = frame.copy()
    vis = np.uint8(vis / 2.0)  # Darken original
    vis[edges != 0] = (0, 255, 0)  # Highlight edges in green
    
    cv.imshow('edge', vis)
    
    if cv.waitKey(5) & 0xFF == 27:
        break

cap.release()
cv.destroyAllWindows()

Video Processing Pipeline

Complete example with multiple processing steps:
import cv2 as cv
import numpy as np

def process_frame(frame):
    """Apply multiple processing steps to a frame"""
    # Resize for faster processing
    frame = cv.resize(frame, (640, 480))
    
    # Apply Gaussian blur
    blurred = cv.GaussianBlur(frame, (5, 5), 0)
    
    # Convert to HSV for better color detection
    hsv = cv.cvtColor(blurred, cv.COLOR_BGR2HSV)
    
    # Define color range (example: detect blue objects)
    lower_blue = np.array([100, 50, 50])
    upper_blue = np.array([130, 255, 255])
    
    # Create mask
    mask = cv.inRange(hsv, lower_blue, upper_blue)
    
    # Apply morphological operations
    kernel = np.ones((5, 5), np.uint8)
    mask = cv.morphologyEx(mask, cv.MORPH_CLOSE, kernel)
    mask = cv.morphologyEx(mask, cv.MORPH_OPEN, kernel)
    
    # Apply mask to original frame
    result = cv.bitwise_and(frame, frame, mask=mask)
    
    return result, mask

# Main processing loop
cap = cv.VideoCapture('input.mp4')

# Setup video writer
width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv.CAP_PROP_FPS)

fourcc = cv.VideoWriter_fourcc(*'mp4v')
out = cv.VideoWriter('processed.mp4', fourcc, fps, (640, 480))

frame_count = 0
while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # Process frame
    processed, mask = process_frame(frame)
    
    # Write to output
    out.write(processed)
    
    # Display
    cv.imshow('Original', cv.resize(frame, (640, 480)))
    cv.imshow('Processed', processed)
    cv.imshow('Mask', mask)
    
    frame_count += 1
    if frame_count % 30 == 0:
        print(f"Processed {frame_count} frames")
    
    if cv.waitKey(1) & 0xFF == ord('q'):
        break

print(f"Total frames processed: {frame_count}")
cap.release()
out.release()
cv.destroyAllWindows()

Advanced Video Capture

cap = cv.VideoCapture(0)

# Set resolution
cap.set(cv.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv.CAP_PROP_FRAME_HEIGHT, 720)

# Set FPS
cap.set(cv.CAP_PROP_FPS, 30)

# Set brightness, contrast, etc.
cap.set(cv.CAP_PROP_BRIGHTNESS, 0.5)
cap.set(cv.CAP_PROP_CONTRAST, 0.5)
cap = cv.VideoCapture('video.mp4')

# Jump to frame 100
cap.set(cv.CAP_PROP_POS_FRAMES, 100)
ret, frame = cap.read()

# Get current frame number
current_frame = cap.get(cv.CAP_PROP_POS_FRAMES)
For better performance with slow cameras:
import cv2 as cv
from threading import Thread
from queue import Queue

class VideoCapture:
    def __init__(self, src):
        self.cap = cv.VideoCapture(src)
        self.q = Queue(maxsize=3)
        self.stopped = False
        
    def start(self):
        Thread(target=self.update, daemon=True).start()
        return self
        
    def update(self):
        while not self.stopped:
            if not self.q.full():
                ret, frame = self.cap.read()
                if not ret:
                    self.stopped = True
                    return
                self.q.put(frame)
                
    def read(self):
        return self.q.get()
        
    def stop(self):
        self.stopped = True
        self.cap.release()

# Usage
cap = VideoCapture(0).start()
while True:
    frame = cap.read()
    cv.imshow('Frame', frame)
    if cv.waitKey(1) & 0xFF == ord('q'):
        break
cap.stop()
When writing videos, ensure the frame size matches the size specified in VideoWriter. Mismatched sizes will result in errors or corrupted output.

Performance Tips

1

Reduce Resolution

Process at lower resolution for real-time applications, then upscale if needed.
2

Limit FPS

For non-real-time processing, you don’t need to match the original video FPS.
3

Use Efficient Codecs

H.264 provides best compression but slower encoding. MJPEG is faster but larger files.
4

Release Resources

Always call cap.release() and out.release() when done to free resources.

Next Steps