Fix Camera Vibration with FFmpeg Deshake Filter

This article provides a practical guide on how to use the FFmpeg deshake filter to stabilize video footage affected by high-frequency camera vibrations, such as engine rumble, drone motor jitters, or rapid hand tremors. You will learn the basic command syntax, the key parameters to tune specifically for micro-jitters, and a step-by-step command example to clean up your shaky videos.

Understanding the Deshake Filter

FFmpeg's built-in deshake filter works by comparing consecutive frames to detect motion, estimating the unwanted camera shake, and applying counter-transformations to smooth the video. For high-frequency vibrations (rapid, small-scale shakes), you must fine-tune the filter's search window and block size to prevent the algorithm from ignoring the tiny jitters.

Basic Command Syntax

The simplest way to apply the filter is by using the default settings:

ffmpeg -i input.mp4 -vf deshake output.mp4

However, default settings rarely yield perfect results for high-frequency vibrations. To fix micro-jitters, you must customize the filter parameters.

Key Parameters for High-Frequency Vibrations

To target rapid, small-scale movements, adjust the following parameters within the -vf deshake filter string:

  • rx and ry: The maximum extent of movement in pixels to search for in the X and Y directions (range 4-128, default is 15). For high-frequency, low-amplitude vibration, reduce these values (e.g., rx=10:ry=10) to focus the filter on small, rapid movements and prevent it from misinterpreting intentional camera pans.
  • blocksize: The size of the blocks used for motion estimation (default is 8). Setting this to 8 or 16 is ideal for high-frequency shakes.
  • contrast: The contrast threshold for a block to be used for motion search (default is 125). Setting this lower (e.g., contrast=100) can help the filter find more tracking points in low-contrast areas.
  • edge: Defines how to fill in the blank areas generated by shifting the frame. Options include blank (black pixels), smear (repeats boundary pixels), wrap (wrap-around), or mirror (mirrors boundary pixels). mirror is usually the most visually seamless.

Here is an optimized command tailored for resolving high-frequency, low-amplitude camera vibrations:

ffmpeg -i input.mp4 -vf "deshake=rx=10:ry=10:blocksize=8:contrast=100:edge=mirror" -c:v libx264 -crf 18 -c:a copy output.mp4

Parameter Breakdown:

  • rx=10:ry=10: Restricts the motion search radius to 10 pixels. This prevents the filter from over-correcting large panning movements while focusing entirely on rapid micro-shakes.
  • blocksize=8: Uses smaller blocks to detect highly localized, rapid movements across the frame.
  • contrast=100: Lowers the detection threshold slightly to ensure the algorithm tracks enough details even in flatter textures.
  • edge=mirror: Fills in the shifting edges by mirroring the adjacent pixels, which hides the stabilization movement much better than black bars.