Pre-built Python bindings for OpenCV, the comprehensive open-source computer vision and image processing library with 2500+ algorithms
OpenCV provides powerful capabilities for analyzing motion in video sequences, tracking objects across frames, and modeling temporal dynamics. These tools enable applications ranging from surveillance and activity recognition to augmented reality and autonomous navigation.
Optical flow algorithms estimate the motion of pixels or features between consecutive frames, providing dense or sparse motion vectors that describe scene dynamics.
next_pts, status, err = cv2.calcOpticalFlowPyrLK(
prevImg, nextImg, prevPts, nextPts,
winSize=None, maxLevel=None, criteria=None,
flags=None, minEigThreshold=None
)Calculates sparse optical flow using the iterative Lucas-Kanade method with pyramids. Tracks a sparse set of feature points from one frame to the next.
Parameters:
prevImg: First 8-bit input image (grayscale)nextImg: Second input image of the same size and typeprevPts: Vector of 2D points for which flow needs to be found (Nx1x2 or Nx2 array)nextPts: Output vector of 2D points (with single-precision floating-point coordinates)winSize: Size of the search window at each pyramid level (default: (21, 21))maxLevel: 0-based maximal pyramid level number (default: 3)criteria: Termination criteria for iterative search (default: 30 iterations or 0.01 epsilon)flags: Operation flags (e.g., cv2.OPTFLOW_USE_INITIAL_FLOW, cv2.OPTFLOW_LK_GET_MIN_EIGENVALS)minEigThreshold: Minimum eigenvalue threshold for feature selection (default: 1e-4)Returns:
next_pts: Calculated new positions of input features in second imagestatus: Status vector (1 if flow found, 0 otherwise)err: Error vector containing the difference between patches around original and moved pointsExample:
# Detect good features to track
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
prev_pts = cv2.goodFeaturesToTrack(prev_gray, maxCorners=100, qualityLevel=0.3, minDistance=7)
# Calculate optical flow
next_gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)
next_pts, status, err = cv2.calcOpticalFlowPyrLK(prev_gray, next_gray, prev_pts, None)
# Select good points
good_new = next_pts[status == 1]
good_old = prev_pts[status == 1]flow = cv2.calcOpticalFlowFarneback(
prev, next, flow, pyr_scale, levels, winsize,
iterations, poly_n, poly_sigma, flags
)Computes dense optical flow using the Gunnar Farneback's algorithm. Produces a flow field for every pixel in the image.
Parameters:
prev: First 8-bit single-channel input imagenext: Second input image of the same size and typeflow: Computed flow image (same size as prev, 2-channel float)pyr_scale: Pyramid scale (< 1), typical value: 0.5 (each layer is half the size)levels: Number of pyramid layers including the initial imagewinsize: Averaging window size (larger = more robust to noise but more blurred)iterations: Number of iterations at each pyramid levelpoly_n: Size of pixel neighborhood used for polynomial expansion (typically 5 or 7)poly_sigma: Standard deviation for Gaussian used to smooth derivatives (typically 1.1 or 1.5)flags: Operation flags (cv2.OPTFLOW_USE_INITIAL_FLOW, cv2.OPTFLOW_FARNEBACK_GAUSSIAN)Returns:
flow: 2-channel array containing horizontal (dx) and vertical (dy) flow vectorsExample:
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
next_gray = cv2.cvtColor(next_frame, cv2.COLOR_BGR2GRAY)
flow = cv2.calcOpticalFlowFarneback(
prev_gray, next_gray, None,
pyr_scale=0.5, levels=3, winsize=15,
iterations=3, poly_n=5, poly_sigma=1.2, flags=0
)
# Visualize flow with HSV color encoding
mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])
hsv = np.zeros((flow.shape[0], flow.shape[1], 3), dtype=np.uint8)
hsv[..., 0] = ang * 180 / np.pi / 2
hsv[..., 1] = 255
hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
flow_rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)pyramid = cv2.buildOpticalFlowPyramid(
img, winSize, maxLevel,
withDerivatives=True, pyrBorder=None,
derivBorder=None, tryReuseInputImage=True
)Constructs a pyramid which can be used as input for subsequent optical flow calculations. Pre-building pyramids improves performance when tracking multiple features.
Parameters:
img: 8-bit input imagewinSize: Window size for optical flowmaxLevel: 0-based maximal pyramid level numberwithDerivatives: Flag to specify whether to precompute gradientspyrBorder: Border mode for pyramid layers (default: cv2.BORDER_REFLECT_101)derivBorder: Border mode for derivatives (default: cv2.BORDER_CONSTANT)tryReuseInputImage: Optimization flag to reuse input imageReturns:
pyramid: Output pyramid listExample:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
pyramid = cv2.buildOpticalFlowPyramid(
gray, winSize=(21, 21), maxLevel=3,
withDerivatives=True
)flow = cv2.readOpticalFlow(path)Read optical flow from a .flo file.
Parameters:
path (str): Path to the file to be loadedReturns:
flow: Optical flow field as CV_32FC2 matrix (2-channel float). First channel corresponds to the flow in the horizontal direction (u), second - vertical (v)Example:
# Read optical flow from file
flow = cv2.readOpticalFlow('flow.flo')
print(f'Flow shape: {flow.shape}') # (height, width, 2)
# Extract horizontal and vertical components
flow_x = flow[..., 0] # u component
flow_y = flow[..., 1] # v componentsuccess = cv2.writeOpticalFlow(path, flow)Write optical flow to a .flo file on disk.
Parameters:
path (str): Path to the file to be writtenflow: Flow field to be stored. Must be CV_32FC2 (2-channel float). First channel corresponds to the flow in the horizontal direction (u), second - vertical (v)Returns:
success (bool): True on success, False otherwiseExample:
# Calculate optical flow
flow = cv2.calcOpticalFlowFarneback(prev_gray, next_gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
# Save to file
success = cv2.writeOpticalFlow('flow.flo', flow)
if success:
print('Flow saved successfully')
# Later, read it back
loaded_flow = cv2.readOpticalFlow('flow.flo')Background subtraction algorithms model the static background and identify moving foreground objects, essential for surveillance and object detection in static camera scenarios.
cv2.BackgroundSubtractorMOG2Gaussian Mixture-based Background/Foreground Segmentation Algorithm. An improved adaptive algorithm that models each pixel as a mixture of Gaussians and selects appropriate components to represent the background.
Key Methods:
apply(image, fgmask=None, learningRate=-1): Compute foreground maskgetBackgroundImage(backgroundImage=None): Compute background imagesetHistory(history): Set number of frames in historysetVarThreshold(threshold): Set variance threshold for pixel-model matchingsetDetectShadows(detect): Enable/disable shadow detectionExample:
bg_subtractor = cv2.createBackgroundSubtractorMOG2(
history=500, varThreshold=16, detectShadows=True
)
while True:
ret, frame = cap.read()
if not ret:
break
fg_mask = bg_subtractor.apply(frame)
# Optional: get background image
bg_image = bg_subtractor.getBackgroundImage()cv2.BackgroundSubtractorKNNK-nearest neighbors based Background/Foreground Segmentation Algorithm. Uses k-nearest neighbors to classify pixels as background or foreground.
Key Methods:
apply(image, fgmask=None, learningRate=-1): Compute foreground maskgetBackgroundImage(backgroundImage=None): Compute background imagesetHistory(history): Set number of frames in historysetDist2Threshold(threshold): Set threshold on squared distancesetDetectShadows(detect): Enable/disable shadow detectionExample:
bg_subtractor = cv2.createBackgroundSubtractorKNN(
history=500, dist2Threshold=400.0, detectShadows=True
)
fg_mask = bg_subtractor.apply(frame, learningRate=0.01)bg_subtractor = cv2.createBackgroundSubtractorMOG2(
history=500, varThreshold=16, detectShadows=True
)Creates a MOG2 background subtractor.
Parameters:
history: Length of history (number of frames)varThreshold: Threshold on squared Mahalanobis distance between pixel and modeldetectShadows: If True, algorithm detects and marks shadows (slower but more accurate)Returns:
bg_subtractor = cv2.createBackgroundSubtractorKNN(
history=500, dist2Threshold=400.0, detectShadows=True
)Creates a KNN background subtractor.
Parameters:
history: Length of historydist2Threshold: Threshold on squared distance between pixel and sampledetectShadows: If True, algorithm detects and marks shadowsReturns:
Comparison Example:
# MOG2 - better for complex scenarios, detects shadows
mog2 = cv2.createBackgroundSubtractorMOG2(history=500, varThreshold=16, detectShadows=True)
# KNN - faster, good for simpler scenarios
knn = cv2.createBackgroundSubtractorKNN(history=500, dist2Threshold=400, detectShadows=False)
# Apply both and compare
fg_mask_mog2 = mog2.apply(frame)
fg_mask_knn = knn.apply(frame)Mean shift algorithms iteratively move a search window toward regions of higher density, useful for tracking objects based on color histograms or appearance models.
retval, window = cv2.meanShift(
probImage, window, criteria
)Finds the object center using mean shift algorithm. The algorithm shifts a window to the location with maximum probability density.
Parameters:
probImage: Back projection of the object histogram (probability map)window: Initial search window (x, y, width, height)criteria: Stop criteria (type, max iterations, epsilon)Returns:
retval: Number of iterations performedwindow: Converged window position (x, y, width, height)Example:
# Setup the initial tracking window
x, y, w, h = 300, 200, 100, 150
track_window = (x, y, w, h)
# Calculate histogram of ROI
roi = frame[y:y+h, x:x+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
# Tracking loop
while True:
ret, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
# Apply meanshift
ret, track_window = cv2.meanShift(dst, track_window,
(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1))
x, y, w, h = track_window
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)rotated_rect, window = cv2.CamShift(
probImage, window, criteria
)Continuously Adaptive Mean Shift algorithm. An extension of mean shift that adapts the size and orientation of the search window based on the zeroth moment.
Parameters:
probImage: Back projection of the object histogramwindow: Initial search window (x, y, width, height)criteria: Stop criteria for iterative algorithmReturns:
rotated_rect: Rotated rectangle containing position, size, and angle ((x, y), (width, height), angle)window: Converged window position (x, y, width, height)Example:
# Similar setup as meanShift
track_window = (x, y, w, h)
# Tracking loop
while True:
ret, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
# Apply CamShift
ret, track_window = cv2.CamShift(dst, track_window,
(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1))
# Draw rotated rectangle
pts = cv2.boxPoints(ret)
pts = np.int0(pts)
cv2.polylines(frame, [pts], True, (0, 255, 0), 2)OpenCV provides multiple tracking algorithms with different trade-offs between speed and accuracy. Modern trackers can handle occlusions, scale changes, and appearance variations.
cv2.TrackerBase class for visual object tracking algorithms (legacy API). Provides a common interface for all tracker implementations.
Common Methods:
init(image, boundingBox): Initialize tracker with image and bounding boxupdate(image): Update tracker state with new frameempty(): Check if tracker is emptyclear(): Clear internal statecv2.TrackerDaSiamRPNDistractor-aware Siamese Region Proposal Network tracker. State-of-the-art deep learning tracker with high accuracy, particularly robust to distractors and appearance changes.
Creation:
tracker = cv2.TrackerDaSiamRPN_create()Example:
# Initialize tracker
tracker = cv2.TrackerDaSiamRPN_create()
bbox = cv2.selectROI('Select Object', frame, fromCenter=False)
tracker.init(frame, bbox)
# Tracking loop
while True:
ret, frame = cap.read()
success, bbox = tracker.update(frame)
if success:
x, y, w, h = [int(v) for v in bbox]
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)cv2.TrackerMILMultiple Instance Learning tracker. Uses an online learning approach that updates the appearance model during tracking. Good balance between accuracy and speed.
Creation:
tracker = cv2.TrackerMIL_create()Characteristics:
cv2.TrackerKCFKernelized Correlation Filters tracker. Fast and efficient tracker using correlation filters in Fourier domain. Good for objects with limited appearance variation.
Creation:
tracker = cv2.TrackerKCF_create()Characteristics:
cv2.TrackerCSRTDiscriminative Correlation Filter tracker with Channel and Spatial Reliability (CSRT). More accurate than KCF but slower, uses spatial reliability maps.
Creation:
tracker = cv2.TrackerCSRT_create()Characteristics:
cv2.TrackerGOTURNGeneric Object Tracking Using Regression Networks. Deep learning-based tracker trained offline on large datasets. Requires Caffe model files.
Creation:
tracker = cv2.TrackerGOTURN_create()Characteristics:
# Create multiple trackers for different objects
trackers = cv2.MultiTracker_create()
# Add trackers for each object
for bbox in bboxes:
tracker = cv2.TrackerKCF_create()
trackers.add(tracker, frame, bbox)
# Update all trackers
while True:
ret, frame = cap.read()
success, boxes = trackers.update(frame)
for i, box in enumerate(boxes):
x, y, w, h = [int(v) for v in box]
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)The Kalman filter provides optimal state estimation for linear dynamic systems, widely used for predicting object positions and reducing measurement noise in tracking applications.
cv2.KalmanFilter(dynamParams, measureParams, controlParams=0, type=CV_32F)Kalman filter implementation for state estimation and prediction. Models system dynamics and measurement process to optimally estimate hidden states.
Parameters:
dynamParams: Dimensionality of the state vectormeasureParams: Dimensionality of the measurement vectorcontrolParams: Dimensionality of the control vector (default: 0)type: Data type (CV_32F or CV_64F)Key Attributes:
statePre: Predicted state (x'(k))statePost: Corrected state (x(k))transitionMatrix: State transition matrix (A)measurementMatrix: Measurement matrix (H)processNoiseCov: Process noise covariance matrix (Q)measurementNoiseCov: Measurement noise covariance matrix (R)errorCovPre: Priori error estimate covariance matrix (P'(k))errorCovPost: Posteriori error estimate covariance matrix (P(k))gain: Kalman gain matrix (K(k))Key Methods:
predict(control=None): Computes predicted statecorrect(measurement): Updates state with measurementExample - Tracking a Moving Point:
# Create Kalman filter for 2D point tracking
# State: [x, y, dx, dy], Measurement: [x, y]
kalman = cv2.KalmanFilter(4, 2)
# Transition matrix (constant velocity model)
kalman.transitionMatrix = np.array([
[1, 0, 1, 0], # x = x + dx
[0, 1, 0, 1], # y = y + dy
[0, 0, 1, 0], # dx = dx
[0, 0, 0, 1] # dy = dy
], dtype=np.float32)
# Measurement matrix
kalman.measurementMatrix = np.array([
[1, 0, 0, 0],
[0, 1, 0, 0]
], dtype=np.float32)
# Process and measurement noise
kalman.processNoiseCov = np.eye(4, dtype=np.float32) * 0.03
kalman.measurementNoiseCov = np.eye(2, dtype=np.float32) * 0.1
# Initialize state
kalman.statePost = np.array([[x], [y], [0], [0]], dtype=np.float32)
# Tracking loop
while True:
# Predict
prediction = kalman.predict()
pred_x, pred_y = int(prediction[0]), int(prediction[1])
# Get measurement (e.g., from detection)
measurement = np.array([[measured_x], [measured_y]], dtype=np.float32)
# Update
kalman.correct(measurement)
# Use prediction for display
cv2.circle(frame, (pred_x, pred_y), 5, (0, 255, 0), -1)Example - Tracking with Missing Measurements:
# When no measurement is available
if object_detected:
measurement = np.array([[x], [y]], dtype=np.float32)
kalman.correct(measurement)
# Always predict (even without measurement)
prediction = kalman.predict()
estimated_position = (int(prediction[0]), int(prediction[1]))Advanced motion analysis tools for estimating geometric transformations and aligning images based on motion models.
retval, warp_matrix = cv2.findTransformECC(
templateImage, inputImage,
warpMatrix, motionType,
criteria=None, inputMask=None,
gaussFiltSize=5
)Finds the geometric transformation between two images by maximizing the Enhanced Correlation Coefficient. Useful for image alignment and registration.
Parameters:
templateImage: Reference image (single-channel 8-bit or 32-bit float)inputImage: Image to align (same type and size as template)warpMatrix: Initial transformation matrix (2x3 for affine/euclidean, 3x3 for homography)motionType: Type of transformation (MOTION_TRANSLATION, MOTION_EUCLIDEAN, MOTION_AFFINE, MOTION_HOMOGRAPHY)criteria: Termination criteria (max iterations and epsilon)inputMask: Optional mask for template imagegaussFiltSize: Size of Gaussian filter for smoothing (1 = no smoothing)Returns:
retval: Final correlation coefficientwarp_matrix: Estimated transformation matrixMotion Types:
cv2.MOTION_TRANSLATION: Only translation (2 parameters)cv2.MOTION_EUCLIDEAN: Rotation + translation (3 parameters)cv2.MOTION_AFFINE: Affine transformation (6 parameters)cv2.MOTION_HOMOGRAPHY: Perspective transformation (8 parameters)Example - Image Stabilization:
# Reference frame
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
# Initialize transformation matrix
warp_matrix = np.eye(2, 3, dtype=np.float32)
# Current frame
curr_gray = cv2.cvtColor(curr_frame, cv2.COLOR_BGR2GRAY)
# Define termination criteria
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 50, 0.001)
# Find transformation
try:
cc, warp_matrix = cv2.findTransformECC(
prev_gray, curr_gray, warp_matrix,
cv2.MOTION_EUCLIDEAN, criteria
)
# Apply transformation to stabilize
stabilized = cv2.warpAffine(
curr_frame, warp_matrix,
(curr_frame.shape[1], curr_frame.shape[0]),
flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP
)
except cv2.error:
print("ECC optimization failed")Example - Video Alignment:
# Align sequence of frames to first frame
first_frame = cv2.cvtColor(frames[0], cv2.COLOR_BGR2GRAY)
aligned_frames = [frames[0]]
for frame in frames[1:]:
curr_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Use affine transformation for better alignment
warp_matrix = np.eye(2, 3, dtype=np.float32)
try:
_, warp_matrix = cv2.findTransformECC(
first_frame, curr_gray, warp_matrix,
cv2.MOTION_AFFINE,
criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 100, 1e-5)
)
aligned = cv2.warpAffine(
frame, warp_matrix,
(frame.shape[1], frame.shape[0])
)
aligned_frames.append(aligned)
except:
aligned_frames.append(frame) # Use original if alignment failsInstall with Tessl CLI
npx tessl i tessl/pypi-opencv-python@4.12.1