Nodes/imgutils/Imgutils JSON Filter
ComfyUI Node

Imgutils JSON Filter

Re-Threshold a Tagger's JSON Without Re-Running the Model

By xiaden·Created 2 months ago·Updated 2 months ago· 0
Imgutils JSON Filter
    • json
    • tags
    • count
    json
    threshold0.50

    Every tagger in the imgutils pack bakes its threshold in at the node - and then hands you the full scored distribution in its json output anyway. Imgutils JSON Filter is for when you want a different cutoff than the one the node used, without paying to run the model again: feed it that scored JSON dict, set a threshold, and get back a filtered JSON, a prompt-ready tag string, and a count.

    Why you'd reach for it

    The taggers give you two outputs: tags (already thresholded, comma-separated) and json (the full score map). The tags output is the default view; JSON Filter is the "reconsider" view. Maybe the node's threshold was too loose and your prompt is drowning in junk tags. Maybe you want a stricter list for a LoRA caption than for a fun prompt. Maybe you want the top N tags by score. All of that is a filter away instead of a re-inference. The KB's captioning material (lora-training, llm-in-comfyui) keeps hammering that tag quality is dataset quality - a stricter secondary threshold is a legitimate cheap upgrade to your captions.

    How it works

    The node accepts a JSON dict of {key: score}. It's smart about one structural wrinkle: the sectioned taggers (WD14, Camie, DeepDanbooru, DeepGelbooru) emit {"rating": {...}, "general": {...}, "character": {...}} - nested dicts. JSON Filter flattens those into one flat map, keeps only entries whose score is >= your threshold, sorts by score descending, and builds the outputs.

    The interface

    • json (STRING) - the scored dict, e.g. a tagger's json or a classifier's json output.
    • threshold (FLOAT, default 0.5, 0–1, step 0.01) - minimum score to keep.
    • Outputs: json (the filtered dict, sorted), tags (keys joined with commas - this is your prompt-ready string), count (INT, how many passed).

    Honest take

    Two things to know. First, the flattening loses your rating/general/character sectioning - fine for building a prompt, wrong if you specifically needed the sections separated (use the tagger's own tags output for that). Second, count is quietly the most useful output here: it turns "how many tags survived" into a signal you can gate on. "Fewer than three tags at 0.6 → this is probably a blank or degenerate frame → skip it." That's a real dataset-cleaning move.

    Install

    cd ComfyUI/custom_nodes
    git clone https://github.com/xiaden/comfyui-imgutils.git
    cd comfyui-imgutils
    pip install -r requirements.txt
    

    Or via ComfyUI Manager (search "imgutils"). Needs ComfyUI >= 0.25.0 and Python >= 3.10; dependency is dghs-imgutils[gpu]. No model, no downloads - it's pure dict filtering.

    Troubleshooting

    If the node returns an empty map on input you know is scored, check whether the scores are actually numeric - a serialized dict of strings (or a detections-style output) yields nothing after filtering. And if your tags output looks thin at the default 0.5, that's the threshold working as intended; drop it toward 0.3 and you'll watch the tag list fatten with noise, which is the tradeoff made visible.

    Categoryimgutils/utility

    Inputs (2)

    NameTypeDefaultDescription
    jsonSTRINGJSON string dict of {key: score} to filter.
    thresholdFLOAT0.500–1Minimum score to keep.

    Outputs (3)

    NameTypeDescription
    jsonSTRING
    tagsSTRING
    countINT