Quality Filter Batch (deliver only passing)
Hand it a batch, get back only the good frames
- images
- passed_images
- rejected_images
- passed_count
- report
Somewhere in every batch-generation pipeline there's a moment where you look at forty images and thirty-seven of them are fine, two are blurred, and one has three faces. Quality Filter Batch automates that triage: it splits an input batch into passed_images and rejected_images, so downstream nodes only ever touch the frames that earned their way through.
It's the no-reference member of the QualityGate pack. Unlike the ranking nodes, this one doesn't need a face reference, a proportion reference, or any of the heavy optional dependencies - it runs on the two checks the pack ships by default: face presence and sharpness.
What "quality" means here
The checks are deliberately simple, and that's the point:
- Face presence - an OpenCV Haar cascade counts faces. If you asked for one face and got zero (a botched render where the model forgot a face) or three (the "everyone's a twin" failure), it fails. Haar is the cheap, bundled option - no downloads, no model files - which is exactly why it's the default.
- Sharpness - Laplacian variance, the standard blur detector. Melted, detail-free regions show up as a sharp drop in variance.
An image passes only if both checks pass and the aggregate score meets your threshold. That dual gate matters: a sharp image of a faceless blob passes nothing, and a clear face at half resolution doesn't skate by on sharpness alone.
Inputs and outputs
images- the batch, typically fromVAEDecode.threshold- aggregate score cutoff, 0 to 1, default 0.6. Raise it to be pickier about marginal frames.expected_faces- how many faces you want, default 1. Set to 0 to skip the face-count requirement entirely (useful for scenes with no people).
Outputs: passed_images, rejected_images, passed_count (so you can feed the number into a conditional), and report - a per-image table showing each check's score and a PASS/FAIL flag.
Where it fits
The classic wiring: VAEDecode → QualityFilterBatch → passed_images → SaveImage, with rejected_images going to a discard node or a "regenerate these" branch. Since it hands you both sides split apart, you can even route rejects back into a retry loop instead of losing them. Pair it with the pack's QualityGate node if you want a boolean "did the whole batch pass" verdict rather than a split.
One quirk worth knowing: the node guarantees neither output is empty - if every image passes or every image fails, the empty side is filled with a copy of the first input image so downstream nodes never choke. That's friendly, but it means you shouldn't test "did anything pass" by checking whether rejected_images is empty. Use passed_count instead.
It's the low-friction on-ramp to this pack: no extra models, no GPU-hungry dependencies, just opencv and numpy, which ComfyUI already has. If you're already deleting blurry frames by hand, this is the smallest upgrade that makes that step automatic.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| threshold | FLOAT | 0.600–1 | — |
| expected_faces | INT | 10–20 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| passed_images | IMAGE | — |
| rejected_images | IMAGE | — |
| passed_count | INT | — |
| report | STRING | — |