Real-time video frame stabilisation for OBS Studio using Lucas-Kanade optical flow.
⚠️ Work in progress — This plugin is in early development. Expect changes and possible instability.
Input should have 1:1 pixel aspect. Apply an aspect correction filter before this filter, if necessary.
On Windows, you may need to run OBS as admin, to allow it to adjust it's GPU priority, or otherwise manually increase OBS GPU priority.
This plugin analyses consecutive video frames to estimate pixel-level motion and applies a counter-transform to cancel out unwanted camera shake. It is applied as an effect filter to a video source.
The stabilisation pipeline runs entirely on the GPU via shaders:
- Luminance conversion — Each frame is converted to a single-channel luminance representation.
- Gradient computation — Spatial gradients are calculated from the luminance image.
- Pyramidal Lucas-Kanade optical flow — A 9-level image pyramid estimates motion vectors using a 5×5 weighted window with Gaussian-like weights. At each level, the coarser-level displacement is used as a prior, and the flow is refined to sub-pixel accuracy.
- Flow reduction — The full-resolution motion field is downsampled, selecting the most reliable sample per tile.
- Transformation accumulation — Reliable motion samples are averaged, and the result is accumulated into running transformation offsets.
- Temporal smoothing — The accumulated transformations decay over a configurable smoothing period.
- Output — The original frame is repositioned by the accumulated transformations and returned.
| Property | Type | Range | Default | Description |
|---|---|---|---|---|
| View Crop | Float | 0.0 – 100.0 | 10.0 | Percentage of view to crop |
| Transparent Background | Boolean | True/False | False | When enabled, scene behind the source is visible at edges, otherwise black |
| Enable Stabilisation | Boolean | True/False | True | Toggle stabilisation or individual transformations |
| Resolution | List | See below | Half | Processing resolution |
| Prioritise | List | See below | None | Magnitude of motions to consider |
| Deviation Filter | Float | 0.0 – 100.0 | 50.0 | Strength of outlier filtering |
| Smoothing Period | Float | 0.0 – 60.0 | 1.0 | Time in seconds over which corrections decay |
| Processing Crop | Float | 0.0 – 100.0 | 5.0 | Percentage of motion field to crop |
| Debug Mode | List | See below | None | Visualisation mode for debugging |
Resolution is relative to source. Output is always at full resolution, only processing is affected.
Full does not necessarily produce best results, due to factors such as aliasing, motion blur or compression artifacts. Interpolating input to a lower resolution can mitigate these issues.
| Option | Description |
|---|---|
| Full | Processing is done at the source resolution |
| Half | Width and height are halved |
| Quarter | Width and height are quartered |
Threshold for prioritisation is the average magnitude of motion for the frame.
| Option | Description |
|---|---|
| None | All motion is considered |
| Low Magnitude | Only low magnitude motion is considered |
| High Magnitude | Only high magnitude motion is considered |
The plugin includes several debug modes to visualise intermediate pipeline stages.
| Mode | Description |
|---|---|
| None | Normal output — stabilised video |
| Crop | Visualises view and motion crop regions |
| Luminance | Shows previous/current luminance (red/green+blue channel) |
| Gradient | Visualises spatial gradients as colour-coded direction/magnitude |
| Flow Direction | Hue represents optical flow direction |
| Flow Magnitude | Brightness represents optical flow magnitude |
| Combined | Shows all intermediate stages in a quadrant layout |
Windows x64:
C:\Program Files\obs-studio\
Linux x86_64 (OBS Flatpak):
~/.var/app/com.obsproject.Studio/config/obs-studio/plugins/
- CMake ≥ 3.28
- OBS Studio 31.1.1 or later
- Platform-specific compilers:
- Windows — Visual Studio 2022 (MSVC)
- Linux — GCC/Clang, Ninja
Based on the OBS Plugin Template. Required deps are fetched automatically on Windows:
| Dependency | Version |
|---|---|
| OBS Studio | 31.1.1 |
| obs-deps | 2025-07-11 |
| Qt6 | 2025-07-11 |
Windows x64:
cmake --preset windows-x64
cmake --build --preset windows-x64Linux x86_64:
cmake --preset ubuntu-x86_64
cmake --build --preset ubuntu-x86_64motion-stabilisation/
├── CMakeLists.txt # Main build configuration
├── CMakePresets.json # Platform-specific build presets
├── buildspec.json # Plugin metadata, dependency versions
├── LICENSE # GNU GPL v2 (or later)
├── README.md
├── cmake/ # Shared CMake modules
├── data/ # Shader effects & resources
│ ├── defines.h # Shader constants (eigenvalue thresholds, window sizes)
│ ├── luminance.effect # Luminance conversion shader
│ ├── gradient.effect # Sobel gradient computation shader
│ ├── motion.effect # Lucas-Kanade optical flow shader
│ ├── reduce.effect # Motion field reduction
│ ├── transform.effect # Frame transformation + output
│ ├── debug.effect # Debug visualisation shader
│ └── locale/
│ └── en-US.ini # Localisation strings
└── src/
├── plugin-main.c # Plugin entry point (load/unload)
├── motion-stabilisation.c # Core filter implementation
├── analyze.c / .h # Frame analysis
├── flow.c / .h # Optical flow computation
├── common.c / .h # Shared utilities
├── plugin-support.h # Plugin metadata header
└── plugin-support.c.in # Generated support file
This project is licensed under the GNU General Public License v2.0 or later. See LICENSE for the full text.
ZerionSeven — zerion7.com · motion-stabilisation@zerion7.com