FFmpeg: Chromatic Aberration

I recently set some time aside to create a "chromatic aberration" effect using just FFmpeg, and this is what I came up with.

The steps in the filtergraph are easy to follow as is, but it's possible that there are ways to reduce the length by merging steps between filterchains.

RGB



Clockwise, from top-left: Original, 2px separation, 10px separation, 30px separation
# ffplay used for testing; filtergraph can be directly inserted into ffmpeg

ffplay\
   -i video.mkv\
   -vf\
      "split=3[r][g][b];\
      nullsrc=size=640x360[base1];\
      nullsrc=size=640x360[base2];\
      nullsrc=size=640x360[base3];\
      [r]lutrgb=g=0:b=0[red];\
      [g]lutrgb=r=0:b=0[green];\
      [b]lutrgb=r=0:g=0[blue];\
      [base1][red]overlay=x=10:shortest=1,format=rgb24[x];\
      [base2][green]overlay=x=0:shortest=1,format=rgb24[y];\
      [base3][blue]overlay=y=10:shortest=1,format=rgb24[z];\
      [x][y]blend=all_mode='addition'[xy];\
      [xy][z]blend=all_mode='addition'[xyz];\
      [xyz]crop=630:350:10:10,scale=640:360:out_color_matrix=bt709"

# 'format=rgb24' needs to be included to stop overlaying layers as YUV
# 'scale=out_color_matrix=bt709' for correct RGB to YUV colourspace conversion
# 'crop & scale' at end to remove border areas missing full RGB data

YUV


20px Y horizontal offset, 10px V vertical offset
# ffplay used for testing; filtergraph can be directly inserted into ffmpeg

ffplay\
   -i short.mkv\
   -vf\
      "split=3[y][u][v];\
      nullsrc=size=640x360[base1];\
      nullsrc=size=640x360[base2];\
      nullsrc=size=640x360[base3];\
      [y]lutyuv=u=0:v=0[Yaxis];\
      [u]lutyuv=v=0:y=0[Uaxis];\
      [v]lutyuv=u=0:y=0[Vaxis];\
      [base1][Yaxis]overlay=x=20:shortest=1[x];\
      [base2][Uaxis]overlay=x=0:shortest=1[y];\
      [base3][Vaxis]overlay=y=20:shortest=1[z];\
      [x][y]blend=all_mode='lighten'[xy];\
      [xy][z]blend=all_mode='lighten'[xyz];\
      [xyz]crop=620:340:20:20,scale=640:480"

# 'format=rgb24' & 'scale=out_color_matrix=bt709' are omitted from YUV version

More "realistic" effects can be created by rescaling each layer, such that, a single plane (or point) is in focus, and the aberration gets more apparent further away from this area. [N.B. potential future blog post]

# UPDATE: 2019.04.06_02.49.13
# Revised, simpler, filtergraphs. In these examples, two element layers are
# scaled larger, then cropped back to original size. This makes the effect more
# apparent further out towards the edges.

# RGB
"
      split=3[red][green][blue];
      [red]lutrgb=g=0:b=0,scale=iw+34:ih+20,crop=iw-34:ih-20[red];\
      [green]lutrgb=r=0:b=0,scale=iw+20:ih+8,crop=iw-20:ih-8[green];\
      [blue]lutrgb=r=0:g=0[blue];\
      [red][blue]blend=all_mode='addition'[rb];\
      [rb][green]blend=all_mode='addition'
"

# YUV
"
      split=3[y][u][v];
      [y]lutyuv=u=0:v=0,scale=iw+44:ih+30,crop=iw-44:ih-30[y];\
      [u]lutyuv=v=0:y=0,scale=iw+20:ih+8,crop=iw-20:ih-8[u];\
      [v]lutyuv=u=0:y=0[v];\
      [y][v]blend=all_mode='lighten'[yv];\
      [yv][u]blend=all_mode='lighten'
"

info: https://en.wikipedia.org/wiki/Chromatic_aberration
source video: http://www.beachfrontbroll.com/2014/10/Free-Stock-Footage-of-a-Buck.html