Nodes/Bart's ComfyUI Nodes/Bart's Anatomy Defect Filter (Ollama) πŸ”
ComfyUI Node

Bart's Anatomy Defect Filter (Ollama) πŸ”

A local vision model as bouncer for your batch

By bartenevveΒ·Created 4 months agoΒ·Updated 7 days agoΒ· 1
Bart's Anatomy Defect Filter (Ollama) πŸ”
  • images
  • passed
  • failed
  • report
  • report_json
  • passed_indices
  • failed_indices
β—„ollama_urlhttp://localhost:11434β–Ί
β—„modelqwen3-vl:8bβ–Ί
β—„extra_limbstrueβ–Ί
β—„missing_limbsfalseβ–Ί
β—„bad_fingerstrueβ–Ί
β—„smeared_limbstrueβ–Ί
β—„impossible_posetrueβ–Ί
β—„face_deformationfalseβ–Ί
β—„merged_bodiesfalseβ–Ί
β—„custom_criterionβ–Ί
β—„confidence_threshold0.60β–Ί
β—„max_side768β–Ί
β—„timeout120β–Ί
β—„num_ctx4096β–Ί
β—„append_no_thinktrueβ–Ί
β—„seed0β–Ί
β—„empty_branchblockerβ–Ί

You queued 64 images. Somewhere in there are fifty you'd keep, ten mediocre ones, and four where somebody's arm grows out of a ribcage. Bart's Anatomy Defect Filter (AnatomyDefectFilter) sorts that for you: image batch in, passed and failed batches out, decided by asking a local vision model whether each picture has the defects you ticked.

Two things first. It doesn't fix anything - repairing the six-fingered hand is the detailing family's job (hand_yolov8 feeding an inpaint pass, not this). And "(Ollama)" is the honest part of the name: no cloud API, no key, but you do need an Ollama server reachable over HTTP.

How it works

Per image, the node slices one frame, downscales the longest side to max_side (768 default), encodes a quality-92 JPEG and makes exactly one POST to /api/chat on your ollama_url. The prompt is a checklist where each line describes a problem; the model answers with JSON giving, per check, found (is this problem present?), a 0–1 confidence and a short note. The request pins temperature: 0, a seed, format: json and a 1024-token cap.

The decision rule is one line: any check marked found at or above confidence_threshold fails the image. Parsing is forgiving (code fences, checks nested or top-level, 85 read as 0.85), and unparsable output gets one retry with a different seed before a hard error - so it never quietly files an image as passed when the model said nothing usable. The trap: lower confidence_threshold is stricter. At 0.25 you fail anything the model is a quarter sure about.

Inputs and outputs

Feed images. Point ollama_url at the server as the ComfyUI machine sees it, and set model to the name Ollama knows (ollama list) - a plain text field on purpose, because a browser-populated dropdown would turn your ComfyUI into an open proxy. It must be a chat-capable vision model: qwen3-vl:8b is the default, and llama3.2-vision, gemma3 and minicpm-v qualify too. An embedding model can't answer "does this hand have six fingers" - it only returns a vector.

Then the checkboxes: extra_limbs, missing_limbs, bad_fingers, smeared_limbs, impossible_pose, face_deformation, merged_bodies - four on by default, with the face and merged-body ones off, presumably because they fire on crowds. custom_criterion is free text evaluated like the built-ins; phrase it as a problem, one line, like a hand holding the cup has no thumb. Phrase it as an expectation and the verdict comes out inverted.

The rest is plumbing: max_side (hands need pixels, but bigger is slower), timeout, seed, append_no_think, num_ctx. Leave num_ctx at 4096 - Ollama otherwise sizes context from free memory, and the author measured 22GB of it for one image on a 32GB box, which dragged qwen3-vl:8b under 1 token/s.

Outputs: passed / failed as IMAGE batches, report (lines like #3 FAIL bad_fingers (0.85): six fingers on left hand), report_json, and passed_indices / failed_indices as comma-separated positions so you can reorder a filtered set. Usual wiring: failed into a Save Image under an output/rejected/ prefix, passed into a Preview. The text outputs always fire.

empty_branch covers a side ending up with no images: blocker (default) feeds it an ExecutionBlocker, so a Save on failed doesn't run - but every downstream node of that output is skipped, not just the Save - while placeholder emits one black image, so downstream always runs.

Install

Nothing to pip install - the Ollama client is stdlib urllib, and torch, Pillow and numpy already ship with ComfyUI. Find comfyui-bart-nodes in ComfyUI Manager, or clone it:

cd ComfyUI/custom_nodes
git clone https://github.com/bartenevve/comfyui-random-imageload-node comfyui-bart-nodes

Restart ComfyUI, then give it a server and a model (ollama pull qwen3-vl:8b, ollama list to check the name). There's a ready-made graph in the pack, example_workflows/05_anatomy_filter.json, listed in ComfyUI under Templates.

What actually goes wrong

cannot reach ollama at ... is the classic. The URL resolves from the ComfyUI process, not your browser, so a ComfyUI in Docker can't see your host's Ollama on localhost - use the host IP or a container name.

Empty answers. Thinking-capable models burn their whole budget and return nothing in content; keep append_no_think on for anything qwen3-family, and the error says when that's what happened. A mistyped model name surfaces as an Ollama error, not a dropdown warning - the cost of the plain text field.

It's slow, and it scales badly. One serial HTTP request per image, each a full vision forward pass, so check timeout (120s) before assuming it hung.

Judgement quality is the real limit, in both directions. A 7–8B VLM will pass a mangled hand and fail a perfectly good one; finger counting is close to its worst case. The community's version of that complaint: a vision judge "could easily misdetect the image as looking bad when you would think it looks good." Run it over ~20 images you've judged by hand, tune model and threshold there, then point it at hundreds - and treat report as a triage list to skim. Re-queuing an unchanged graph is cached, so you won't re-ask the model until something changes.

Finally: your images go to whatever ollama_url the workflow names, with no allowlist and no HTTP routes of this node's own, so a graph someone else wrote can aim it at any host reachable from yours. That's the same caution the whole "a VLM inside your graph" category earns - and it's exactly the category people install without reading. This one is MIT, readable, and tests its verdict parsing and Ollama client, which is more than most manage.

CategoryBart's nodes/Image

Inputs (18)

NameTypeDefaultDescription
imagesIMAGEβ€”
ollama_urlSTRINGhttp://localhost:11434β€”
modelSTRINGqwen3-vl:8bβ€”
extra_limbsBOOLEANtrueβ€”
missing_limbsBOOLEANfalseβ€”
bad_fingersBOOLEANtrueβ€”
smeared_limbsBOOLEANtrueβ€”
impossible_poseBOOLEANtrueβ€”
face_deformationBOOLEANfalseβ€”
merged_bodiesBOOLEANfalseβ€”
custom_criterionSTRINGβ€”
confidence_thresholdFLOAT0.600–1β€”
max_sideINT768128–4096β€”
timeoutINT1205–3600β€”
num_ctxINT40962048–32768β€”
append_no_thinkBOOLEANtrueβ€”
seedINT00–2147483647β€”
empty_branchCOMBOblocker2 options: blocker, placeholder

Outputs (6)

NameTypeDescription
passedIMAGEβ€”
failedIMAGEβ€”
reportSTRINGβ€”
report_jsonSTRINGβ€”
passed_indicesSTRINGβ€”
failed_indicesSTRINGβ€”