Nodes/CCIP Judge/Image Router (liked/disliked)
ComfyUI Node

Image Router (liked/disliked)

The end of the judge pipeline that splits liked from disliked

By o-ankomochi-o·Created 3 months ago·Updated 29 days ago· 0
Image Router (liked/disliked)
  • image
  • liked
  • disliked
  • info
pass_mask
save_liked_dir
save_disliked_dir
liked_prefixliked
disliked_prefixdisliked
clear_dirs_before_savefalse
csv_dir
ccip_threshold0.213
oks_threshold0.50
angle_threshold0.50
ccip_distance
oks
angle_distance
pose_reasons
angle_reasons
reach_d
gate_status
gate_reason

Every scoring pipeline ends the same way: you've got a batch of images and a list of booleans, and you need the good ones separated from the bad ones. Image Router is the final stage of the CCIP Judge pack - the node that takes your batch plus a pass_mask and hands you two clean outputs: liked and disliked.

It's deliberately more than a filter. The author's stated design goal is that the liked output feeds straight into downstream nodes like IPAdapter - no saving to disk and reloading in between. Both outputs are always IMAGE tensors, and here's a detail people love once they notice it: when a branch is empty, the router doesn't emit a fake black image. It emits ComfyUI's ExecutionBlocker, which stops that branch from executing at all. No garbage black frames polluting your pipeline, no wasted inference.

What it does when you ask it to save

  • save_liked_dir / save_disliked_dir - where each branch gets written. Leave empty and it skips saving that side entirely. Use dedicated directories, not the same folder as your reference images - the README says so, and it means the "clear" button won't nuke anything precious.
  • liked_prefix / disliked_prefix - filename stems, defaulting to liked/disliked. They're sanitized so a widget value can never contain a path or traversal sequence - the node forces prefixes to be plain filename stems. Saved files embed the original batch index ({prefix}_idx00042_...png), which is how you trace a specific generation back to its verdict.
  • clear_dirs_before_save - a careful reset: it deletes only the files this node wrote before ({prefix}_idx*.png and scores_*.csv), never your other files in the same folder.
  • csv_dir - writes a scores_*.csv report when you connect the optional score inputs. This is your batch's audit trail.
  • It never overwrites - on a filename collision it appends a numeric suffix. Run the same batch twice and both result sets survive.

The inputs that matter

Required: image (the batch), pass_mask (from Three-Stage Filter, or a scorer's mask if you're doing a single-metric run), the save settings above, and the three thresholds (ccip_threshold, oks_threshold, angle_threshold) - those thresholds are what the CSV report uses to mark each row pass/fail.

Optional: ccip_distance, oks, angle_distance, plus pose_reasons and angle_reasons from the OKS/Angle scorers. Wire them up and the CSV becomes genuinely useful - it records per-image scores, the failure reasons, and empty cells plus a detect_failed flag for NaN images. That CSV is the backbone of the pack's optional Optuna threshold-search script, but you don't need any of that for normal use.

Outputs: liked, disliked (IMAGE), and info (a summary string). Wire liked into a Save Image node, a preview, or straight into whatever eats images next.

Installing

cd ComfyUI/custom_nodes
git clone https://github.com/o-ankomochi-o/comfyui-ccip-judge.git
cd comfyui-ccip-judge
python -m pip install -r requirements.txt

Or search "CCIP Judge" in ComfyUI Manager. Python 3.10–3.12, don't double-install onnxruntime and onnxruntime-gpu, and the DWPose model fetches from Hugging Face on the first scorer run.

Where people get burned

  • Length mismatch. The router compares image count to pass_mask length and errors loudly if they differ - usually a stale cache or a scorer you re-ran with different settings mid-pipeline. Rerun the whole graph.
  • Security hygiene. Save directories and reference_folder are arbitrary local paths your ComfyUI process can read and write. Before running a workflow you didn't build, check the path fields - the README treats this as a real concern, not theater.
  • Group shots still get routed by whoever has the biggest bounding box upstream, and the router won't save you from that - fix it at the scorer stage.
Categoryimage_judge

Inputs (19)

NameTypeDefaultDescription
imageIMAGE
pass_maskBOOLEAN
save_liked_dirSTRING
save_disliked_dirSTRING
liked_prefixSTRINGliked
disliked_prefixSTRINGdisliked
clear_dirs_before_saveBOOLEANfalse
csv_dirSTRING
ccip_thresholdFLOAT0.2130–2
oks_thresholdFLOAT0.500–1
angle_thresholdFLOAT0.500–5
ccip_distanceoptFLOAT
oksoptFLOAT
angle_distanceoptFLOAT
pose_reasonsoptSTRING
angle_reasonsoptSTRING
reach_doptFLOAT
gate_statusoptSTRING
gate_reasonoptSTRING

Outputs (3)

NameTypeDescription
likedIMAGE
dislikedIMAGE
infoSTRING