Grounding Detector
One Node, 19 Models, No API Keys, Just a Prompt
- model
- image
- bboxes
- annotated_image
- labels
- masks
The name sounds like it's going to phone home to some cloud API. It doesn't. Everything here is local: you type "person . car . dog ." into a prompt box, GroundingDetector looks at the image with the model you loaded, and returns bounding boxes, an annotated preview, labels, and even rough masks. It's the workhorse of the ComfyUI-Grounding pack, and it's the node you'll reach for whenever a workflow needs to find things by description before doing anything with them.
That "find by text" step is the grounding part, and it's what separates this from the background-removal family. rembg and BiRefNet give you "foreground vs background" - this gives you "the red car on the left" specifically, which is why the KB's background-removal essay pairs GroundingDINO with SAM for selective masking and why inpainting guides lean on text-grounded masks. GroundingDetector is the box half of that pipeline; Sam2 Segment (or Grounding Mask Detector) is the mask half.
How it works
The node is a thin dispatcher. Whatever GROUNDING_MODEL you wired in from the loader, it routes the prompt to that backend - GroundingDINO/MM-GroundingDINO, OWLv2, Florence-2, or YOLO-World - and normalizes the results. It also always generates masks from the boxes, so you get a MASK output even before SAM2 touches anything. Fair warning: those masks are just filled rectangles. Fine for cropping, crude for inpainting edges.
The signature behavior is label parsing. Periods split into multiple objects; commas make one compound label. So "dog. cat." finds dogs and cats, while "small, brown dog" hunts for an item literally described as "small, brown dog". This trips people up constantly, and it's genuinely the difference between one box and ten.
The inputs that matter
prompt- the whole game. Use the period/comma rule above.confidence_threshold- 0.3 default. The tooltip's guidance is honest: 0.2–0.35 permissive, 0.35–0.5 balanced, 0.5+ strict. If you're getting junk boxes, raise it; if the detector is missing things, lower it.single_box_mode- return only the top detection. This is your friend for referring expressions like "the red car on the left".single_box_per_prompt_mode- best box per label instead of one global winner.bbox_output_format- keeplist_onlyif you're feeding boxes into Sam2 Segment (that's the compatible format); switch todict_with_dataif you want the labels and scores alongside.seed- fixes mask-visualization colors and model randomness for reproducible runs.
The rest of the optional inputs are model-specific and only bite when that model is loaded: text_threshold (GroundingDINO only), florence2_max_tokens/florence2_num_beams, and the yolo_* trio (IoU, class-agnostic NMS, max detections). Don't touch them until you're tuning a specific backend.
Outputs
Four wires: bboxes (into Sam2 Segment or BboxVisualizer), annotated_image (preview with boxes drawn), labels (a string like person (0.92), car (0.87)), and masks (the coarse rectangles). If all you need is a quick "did it find it?" check, route annotated_image to a preview node and move on.
Installing it
One pack install covers every node here:
cd ComfyUI/custom_nodes/
git clone https://github.com/PozzettiAndrea/ComfyUI-Grounding
cd ComfyUI-Grounding
pip install -r requirements.txt
Or install "ComfyUI-Grounding" from ComfyUI Manager. Models download on first use - the loader hits Hugging Face when you pick a model, so expect a wait on first run per model, then cached reloads after that.
Where people get burned
- The
text_thresholdtrap - it does nothing unless GroundingDINO is loaded. People set it on Florence-2 workflows and wonder why nothing changed. - VRAM stacking - running detection while Flux is resident can OOM. Set
keep_model_loadedto false on the loader to offload after each detection; it's slower but safe. - The Ultralytics asterisk - the YOLO-World path pulls in ultralytics, which had a December 2024 supply-chain incident (a compromised release shipped a cryptominer and reached ComfyUI users via Impact Pack). Keep it pinned from PyPI and don't install random YOLO wheels.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| model | GROUNDING_MODEL | — | |
| image | IMAGE | — | |
| prompt | STRING | person . car . dog . | Period-separated (.) = multiple objects: 'banana. orange' finds bananas AND oranges. Comma or no separator = single object: 'banana, orange' finds items labeled 'banana, orange' |
| confidence_threshold | FLOAT | 0.300–1 | Confidence threshold for detections. Typical: 0.2-0.35 (permissive), 0.35-0.5 (balanced), 0.5+ (strict) |
| single_box_modeopt | BOOLEAN | false | Return only the highest-scoring detection. Use for referring expressions (e.g., 'the red car on the left') |
| single_box_per_prompt_modeopt | BOOLEAN | false | Return highest-scoring detection for each prompt/label (e.g., 'banana. orange' returns best banana and best orange). Ignored if single_box_mode is True |
| bbox_output_formatopt | COMBO | list_only | list_only: SAM2-compatible | dict_with_data: includes labels/scores |
| seedopt | INT | 420–4294967295 | Fixed seed for reproducible results (affects mask visualization colors and model randomness) |
| text_thresholdopt | FLOAT | 0.250–1 | GroundingDINO ONLY! Text confidence threshold |
| florence2_max_tokensopt | INT | 10241–4096 | 🌸 Florence-2 ONLY! Max tokens for generation |
| florence2_num_beamsopt | INT | 31–10 | 🌸 Florence-2 ONLY! Beam search width |
| yolo_iouopt | FLOAT | 0.450–1 | 🌍 YOLO-World ONLY! IoU threshold for NMS. Typical: 0.3-0.4 (keep more overlapping boxes), 0.45 (balanced/default), 0.5-0.7 (aggressive filtering) |
| yolo_agnostic_nmsopt | BOOLEAN | false | 🌍 YOLO-World ONLY! Class-agnostic NMS. Enable when detecting overlapping objects of different classes (e.g., person holding bottle) |
| yolo_max_detopt | INT | 3001–1000 | 🌍 YOLO-World ONLY! Max detections per image. Typical: 100 (sparse), 300 (balanced/default), 500-1000 (dense/crowded scenes) |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| bboxes | BBOX | — |
| annotated_image | IMAGE | — |
| labels | STRING | — |
| masks | MASK | — |