Image CAS harpening (Batch)
AMD's sharpening shader, ported to your image batches
- image
- image
Most sharpening in ComfyUI is unsharp masking - blur a copy, subtract it, add the detail back - and it's fine until it starts ringing halos around edges. "Image CAS harpening (Batch)" takes a different, smarter route: it's a faithful port of AMD's Contrast Adaptive Sharpening shader, the same algorithm that ships in GPUs and game engines, implemented in plain torch so it runs on any hardware. The display name has a typo ("CAS harpening") - the node itself is anything but sloppy.
What it is
NNImageCASharpening applies Contrast Adaptive Sharpening to image tensors with full batch support. The point of CAS versus classic unsharp mask is the "adaptive" part: instead of a fixed blur radius, it inspects a small 3×3 neighborhood per pixel and sharpens only where there's actual contrast to enhance, leaving flat areas - like skin and skies - alone. That's exactly why it's the sharpening that doesn't produce the ugly halos you get from cranking an unsharp mask.
How it works
The implementation is the real CAS algorithm, not a lookalike. It pads each image, reads the 3×3 neighborhood of every pixel, computes local min/max across the cross and diagonal neighbors, derives an amplitude from the contrast, and applies a weighted combination weighted toward the center pixel. It's a shader-style filter - the "s" in CAS - rewritten as tensor ops with torch.nn.functional.pad and elementwise arithmetic, then clamped to [0, 1] so highlights can't overshoot.
The batch handling is where this node earns its keep. The batch_size input (1–256) controls how many frames are processed per chunk, and device lets you pick GPU or CPU. The node chunks through large batches and copies results off-GPU as it goes, so you can sharpen a 100-frame video batch without ballooning VRAM. Set amount to 0 and it passes the image through untouched - a handy "park it in the workflow" default.
The inputs that matter
Only four:
image- the tensor to sharpen.amount- 0 to 1, default 1.0. Full strength at 1.0; back it to 0.3–0.6 for a subtler result. Unlike unsharp masking there's no separate radius knob - the adaptive neighborhood handles that.batch_size- frames per processing chunk, 1–256, default 1.device-gpuorcpu.
Single image output, same shape in, same shape out.
When to reach for it
Three real use cases. Sharpening a batch of generated frames for consistency (video pipelines love this - same settings, every frame, no halos). A final detail pass before upscaling, since a clean sharpen upstream makes any later interpolation or model upscale look better. And as a cheap alternative to re-rolling generations that came out slightly soft - this is a deterministic, millisecond operation, in the same spirit as the KB's "reach for the primitive before the expensive pass" rule. If your source is already noisy, sharpen after any denoising, not before - CAS will happily amplify noise it thinks is detail.
Installing
Part of the bandifiu/ComfyUI-NN-custom-nodes pack:
cd ComfyUI/custom_nodes
git clone https://github.com/bandifiu/ComfyUI-NN-custom-nodes
Restart ComfyUI (or Manager → search "NN-custom-nodes"). Dependencies are torch, numpy, pillow - no models, no downloads, no exotic math libraries, because the CAS filter is implemented from scratch rather than bolted onto a dependency. The pack is GPL-3.0 and uses ComfyUI's newer V3 backend API (io.ComfyNode), so the source won't have the classic NODE_CLASS_MAPPINGS registration.
The realistic gotcha is expectation-setting: CAS sharpens edges, it doesn't add detail that isn't there. It will make a soft-but-clean image snap; it will not resurrect a blurry one. For genuinely soft output you want a generative upscaler (see the upscaling doc's ESRGAN/SeedVR2 territory) with CAS as the finishing touch afterward.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| amount | FLOAT | 1.000–1 | — |
| batch_size | INT | 11–256 | — |
| device | COMBO | gpu | 2 options: gpu, cpu |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |