Adjusting video contrast, brightness, saturation, and color balance with FFMPEG

(This method is depricated, use this new method: new method link)

I spent most of today researching how to adjust various video settings with FFMPEG. Last night I shot video of a jazz singer in a fairly dark club. Even though I used a low-lux setting on the camera (Sony HDR-CX260) that compensated for some of the darkness, I was still left with video that seemed dark and low contrast.

One method suggested porting the entire video into JPG files, having a program-script adjust each of these, then reassembling them into a video. I tried this on a clip and it was pretty lousy quality, and of course had no audio.

I eventually delved into FFMPEG filters and found one that worked, though the documentation for it is sparse. The filter I used is “mp” for mplayer. A subfilter for mplayer called “eq2” does the magic. It can adjust several aspects of video at once. For details on what this filter can do, see the page:

NOTES: I found with trial and error that in FFMPEG filters are only applied to video that is being encoded or re-encoded. If I tried to just copy the video and audio codecs, the filters were ignored. I also found that the mp=eq2 filter seemed to influence a change in the frame dimensions (as in squished-looking) if I converted to DVD format (MPEG2), but didn’t change if I converted to MP4. Not sure why. But I can convert to one and then to the other as a work-around.

The syntax of the filter in FFMPEG is:

-vf mp=eq2=gamma:contrast:brightness:saturation:rg:gg:bg:weight

I won’t try to define each of these. If you don’t know what they mean, try tweaking a JPG image in a graphics program to see how each setting affects the final image. Very slight changes can have dramatic effects. “rg, gg, and bg” are red, green, and blue gamma. Some of the settings have a default value of 1, and some have default value of 0. You can specify decimal values for any of them (e.g., 0.962). I’ll copy a short relevant portion of the user-guide for mplayer at the end of this post.

I found when I boosted the contrast and brightness, the video had a slightly green look to it. I played around with boosting red, but that didn’t look right. I removed a bit of green and that looked better, but left it looking kind of washed out. I boosted the color saturation a bit and that gave me what I was after.

When you are trying out the filter, you can interrupt the conversion after there are 10 seconds of video processed and view the file so you can see what your settings are doing.

This is the format I ended up using:
ffmpeg -i all.MTS -c:v libx264 -c:a libfaac -vf mp=eq2=1:1.68:0.3:1.25:1:0.96:1 foo.mp4

This leaves gamma at 1, boosts contrast to 1.68, increases brightness just slightly (0.3) to compensate for the contrast, boosts color saturation by .25, leaves red channel at 1, removes a smidge of green (0.96), and leaves blue at 1. The format becomes an HD MP4 (MOV). I also made a DVD from this by converting the color-adjusted MP4 to an MPG:

ffmpeg -i foo.mp4 -target ntsc-dvd foo.mpg

(note that the FFMPEG docs show this incorrectly as gamma, brightness, contrast)

initial gamma value (default: 1.0)

initial contrast, where negative values result in a negative image (default: 1.0)

initial brightness (default: 0.0)

initial saturation (default: 1.0)

gamma value for the red component (default: 1.0)

gamma value for the green component (default: 1.0)

gamma value for the blue component (default: 1.0)

The weight parameter can be used to reduce the effect of a high gamma value on bright image areas, e.g. keep them from getting overamplified and just plain white. A value of 0.0 turns the gamma correction all the way down while 1.0 leaves it at its full strength (default: 1.0).

Convert to B&W, then up contrast and brightness to give 50s feel:

ffmpeg -i willow.mp4 -target ntsc-dvd -vf format=gray temp.mpg
ffmpeg -i temp.mpg -target ntsc-dvd -vf mp=eq2=1:1.3:0.1 new.mpg

I think the grainy feel of mpg is better for a retro feel.

Or keep as an MP4,
ffmpeg -i willow.mp4 -c:v libx264 -c:a libfaac -vf format=gray temp.mp4
ffmpeg -i temp.mp4 -c:v libx264 -c:a libfaac -vf mp=eq2=1:1.3:0.1 new.mp4

Example 2:
I did a video at a club where the light was RED, overwhelmingly red. I did some tweaks and got it at least somewhat color balanced. I boosted gamma to bring everything up, boosted contrast to make it less muddy, boosted brightness slightly, decreased saturation to remove a bit of glow, reduced red, reduced green due to an overall green haze, boosted blue, and increased weight.

ffmpeg -i all.m2ts -target ntsc-dvd -vf mp=eq2=2.0:1.5:0.2:0.9:0.1:0.8:1.3:0.4 temp.mpg


9 thoughts on “Adjusting video contrast, brightness, saturation, and color balance with FFMPEG

  1. First, great explaination and well worth my adding it to my knowledge. I appreciated the in-depth but very easy to understand description.

    Second, if I might, FFmpeg will not honor filters if the codec is not specified or if -vcodec copy specified. It assumes you want no encoding and it cannot alter the video unless it encodes. You can still keep the same format but just specify the same or other codec such as libx264, etc.

    An example would be: (Notice codecs AFTER filters)
    ffmpeg -i all.FLV -vf mp=eq2=1:1.68:0.3:1.25:1:0.96:1 -c:v libx264 -c:a libfaac foo.flv

    Thirdly, DVD standard is always, ALWAYS, 720X480 but yes you can adjust the pixel aspect as well as display aspect to reach other proportions but it still has to be encoded in 720×480 .

  2. Regarding ‘squished-looking’… DVD dimensions are anamorphic. Think of 720 (as in 720×480) as a ‘tentative width’ and not the square pixel width. At a DAR of 4:3, pixel aspect ratio is 0.889, and at 16:9, PAR is 1.185 (NTSC). You have to multiply 720 with PAR to get the square pixel width. At 4:3, 720*0.889 = 640 (640×480). At 16:9, 720*1.185 = 853 (853×480). As you may have noticed, 720:480 does not equal 4:3 or 16:9, but 640:480=4:3 (1.333) and 16:9=853:480 (1.778).

    ffmpeg is a no-joy in the instant gratification department — perhaps this freeware might interest you (lets you preview the filters with ffplay)…

  3. As of now on Arch Linux
    ffmpeg version 2.6.1 Copyright (c) 2000-2015 the FFmpeg developers
    the correct filter to use now is just called “eq”. both mp and eq2 fail.

  4. Anyone know of an ffmpeg filter that can fix this?

    I timelapse stuff, and my Canon T5 could have a better exposure algorithm. The near flashes in rapid exposure adjustment, every 4 seconds, really bug me. “Exposure Smoother”?

  5. Was just trying to do this with version N-76250-g7c8fcbb and was getting an error that mp filter doesn’t exist. You have to use ‘eq’ filter now, and the format takes each of the settings you wish to change as a key value pair.

    To bump brightness by 20% and contrast by 30%:
    ffmpeg -i -c:v libx264 -c:a libfaac -vf eq=brightness=0.2:contrast=1.3

    For other options, see:

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s