Nodes/ComfyUI-BCNodes/Image Quality Gate
ComfyUI Node

Image Quality Gate

Keep the blurry ones out of the dataset

By 0xBeycan·Created 23 days ago·Updated 3 days ago· 2
Image Quality Gate
  • image
  • badge
  • verdict
  • report
  • blur_score
  • sharpness_score
  • noise_score
  • clipping_score
  • entropy_score
◄shot_type▾►
◄blur_mode▾►
◄blur_threshold0.40►
◄blur_var_threshold30►
◄sharpness_threshold15.0►
◄noise_threshold25.0►
◄clipping_threshold0.020►
◄entropy_threshold5.0►

The one piece of LoRA advice that has survived every architecture change is that dataset curation beats every knob. And the tedious half of curation is going through 400 generated images deciding which ones are actually sharp. This node does the first pass.

What it is

Five metrics, five thresholds, one verdict. Feed it an image and it hands back a colour-coded badge with the per-metric breakdown, an integer verdict, a text report, and the five raw scores.

| Verdict | Value | Meaning | |---|---|---| | PASS | 2 | every metric inside its threshold | | SO-SO | 1 | nothing failed hard, but something sits in the margin zone (within 1.4× of its threshold) | | FAIL | 0 | a metric is past the margin zone |

How it works

The five metrics are blur (block-wise Laplacian variance), sharpness (Laplacian + Tenengrad), noise (a Gaussian difference), highlight/shadow clipping, and Shannon entropy. Each is compared against your threshold, and the three-tier verdict folds them together.

shot_type is the part that makes it usable. The presets close-up, medium and wide / full-body scale the sliders - a close-up is judged more strictly on blur and sharpness, a wide shot more loosely, because frame-filling detail simply isn't there in a wide shot. custom uses your raw numbers.

blur_mode deserves a mention: center-weighted stops background bokeh from inflating the score. On a portrait deliberately shot with a soft background, full-image blur scoring will tell you the image is soft when the face is razor sharp. That's the mode to reach for on people.

The inputs you'll actually tune

Everything has a default that's roughly sensible, and two knobs do most of the work:

  • blur_var_threshold (default 30) - the per-block Laplacian variance that counts as blurry. The node's own guidance is the useful part: 20–50 for AI images, 80–150 for photographs. Distilled models produce inherently lower variance, so judging an AI image by camera numbers will fail almost everything you generate. Use the AI range and tighten from there.
  • sharpness_threshold (default 15) and noise_threshold (default 25) are the next two you'll nudge. clipping_threshold (0.02) and entropy_threshold (5.0, bits) are the ones I'd leave alone unless you know why.

Using it

Wire verdict into a switch ahead of your save node - PASS through, FAIL to a reject folder or dropped entirely - and put the badge somewhere you can see a batch at once. The report string is there for logging, and the five score outputs are for when a threshold is doing something you don't understand: read the number instead of the colour.

Calibrate before you trust it. Pick five images you already know are keepers and five you know are scrap, run them through, and set the thresholds so the two groups separate. Defaults tuned on someone else's model, resolution and shot type will misclassify yours.

Installing it

ComfyUI Manager → search ComfyUI-BCNodes → install → restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/0xBeycan/ComfyUI-BCNodes
pip install -r ComfyUI-BCNodes/requirements.txt

Reload the browser tab after the restart. It registers under BCNodes/analysis; the pack's requirements.txt covers PostFx and Caption Audit, not this node - it uses OpenCV and Pillow, which a normal ComfyUI install already has.

Where people get burned

AI numbers, not camera numbers. Covered above, and it's the reason most people conclude the node is broken on the first try. Set blur_var_threshold to 30, not 120.

Blur and sharpness are not the same complaint. Blur asks "is this frame out of focus"; sharpness asks "does this frame have detail". A clean, crisp image of a smooth subject can score low on sharpness and high on blur quality, and both readings are correct.

Noise threshold vs deliberate grain. If you run a film-grain pass - the cheapest single move there is for breaking the AI look - then judge the dataset before the grain goes on, or your own aesthetic choice reads as a defect.

It's a filter, not a curator. PASS means "nothing measurably wrong". Composition, hands, whether the picture is any good - not its job, and it won't pretend otherwise.

CategoryBCNodes/analysis

Inputs (9)

NameTypeDefaultDescription
imageIMAGE—
shot_typeCOMBO4 options: custom, close-up, medium, wide / full-body
blur_modeCOMBO2 options: full image, center-weighted
blur_thresholdFLOAT0.400–1Max blur ratio. Presets scale this; 'custom' uses as-is.
blur_var_thresholdFLOAT305–500Laplacian variance per block. AI-generated: 20-50, photos: 80-150.
sharpness_thresholdFLOAT15.00–500Min sharpness. Presets scale this; 'custom' uses as-is.
noise_thresholdFLOAT25.00–100Max noise level. Presets scale this; 'custom' uses as-is.
clipping_thresholdFLOAT0.0200–1Max clipping ratio. Presets scale this; 'custom' uses as-is.
entropy_thresholdFLOAT5.00–8Min entropy in bits. Presets scale this; 'custom' uses as-is.

Outputs (8)

NameTypeDescription
badgeIMAGE—
verdictINT—
reportSTRING—
blur_scoreFLOAT—
sharpness_scoreFLOAT—
noise_scoreFLOAT—
clipping_scoreFLOAT—
entropy_scoreFLOAT—