Using ffmpeg to color correct / color grade a video

When searching for ffmpeg color correction I always ran into examples with saturation, brightness, contrast and gamma command line options (or even curves) and a lot of guess work. But after a bit of digging I found out that you can also easily apply any color correction you can do to a picture in your favorite image editor (like Photoshop or GIMP), thanks to LUTs.

LUTs are Look Up Tables for colors, used mainly for color grading, they basically map colors to different colors and can be represented as a regular PNG. Ffmpeg can apply LUTs to videos, and it can also generate you one to edit to your liking and then apply it.

You might have a clip that you shot but for some reason the colors were a bit off, or you just want to do some fine-tuned effects. With the following command you can generate a snapshot of the video at a specific time (0:00:04 in this case) along with a LUT.

ffmpeg -f lavfi -i haldclutsrc=8 \
  -i input.mp4 -ss 0:00:04 -frames:v 1 \
  -filter_complex "[1]scale=-1:512[b];[0][b]hstack" \
  haldclut_correction.png
The generated PNG containing the LUT and the snapshot.

Then you edit it in your photo editor, but make sure to only apply effects that are affecting the pixel color values (color temperature, curves, contrast, sepia, etc.) but does not alter the image (i.e. blurring).

The generated PNG before and after the color correction (using color temperature and color curves in GIMP).

Then after saving the image, with the following command you can apply it to the whole video:

ffmpeg -i input.mp4 \
  -i haldclut_correction.png \
  -filter_complex haldclut \
  -pix_fmt yuv420p \
  -c:v libx264 -preset slow -crf 18 \
  -c:a copy \
  output.mp4
The video before and after applying the LUT with ffmpeg. Charlie loved this hike :)

And that’s it, no guesswork included. And as this is still ffmpeg you can automate it, chain more edits, etc. and have full control over the quality of the output. (This example results in a fairly high quality MP4, the videos in this post are more compressed (have worse quality) to conserve bandwidth.)

If by any chance you come across a video that looks underexposed to you, you can also fix that with a simple adjustment.

A crossfade between the original and the altered screenshot of House Of The Dragon (copyright HBO), applying color curve adjustment in GIMP.
A few seconds of House Of The Dragon (copyright HBO). On the top is the original one, on the bottom is the same clip with the LUT applied.

And of course, you can go further if you want.

Another crossfade with a bit more extreme settings.
A close up video of my 3D printer doing its job, before and after applying the effect.

You can really apply anything you’d like, and I just found out that you can also have a video as input for the LUT – I won’t start playing with that for now. But please share it with me if you do :)

Notes

Of course you can also apply any effects to the PNG that “corrupts” the LUT – it might result in a glitchy, fuzzy, artistic video – and that might even be what you’re after! You really can’t do any harm by trying, ffmpeg will happily render you something.

The post is based on this answer for the question How to apply a LUT filter with FFmpeg on StackOverflow.

The -pix_fmt yuv420p might not be necessary when encoding the output but ffmpeg with libx264 might default to yuv444p which might cause problems when playing the video in browsers and older media players. Also, when exporting to web with libx264 encoding, adding -movflags faststart should reduce the time needed to start the playback (more here), but this is unrelated to the post.

The screenshot on the right of the generated image is simply ignored by ffmpeg (“Padding on the right (910px) of the Hald CLUT will be ignored”), it is just there so you can see the results of your edits.

While ffmpeg can work with several types of LUTs, the Hald CLUT that is used in this post is probably the most widely used one. There are tools like cluttool to convert from Hald CLUT to 3D LUT (3DL) and LUT-Convert to convert from Hald CLUT to CUBE. Ffmpeg also supports 3D LUT and probably CUBE, too.

The second example is a few seconds of House Of The Dragon (season 1, episode 7) that was criticized for being too dark, I used it only for illustration and educational purposes, please don’t sue me, HBO. I’ll remove it if you ask.

Similar Posts:

    None Found

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.