Skip to content

Stabilizing

currentMigrated from docs/filtering/stabilizing.mdx at 37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0

Stabilization estimates how the camera moved from frame to frame and warps each frame to cancel the shake. It suits handheld and action-camera footage. It cannot add information that wasn’t captured, so it always costs something: the warp needs interpolation, and the borders exposed by the movement are cropped or zoomed away.

Stabilizing can help compression, since removing erratic global motion leaves the encoder less to predict. The saving is secondary; the reason to stabilize is a steadier picture.

FFmpeg’s vidstabdetect and vidstabtransform filters wrap the vid.stab library, and your FFmpeg build needs --enable-libvidstab. The first pass analyses motion and writes it to a file; the second applies it.

Terminal window
ffmpeg -i input.mp4 -vf vidstabdetect -f null -
ffmpeg -i input.mp4 -vf "vidstabtransform,unsharp=5:5:0.8:3:3:0.4" -c:v libx264 -crf 18 output.mp4

The first command writes transforms.trf in the current directory, which you can delete afterwards. The unsharp filter is recommended by the FFmpeg documentation because the interpolation in the transform softens the picture. Both passes must see the same frames, so don’t trim or filter differently between them. You cannot use -c:v copy, since the video is being changed.

For very shaky, fast footage, such as action-camera video, detect with a higher shakiness, write to a named file, and smooth more with a small zoom-out:

Terminal window
ffmpeg -i input.mp4 -vf "vidstabdetect=shakiness=8:result=a.trf" -f null -
ffmpeg -i input.mp4 -vf "vidstabtransform=input=a.trf:smoothing=30:zoom=-5,unsharp=5:5:0.8:3:3:0.4" -c:v libx264 -crf 18 output.mp4
OptionFilterWhat it does
shakinessdetectHow shaky the video is and how fast the camera moves, 1-10 (default 5). It tunes detection; it is not a stabilization strength.
accuracydetectDetection accuracy, 1-15 (default 15). Lower is faster.
smoothingtransformFrames on each side used to smooth the camera path (default 15). Larger is steadier but fights real pans and tilts. 0 simulates a static camera.
optzoomtransformAutomatic zoom to hide borders: 1 (default) picks one static zoom, 2 adapts it per frame, 0 disables it.
zoomtransformExtra zoom in percent, added to optzoom. Negative values zoom out and expose more border.
croptransformWhat to do with exposed borders: keep the previous frame’s content (default) or fill with black.
interpoltransformbilinear (default), bicubic (slower, sharper) or no.
tripodbothVirtual tripod for a camera that should be locked off: every frame is compared to a reference frame. In vidstabdetect the value is the reference frame number (counted from 1); in vidstabtransform it is 1 to enable.

vid.stab estimates translation and rotation of the whole frame. It will not fix rolling-shutter wobble (“jello”), parallax between near and far objects, or motion blur from the shake, and low-contrast or very dark footage can confuse the detection. FFmpeg also has a single-pass deshake filter that needs no extra library. If your camera records gyroscope data, Gyroflow stabilizes from that data instead of from the image.

Watch the intended pans and any foreground subject, since a large smoothing makes them lag or drift. Check the edges: stronger stabilization means more zoom or more visible border, and the picture will be a little softer. If the result wobbles in a way the original did not, reduce smoothing or shakiness, or give up on that clip. Stabilization is lossy and cannot be repeated without further loss, so do it once, from the original, and encode after.