Nodes/comfyui-english-annotator/πŸ“š English Word Annotator
ComfyUI Node

πŸ“š English Word Annotator

Turn any generated scene into a labeled vocabulary card β€” boxes and English words, no drawing by hand

By aadebugerΒ·Created 3 months agoΒ·Updated 3 months agoΒ· 0
πŸ“š English Word Annotator
  • image
  • bboxes
  • labels
  • image
β—„font_size36β–Ί
β—„box_width4β–Ί
β—„label_positionaboveβ–Ί
β—„font_pathβ–Ί
β—„text_color#FFFFFFβ–Ί
β—„max_labels0β–Ί

The name sounds fancier than the job, and that's the point. πŸ“š English Word Annotator doesn't detect anything, call any API, or need a key. It's a pure renderer: you hand it an image, a list of bounding boxes, and a list of English labels, and it draws a colored rectangle around each object with the word printed in a little colored tag. It was built for one specific thing - vocabulary learning cards - and it's honestly the cleanest way to get there in ComfyUI.

Here's the workflow it's meant to sit in. Generate a scene (SDXL, Flux, whatever - the README demos Z-Image-Turbo), then run Florence-2 in detection mode to get per-object boxes and labels, then feed both into this node and save the result. The rendering step is the part nobody wants to hand-roll in PIL, and that's the whole package: one node, one file, about 250 lines.

How it works

The mechanism is boring in the best way. The image input (an IMAGE tensor) gets converted to a PIL image, boxes are drawn with ImageDraw, labels are stamped in a filled pill above or inside each box, and the result goes back to an IMAGE tensor. Two details save you from real pain:

  • An AnyType wildcard on bboxes and labels. Florence-2 wrappers have changed their output shape across releases - flat lists, batch-wrapped lists, even {"bbox":..., "label":...} dicts from older versions. This node normalizes all of them. If you're fighting a type mismatch between Florence-2 versions, this is the node that shrugs and works.
  • Sensible fallbacks. Boxes are clipped to image bounds, degenerate boxes are skipped, and if a label tag doesn't fit above the box it falls back inside. If you're missing a label for a box, you get #1, #2… instead of a crash.

An 8-color palette cycles so adjacent boxes stay distinguishable - no two neighbors get the same tint.

The inputs that matter

Required: image, bboxes, labels. That's it - everything else has a sensible default.

  • label_position (above / inside_top / below) - where the word tag sits. above is the default and usually the right call for study cards; inside_top if objects run to the top edge.
  • font_size (default 36) and box_width (default 4) - text size and outline thickness. Bump font_size for big classroom cards.
  • max_labels (default 0, and 0 = no limit) - cap how many objects get annotated. Handy when Florence-2 finds 20 regions and you only want the first five.
  • font_path and text_color (both optional) - an explicit TTF path if you hate the defaults, and a hex text color.

One output: image. Wire it straight into SaveImage or PreviewImage. It only draws on the first frame of a batch, so don't feed it a video.

Install

It's two minutes. Either ComfyUI Manager (search "English Annotator") or:

cd ComfyUI/custom_nodes
git clone https://github.com/aadebuger/ComfyUI-EnglishAnnotator.git
cd ComfyUI-EnglishAnnotator
uv pip install -r requirements.txt   # just Pillow + numpy

Restart ComfyUI and it appears under πŸ“š English Annotator. The node itself is featherweight - the real dependency is upstream: you'll also want kijai/ComfyUI-Florence2 (and its Florence-2-base/large weights, which download on first run and can be several GB). The README's example flow is CheckpointLoader β†’ KSampler β†’ VAEDecode feeding the image, with Florence2ModelLoader β†’ Florence2Run feeding boxes and labels.

Gotchas

  • Labels render as empty boxes or squares on a fresh headless Linux box - no fonts installed. sudo apt install fonts-dejavu-core fixes it.
  • Florence-2 is the fragile half. Its transformers dependency needs >=4.41 but can clash with other packs locked to 4.x; if Florence2ModelLoader complains, upgrade it but stay below 5.0. And flash_attn import errors - set attention="sdpa" on Florence2Run.
  • Long labels overflow their colored pill - the box is clamped to the image edge but the text isn't wrapped, so a word like "refrigerator" on a small box will spill right. Keep words short or bump font_size down.
  • Uses uv pip install, not pip if your venv is uv-managed - uv venvs ship no pip, and python -m pip will just fail.

For task mode, od gives clean COCO category names; caption_to_phrase_grounding is the one to reach for when you have a fixed vocabulary list and want Florence-2 to lock onto exactly those words - which is precisely the daily-vocab pipeline this node was built for.

CategoryπŸ“š English Annotator

Inputs (9)

NameTypeDefaultDescription
imageIMAGEβ€”
bboxes*β€”
labels*β€”
font_sizeINT368–256β€”
box_widthINT41–20β€”
label_positionCOMBOabove3 options: above, inside_top, below
font_pathoptSTRINGβ€”
text_coloroptSTRING#FFFFFFβ€”
max_labelsoptINT00–1000 = no limit

Outputs (1)

NameTypeDescription
imageIMAGEβ€”