Nodes/ComfyUI-NS-Util/NS Toon Filter
ComfyUI Node

NS Toon Filter

A classic cel-shade toon pass, straight out of OpenCV

By NakamuraShippo·Created about a year ago·Updated 4 months ago· 5
NS Toon Filter
  • image
  • IMAGE
num_colors8
bilateral_d9
sigma_color75
sigma_space75
blur_ksize7
block_size9
c2

NS Toon Filter is the cel-shade effect you've seen a thousand times in image editors, packaged as a ComfyUI node: flatten the image into a handful of flat colors, slap bold black outlines on top, and suddenly your render looks like an anime still. It's the "toon" in the pack's Graphics Filter section, and it's built on a completely classic, pre-AI OpenCV pipeline. No model, no VRAM, no waiting - just a deterministic filter that runs in a fraction of a second.

Why reach for it? Sometimes you don't want to generate in an anime style - you want to convert what you have. If you've got a batch of renders or real photos that all need a consistent cel-shaded look, a filter like this is far more reliable than prompting a checkpoint, because the output is a fixed transformation, not a new sample. It's the difference between "ask the model to draw it toon" and "make it toon, guaranteed."

How it works

The pipeline is four OpenCV steps, straight from the classic "cartoon effect" recipe:

  1. Smooth - a bilateral filter (bilateral_d, sigma_color, sigma_space, defaults 9/75/75) smooths flat regions while keeping edges crisp. Bilateral is the key choice here: a plain Gaussian would smudge the outlines it's trying to preserve.
  2. Quantize - K-means clustering reduces the image to num_colors flat color levels (default 8, range 2–64). Fewer colors = flatter, more graphic; more = subtler.
  3. Outline - the image is blurred (blur_ksize, default 7) and run through an adaptive threshold (block_size, default 9; c, default 2) to find edges, producing a bold black-line mask. The c constant is the "how eager are we to call something an edge" dial - raise it for fewer, stronger lines.
  4. Combine - the quantized color image and the edge mask are AND-ed together. Colors where there are no lines, black lines where there are.

Output is a single IMAGE you can save or feed onward. Every parameter is an INT and all of them map to a real OpenCV call, so there's no black-box tuning - if you've done cartoon filters in any image tool, you already understand these knobs.

The inputs that matter

Three of the seven do the heavy lifting:

  • num_colors - the flat-color count. This is the biggest style lever; 8 is a strong toon, 16 is soft.
  • block_size - edge sensitivity (must be odd, 3–51). Smaller = more/denser edges.
  • c - edge threshold offset (0–20). Higher = fewer, thicker lines.

The rest (bilateral_d, the two sigmas, blur_ksize) are "if the result looks noisy or the edges are ugly" refinements. The defaults are genuinely reasonable - run it once before you touch anything.

The gotchas

Two things will surprise you. First, it processes only the first frame of a batch - the code grabs image[0] and works on that alone, so don't feed it a video or a multi-image batch and expect all of them converted. Second, edges render black by default, which is the classic toon look but not every look - if you want colored or softer outlines, this node doesn't give you that control; you'd composite afterward. And as with any K-means step, the quantization result isn't perfectly stable run to run (random centroid initialization), though at 8–16 colors the differences are minor.

Installing it

It's one node in ComfyUI-NS-Util, and it's the node that actually needs the pack's OpenCV dependency, so the install is worth doing right. ComfyUI Manager → Install via Git URL:

https://github.com/NakamuraShippo/ComfyUI-NS-Util

or clone into ComfyUI/custom_nodes and restart. The pack's requirements.txt pulls opencv-python automatically, so it should just work - if the node complains about cv2 on a weird environment, install it manually (pip install opencv-python) into the same Python that runs ComfyUI. No model files involved anywhere.

The honest take

This is a genuinely handy utility for a narrow job - consistent cel-shaded conversions of existing images. It won't match what a good anime checkpoint generates from scratch, but that's not its job; its job is "make this specific image toon, deterministically," and it does that with a well-understood, tweakable pipeline. Set num_colors, maybe nudge block_size, and you're done. The single-frame limitation is the main reason it's not a daily driver.

CategoryNS/Filter

Inputs (8)

NameTypeDefaultDescription
imageIMAGE
num_colorsINT82–64
bilateral_dINT91–50
sigma_colorINT751–255
sigma_spaceINT751–255
blur_ksizeINT71–64
block_sizeINT93–51
cINT20–20

Outputs (1)

NameTypeDescription
IMAGEIMAGE