Quality Gate (score & pass)
Score a batch and let the workflow decide
- images
- images
- score
- all_passed
- report
The most expensive thing in ComfyUI is time spent upscaling, detailing, and post-processing an image that should have been deleted at birth. The QualityGate node is the checkpoint that catches it: it looks at a batch, gives it a score and a pass/fail verdict, and hands you back the images untouched - it's a sensor, not a filter. You decide what happens next based on what it tells you.
Its sibling QualityFilterBatch physically splits a batch into passing and rejected images. This node is the more interesting one, because its all_passed boolean output is built for loops: wire it into an IF/switch, and the workflow itself can decide whether to upscale this batch or throw it away and try again with a new seed. That's the "stop wasting GPU on bad seeds" pattern the community keeps asking for, done with no external models and no API.
What it scores
Same two default checks as the filter: face presence (OpenCV's bundled Haar cascade, so no downloads) and sharpness (Laplacian variance). Each image passes when both checks pass and the aggregate score clears your threshold. No reference images required - this is purely a "is this a coherent, sharp, correctly-populated image" gate, not a "does it match my subject" gate. For likeness or head-size ranking you want the pack's ranker nodes instead.
Inputs and outputs
Three inputs, all self-explanatory:
images- the batch to evaluate.threshold- aggregate pass cutoff, default 0.6.expected_faces- target face count, default 1; 0 disables the face check.
The outputs are the payload:
images- the batch passed through unchanged. This node never modifies, reorders, or crops a pixel.score- the mean score across the batch, 0 to 1. Feed it to a text display or log it to watch quality drift over many runs.all_passed- a boolean that's true only when every image passes. This is the wire you attach to your retry logic.report- the audit trail, one line per image with each check's score and detail.
The loop pattern
The setup that makes this node shine:
KSampler→VAEDecode→QualityGate.all_passed→ a switch. If false, re-roll with a different seed (change the seed, queue again). If true, let the images continue to your upscaler or detailer.- Optionally gate the expensive nodes behind
scorewith a minimum, so a 0.3 average never reaches a 4x upscale.
That's the whole game: cheap evaluation before expensive post-processing. The evaluation itself is nearly free - Haar detection plus a grayscale convolution runs in milliseconds per image and needs no GPU work beyond what's already in flight.
Two practical notes. First, "quality" here is coarse by design - it catches blobs, blank frames, and heavy blur, not subtle aesthetic differences. If you need finer judgment, you're looking at the pack's ranking nodes or an aesthetic scorer. Second, because both sides of a boolean verdict can be "all images fail," design the false branch to regenerate rather than feed an empty batch downstream - the pack's own design philosophy is to protect the downstream pipeline, and your loop should do the same.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| threshold | FLOAT | 0.600–1 | — |
| expected_faces | INT | 10–20 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| score | FLOAT | — |
| all_passed | BOOLEAN | — |
| report | STRING | — |