Batch Router
Turn four separate opinions into one folder name
- target_dir
- passed
- failed
- report
By the time you've decided an image is usable, three different nodes have an opinion: the anatomy checker says the hands are fine, the face matcher says that's the right person, and the detector says there are one, not three, heads in frame. Batch Router is the node that collects those opinions and answers with a single string - the folder the picture belongs in.
How it works
Three boolean gates (gate_a, gate_b, gate_c) plus one optional integer count, combined by combine. all means every connected gate has to pass; any means one is enough. Then count_min / count_max bound the count input - wire Person Selector's face_count in, set 1 and 1, and you've written "exactly one person". The result is target_dir, which is either pass_dir or fail_dir.
The subtle bit, and the reason this node doesn't drive you mad: an unconnected gate is "not asked", not "false". You can build the graph in stages - wire the reality check today, add the identity check next week - and a gate you haven't hooked up yet can't reject your entire batch. That's the opposite of how a naive AND node behaves, and it's the correct default for an incremental workflow.
invert swaps the two folders, which is the trick for collecting rejects: point the pass folder at your reject pile and flip the boolean.
Inputs and outputs
pass_dir/fail_dir- the two destinations. Usually wired straight from Batch Load Image'spass_dir/fail_dir, which is what stops you typing a path twice and getting one of them wrong.combine-allorany.label_a/label_b/label_c- free text names for the gates (reality,identity,extraby default). These show up in the report, which is the whole point: the report should read like a sentence, not likeA=1 B=0 C=1.count_min/count_max- the acceptable range oncount, ignored whencountisn't connected.report_in- an upstream report that gets prepended to this node's own. Chain Reality Check'sreportthrough here and Batch Save Image'sreportsidecar ends up recording why each file landed in the folder it did. That sidecar convention - one.txtnext to the picture - is the same one captioning tools use for training sets, and it's what makes a sorted folder auditable a month later.
Outputs: target_dir (a STRING, into Batch Save Image's directory), passed, failed, and report.
Install
Same pack, same steps, no extra dependencies for this node:
cd ComfyUI/custom_nodes
git clone https://github.com/ping1979ping/comfyui-FVMtools
Restart, or install via ComfyUI Manager by searching comfyui-fvmtools. The face and segmentation machinery the rest of the pack uses needs insightface, onnxruntime-gpu, opencv-python plus the buffalo_l and BiSeNet models - Batch Router itself is pure logic and runs on a bare ComfyUI install.
Traps
Empty pass_dir and fail_dir are the number one complaint: the node will happily return a target_dir of "" and the saver will go nowhere useful. Wire them from the loader.
combine = any with all three gates connected is a very forgiving filter - one green light and the file is kept. If your rejects are leaking through, check you didn't set any while thinking "all".
And don't build the count range around a value that can be absent. If Person Selector finds no faces at all, face_count is 0 and a 1..1 range rejects the picture - which is usually right, but it means "no face detected" and "wrong person" land in the same folder. If you care about telling those apart, use a second router downstream with label_a reading no_face, and let the report do the explaining.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| pass_dir | STRING | Folder for pictures that clear every gate. | |
| fail_dir | STRING | Folder for pictures that fail any gate. | |
| combine | COMBO | all | all: every connected gate must pass. any: one is enough. |
| label_a | STRING | reality | — |
| label_b | STRING | identity | — |
| label_c | STRING | extra | — |
| count_min | INT | 10–100 | Lowest acceptable value on the count input — e.g. 1 face. Ignored when count is unconnected. |
| count_max | INT | 10–100 | Highest acceptable value on the count input. 1/1 means 'exactly one person'. |
| invert | BOOLEAN | false | Swap the two folders — useful to collect rejects. |
| gate_aopt | BOOLEAN | — | |
| gate_bopt | BOOLEAN | — | |
| gate_copt | BOOLEAN | — | |
| countopt | INT | A count to bound, e.g. PersonSelector's face_count. | |
| report_inopt | STRING | Upstream report, prepended to this node's own. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| target_dir | STRING | — |
| passed | BOOLEAN | — |
| failed | BOOLEAN | — |
| report | STRING | — |