Normalize Video Contrast and Brightness with FFmpeg

This article provides a practical guide on how to use the FFmpeg normalize filter to automatically adjust video contrast and brightness on a frame-by-frame basis. You will learn the fundamental command syntax, how the filter analyzes pixel intensity, and how to configure key parameters like temporal smoothing and channel independence to achieve professional, flicker-free results.

The normalize filter in FFmpeg works by stretching the dynamic range of a video’s color channels to the maximum possible limits (typically 0 to 255 for 8-bit video). By analyzing the darkest and lightest pixels in a frame, it automatically brightens underexposed areas and darkens overexposed areas.

The Basic Command

To apply automatic contrast and brightness normalization to a video using default settings, use the following command:

ffmpeg -i input.mp4 -vf "normalize" output.mp4

By default, this command normalizes each RGB channel independently on every single frame.

Preventing Color Shifts

Normalizing RGB channels independently can sometimes cause unwanted color shifts (for example, making a warm sunset look overly blue). To adjust brightness and contrast while preserving the original color balance of your video, set the independence parameter to 0:

ffmpeg -i input.mp4 -vf "normalize=independence=0" output.mp4

Preventing Flickering with Temporal Smoothing

Because the normalize filter evaluates every frame individually, sudden changes in a frame’s content (like a light turning on or a bright object passing by) can cause sudden, jarring jumps in brightness, known as flickering.

To prevent this, use the smoothing parameter. This averages the normalization range over a specified number of consecutive frames:

ffmpeg -i input.mp4 -vf "normalize=smoothing=24:independence=0" output.mp4

In this example, smoothing=24 means FFmpeg will smooth the brightness and contrast transitions over a window of 24 frames (about 1 second of video at 24fps), resulting in a much smoother, more natural visual transition.

Fine-Tuning Black and White Points

You can also define the target black and white points to prevent the filter from stretching the contrast to absolute absolute black (0) and absolute white (255), which can sometimes look too harsh.

To set custom target color bounds, use the blackpt and whitept options:

ffmpeg -i input.mp4 -vf "normalize=blackpt=black:whitept=white" output.mp4

You can specify these points using standard color names (like black, gray, white) or hexadecimal color values. This is highly useful for mapping the output to specific broadcast or color-space standards.