motionx is a lightweight Python library + CLI tool for motion extraction in videos or image sequences.
It builds on OpenCV and provides a clean, modern API for frame differencing, background subtraction, and a colorized weighted motion highlighting method.
- 📽️ Frame differencing (consecutive grayscale subtraction + thresholding)
- 🧩 Background subtraction (MOG2) with shadow detection
- 🎨 Weighted motion (color): blend current frame with inverted delayed frame
- 🖼️ Returns binary motion masks (diff/mog2) or color motion (weighted)
- 📂 Supports video files, webcams, and image sequences
- 🛠️ Easy to integrate into Python pipelines
- 💻 Comes with a CLI tool for quick conversion
- 🧪 Tested & typed (Python ≥3.9, type hints included)
git clone https://github.com/engineer1469/motionx.git
cd motionx
python -m venv .venv && source .venv/bin/activate
pip install -U pip
pip install -e .- Python 3.9+
- OpenCV
- NumPy
import cv2
from motionx import MotionExtractor
# Initialize with "diff", "mog2", or "weighted"
me = MotionExtractor(method="diff")
cap = cv2.VideoCapture("input.mp4")
while True:
ok, frame = cap.read()
if not ok:
break
motion = me.process(frame) # mask (diff/mog2) or color (weighted)
win = "Motion (mask/color)"
cv2.imshow(win, motion)
if cv2.waitKey(30) == 27: # ESC
break
cap.release()
cv2.destroyAllWindows()motionx -i input.mp4 -o motion_mask.mp4 --method diff --thresh 30 --blur 5motionx -i 0 --out-dir masks --method mog2motionx -i frames/ --in-fps 24 -o motion_mask.mp4 --method diffmotionx -i "frames/*.png" --in-fps 30 --out-seq "out/mask_%06d.png"The weighted method produces a color visualization by blending the current frame with the inverted previous (or delayed) frame:
alpha: weight for the current framebeta: weight for the inverted previous frameoffset: how many frames back to reference (1 = immediate previous)
Example:
motionx -i input.mp4 -o weighted.mp4 --method weighted --alpha 0.6 --beta 0.6 --offset 2Notes:
- Weighted mode writes a color video (
--o weighted.mp4) automatically. - If writing an image sequence, color PNGs/JPEGs are produced.
| Parameter | Default | Description |
|---|---|---|
thresh |
25 | Binary threshold for pixel difference |
blur_kernel |
(5, 5) | Gaussian blur kernel (helps remove noise) |
morph_kernel |
(3, 3) | Morphological kernel size |
morph_iters |
1 | Dilation iterations |
| Parameter | Default | Description |
|---|---|---|
alpha |
0.5 | Blend weight for current frame |
beta |
0.5 | Blend weight for inverted delayed frame |
offset |
1 | Number of frames to delay (>=1) |
The output is a full-color image where static regions tend toward neutral gray (~127), and motion regions become more vivid due to blending with the inverted previous frame.
| Parameter | Default | Description |
|---|---|---|
history |
500 | Frames to build background model |
var_threshold |
16.0 | Variance threshold for foreground detection |
detect_shadows |
True | Whether to mark shadows (~127 gray) |
Original Frame → Motion Mask
Original Frame → MOG2 Mask
git clone https://github.com/engineer1469/motionx.git
cd motionx
python -m venv .venv && source .venv/bin/activate
pip install -U pip
pip install -e ".[dev]"
# Run tests
python -m pip install pytest
pytest -q
# Code formatting + linting
pre-commit install
pre-commit run --all-files- Add Farnebäck optical flow (per-pixel motion vectors)
- Motion bounding box extraction
- Support for region-of-interest (ROI) masking
- Temporal motion smoothing
- Real-time camera capture mode (
motionx --camera 0) - Publish to PyPI
MIT © 2025 Sepp Beld
- OpenCV for the core computer vision tools
- Inspiration from countless "motion detection" snippets floating around the CV community
- Inspiration from the very interesting videos from Consistently Inconsistent