image processing
cartoon effect
programming tutorial
digital art
image manipulation

How to cartoon-ify an image programmatically?

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Cartoonifying an image is usually a combination of two separate effects: flattening or simplifying the colors, and drawing clean dark edges around important shapes. You do not need a neural network to get a convincing result. A classical OpenCV pipeline is often enough and is easier to tune, faster to run, and simpler to understand.

The Basic Cartoon Pipeline

A typical cartoon effect does four things:

  1. smooth small texture so skin, grass, and fabric become simpler
  2. reduce the number of colors so regions look painted
  3. detect strong edges
  4. combine the simplified colors with the edge mask

The following Python example uses OpenCV and NumPy. It reads an image, quantizes colors with k-means, finds edges with adaptive thresholding, and merges the two outputs.

python
1import cv2
2import numpy as np
3
4
5def cartoonify(image_path: str, output_path: str) -> None:
6    image = cv2.imread(image_path)
7    if image is None:
8        raise FileNotFoundError(image_path)
9
10    image = cv2.resize(image, (800, 600))
11
12    # Step 1: smooth the image while preserving major edges.
13    smooth = cv2.bilateralFilter(image, d=9, sigmaColor=75, sigmaSpace=75)
14
15    # Step 2: reduce colors with k-means.
16    data = smooth.reshape((-1, 3)).astype(np.float32)
17    criteria = (
18        cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,
19        20,
20        0.5,
21    )
22    k = 8
23    _, labels, centers = cv2.kmeans(
24        data,
25        k,
26        None,
27        criteria,
28        10,
29        cv2.KMEANS_RANDOM_CENTERS,
30    )
31    centers = np.uint8(centers)
32    quantized = centers[labels.flatten()].reshape(smooth.shape)
33
34    # Step 3: detect bold edges.
35    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
36    gray = cv2.medianBlur(gray, 7)
37    edges = cv2.adaptiveThreshold(
38        gray,
39        255,
40        cv2.ADAPTIVE_THRESH_MEAN_C,
41        cv2.THRESH_BINARY,
42        9,
43        7,
44    )
45
46    # Step 4: combine edge mask with quantized colors.
47    cartoon = cv2.bitwise_and(quantized, quantized, mask=edges)
48    cv2.imwrite(output_path, cartoon)
49
50
51cartoonify("input.jpg", "cartoon.jpg")

This version is fully runnable as long as opencv-python and numpy are installed.

Why These Steps Work

The bilateral filter matters because a plain Gaussian blur softens important contours too aggressively. A bilateral filter smooths regions while preserving larger intensity boundaries, which keeps the image structure suitable for later edge extraction.

Color quantization is what gives the "flat paint" look. Real photos contain thousands of subtle color variations. Reducing the image to k representative colors creates larger blocks of similar tone, which reads more like an illustration than a photograph.

Adaptive thresholding is a good edge choice because it works locally. If one side of the image is bright and the other is darker, local thresholding usually keeps the edges cleaner than a single global threshold.

A Faster Alternative Without K-Means

K-means can be the slowest part of the pipeline. If you want something cheaper, you can quantize by dividing the color space into buckets:

python
1import cv2
2import numpy as np
3
4
5def fast_quantize(image: np.ndarray, levels: int = 16) -> np.ndarray:
6    step = 256 // levels
7    return (image // step) * step
8
9
10image = cv2.imread("input.jpg")
11quantized = fast_quantize(image, levels=8)
12cv2.imwrite("fast_quantized.jpg", quantized)

This does not look quite as polished as k-means, but it is fast and often good enough for batch image effects.

Tuning the Look

If the result looks too photographic, lower the number of colors by reducing k. If it looks too harsh or posterized, increase k or reduce the strength of the edge mask.

For softer edges, try a larger median blur before thresholding. For stronger comic-book outlines, increase the contrast of the grayscale image or switch to a Canny-based edge map and dilate the result slightly.

You can also resize the image before processing. Cartoon effects often look better after downscaling because fine-grained camera noise disappears and edges become more dominant.

Common Pitfalls

The most common problem is using only edge detection without color simplification. That produces a sketch-like overlay, not a real cartoon effect.

Another mistake is over-blurring the image before edge detection. Too much smoothing destroys the contours you want to preserve, and the final result looks muddy.

Developers also run k-means on very large images and then wonder why the effect is slow. Resize first, or use the faster bucket quantization approach when runtime matters.

Finally, do not expect one parameter set to work for every photo. Portraits, landscapes, and low-light images respond very differently, so expose the main thresholds if this is part of an application.

Summary

  • A cartoon effect usually combines color simplification with strong edge extraction.
  • Bilateral filtering preserves contours better than a plain blur.
  • K-means gives a good quantized look, while bucket quantization is a faster fallback.
  • Adaptive thresholding is a practical way to create clean outlines.
  • Parameter tuning matters because different images need different levels of smoothing, quantization, and edge strength.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.