Nodes/ComfyUI CV/cv2.detailEnhance
ComfyUI Node

cv2.detailEnhance

Local contrast pop from two sliders, no model

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.detailEnhance
  • src
  • result
◄sigma_s10.0000►
◄sigma_r0.1500►

cv2.detailEnhance is the deterministic, model-free answer to "this image looks flat, can you make the detail read". It's one of OpenCV's photo-module NPR filters - the same family as edgePreservingFilter, pencilSketch and stylization, all built on edge-preserving smoothing - and it does what it says: it boosts local structure while leaving the overall tonality roughly where it was. No diffusion pass, no VRAM, instant.

How it differs from sharpening

The KB's post-processing notes make the point that "sharpening is unsharp masking, and the name is literally the recipe" - blur a copy, subtract, add the difference back scaled. That's a high-pass operation and it's why cranking it produces halos: you're amplifying noise and edge overshoot together. detailEnhance is the same idea (make local detail stronger) built on an edge-aware decomposition instead: flat regions get smoothed and left alone, structure gets its contrast lifted. It's closer in spirit to a local-contrast or "clarity" slider in a RAW editor than to a sharpen radius/amount pair.

That also means it's not interchangeable with a sharpen node in this pack (cv2.unsharpMask-style nodes elsewhere), and it's not a substitute for a proper upscale. What it's good at is texture and mid-frequency structure: skin, fabric, foliage, stone - the stuff that makes an image look rendered when it's too smooth.

The inputs

src must be an 8-bit, three-channel image, and it accepts an IMAGE link directly. The output echoes that format - an IMAGE in gives an IMAGE out - so you can preview it immediately rather than doing the CV Array → Image dance. It's one of the type-preserving wrappers in this pack.

The two knobs are the whole filter, and the pack's own tooltips describe them better than OpenCV's docs do:

  • sigma_s (FLOAT, default 10, range 0–200) - the spatial scale, "how far the filter reaches. Bigger = stronger flattening". In practice this is the size of the features it treats as detail: small values lift fine texture, big values lift broader shapes and can start to look like a bad HDR.
  • sigma_r (FLOAT, default 0.15, range 0–1) - the range threshold, "colour differences below it are smoothed away, above it are kept as edges. Bigger = fewer surviving edges". Lower it and the filter sees more of your image as edges; push it too far down and you amplify noise along with the structure.

Defaults are sensible. Change one at a time.

Where it fits in a workflow

A cheap final-pass punch on a finished render before you export, especially on images that came out of a high-denoise or heavy-upscale pipeline where micro-detail got smoothed away. Or the opposite move: run it as a reference while comparing two upscale paths, since it makes the difference in retained detail obvious. And because it's deterministic and instantaneous, you can use it in a batch loop without worrying about what sampling does to the look.

The honest limit: it can't invent detail that isn't there, and past a point it starts to produce the flattened, over-processed look that every clarity slider is notorious for. If your problem is that a 512px generation doesn't hold up at 4K, this is not the fix - that's upscaling territory, and this pack's cv2.detail.* and photo wrappers won't help. What it's for is the last 5%, not the first 50%.

Install

Manager → Install Custom Nodes → ComfyUI CV (publisher bmad4ever), or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"

Restart ComfyUI. Python ≥ 3.12 and a recent V3-API ComfyUI; the contrib headless OpenCV wheel is the only dependency and no models are downloaded. This function is core OpenCV, but the pack as a whole wants the contrib build: all four OpenCV wheels share one site-packages/cv2, so installing plain opencv-python over it empties the contrib submodules and those nodes disappear (python tools/repair_opencv_contrib.py --check, then --apply). The pack is GPL-3.0, forked from geroldmeisinger/opencv-comfyui, largely LLM-written, and the author's disclaimer is explicit that it isn't production-ready.

Common issues

  • Type assertion on execution. Colour images only, 8-bit. A MASK or a 4-channel image will raise; convert first.
  • The image looks flattened and plasticky. sigma_s too high. Come back toward 5–15 for a photoreal pass.
  • Noise and grain got louder. sigma_r too low - you've moved the edge threshold below your sensor/compression noise. Raise it toward 0.15–0.25.
  • Nothing happens. At small image sizes there's little mid-frequency structure to lift; the effect is strongest on large images with real detail in them.
Categoryimage/CV/low-level/cv2 D

Inputs (3)

NameTypeDefaultDescription
srcCOMFY_MATCHTYPE_V3Input 8-bit 3-channel image. The image output(s) echo this input's format. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.
sigma_soptFLOAT10.0000-1e+38–1e+38%Range between 0 to 200. Preset to the OpenCV default (10.0).
sigma_roptFLOAT0.1500-1e+38–1e+38%Range between 0 to 1. Preset to the OpenCV default (0.15).

Outputs (1)

NameTypeDescription
resultCOMFY_MATCHTYPE_V3Echoes the 'src' input's format: an IMAGE link comes back as IMAGE, MASK as MASK, NPARRAY stays NPARRAY.