How to Create a Cartoon Effect in FFmpeg
Applying a cartoon or cel-shaded effect to a video in FFmpeg is achieved by running two parallel processing chains on the footage: one that flattens colors using an edge-preserving blur, and another that extracts outlines using an edge-detection filter. By inverting the detected edges into dark lines and multiplying them over the flattened color layer, you produce a stylized animation appearance directly from the command line.
The Complete Command
Run the following command to apply the cartoon effect:
ffmpeg -i input.mp4 -filter_complex \
"[0:v]split=2[color_in][edge_in]; \
[color_in]bilateral=sigmaS=5:sigmaR=0.2[smoothed]; \
[edge_in]edgedetect=low=0.1:high=0.3,negate[lines]; \
[smoothed][lines]blend=all_mode=multiply[outv]" \
-map "[outv]" -map 0:a? -c:v libx264 -crf 18 -c:a copy output.mp4How the Filtergraph Works
split=2[color_in][edge_in]
Duplicates the primary video stream into two separate paths for simultaneous processing.bilateral=sigmaS=5:sigmaR=0.2[smoothed]
Thebilateralfilter smooths out surface textures and gradients while keeping sharp boundaries intact.sigmaS(Spatial Sigma): Controls the blur radius. Higher values blur larger areas.sigmaR(Range Sigma): Sets the edge-preservation threshold. Lower values preserve more distinct boundaries between contrasting color fields, avoiding muddy colors.
edgedetect=low=0.1:high=0.3,negate[lines]edgedetectapplies a Canny edge detector, rendering high-contrast boundaries as white lines over a pure black background. Adjustinglowandhighthresholds determines how sensitive the filter is to subtle lines.negateinverts the result, transforming the image into black ink lines on a solid white canvas.
[smoothed][lines]blend=all_mode=multiply[outv]
Theblendfilter combines the two streams using themultiplymode. Pure white areas from the lines layer leave the underlying smoothed colors unaffected, while black pixels draw solid dark outlines directly over the image.
Fine-Tuning the Results
Increase Cel-Shading: If the bilateral filter leaves too much detail, chain an additional posterize or color reduction step by inserting
eq=contrast=1.2:saturation=1.4into the[color_in]chain to make colors vibrant and punchy.Thicker Outlines: Chain a
dilationfilter immediately afteredgedetect(beforenegate) to expand the line width:[edge_in]edgedetect=low=0.1:high=0.3,dilation,negate[lines]Reduce Noise: If the edge detector picks up unwanted background grain, add a mild blur like
smartblur=lr=1:ls=-0.5prior toedgedetect.