Select VLM Detection
When your detector finds too many things, this node chooses
- detections
- selection
Detection nodes are generous. Feed a frame to Florence-2 or an open-vocabulary detector and you get back every box the model could find - ten objects, twenty, whatever's in the shot. But downstream, plenty of nodes want one thing: crop the face, run a region-caption on this specific object, resample just that one. VLMSelectDetection is the node that does the picking.
It's the smallest tool in the pack's detection utilities and honestly the one you'll wire into more workflows than you'd expect. Its entire job is "give me the detection at this index," which sounds trivial until you're chaining region tasks and realize most of them reject ambiguous multi-box input.
How it works
You connect a VLM_DETECTIONS sequence (from VLMOpenVocabularyDetection, Florence2, Moondream detect, VLMStructuredSpatialParser, or a JSON load via VLMDetectionsFromJSON) and set index. The node returns just that one detection, still in the same VLM_DETECTIONS format, so whatever produced the full list can accept the selection in its place. Index 0 is the first detection; the input enforces min: 0, so counting starts at zero like any sane API.
The one input that matters
index- zero-based position in the detection list. Set it by hand while you're debugging; in a finished workflow you'd drive it from a widget or a value node when you want the workflow to pick the Nth object deterministically.
Output is a single selection (VLM_DETECTIONS). It's one object, not a batch of one, but it is still a valid detection payload - which is the entire trick. Anything that consumes detections can consume your selection, so this node slots in anywhere upstream.
Where you'll actually use it
The most common real case comes from the pack's own Florence-2 integration. Florence-2's region tasks - region to segmentation, region to description, region to OCR - need exactly one core BOUNDING_BOX per image and will reject ambiguous multi-box input. The documented pattern is: detect everything, run VLMSelectDetection to isolate the record you care about, then convert to a single BOUNDING_BOX with the same pixel coordinates. Two nodes and you've turned "annotate this whole scene" into "annotate this one pedestrian."
It's also the natural partner for VLMCropDetections (crop that one detection) and VLMDetectionsToMasks (mask just that object instead of the full set). If you're building a targeted pipeline - track a single face, describe one product in a shelf - index-select first, then let the expensive nodes run on the one thing that matters.
Install
Part of ComfyUI VLM Nodes (gokayfem/ComfyUI_VLM_nodes). ComfyUI Manager → search "VLM Nodes", or:
cd ComfyUI/custom_nodes
git clone https://github.com/gokayfem/ComfyUI_VLM_nodes
python -m pip install -r ComfyUI/custom_nodes/ComfyUI_VLM_nodes/requirements.txt
Use ComfyUI's own Python, and don't let the repo touch torch. No model downloads here - this node does zero inference, so it works on any backend, CPU included, the moment the pack imports.
Pitfalls
The obvious one: indexes shift when the upstream detector changes its mind. A model update or a slightly different frame can reorder detections, so a hardcoded index is a debugging tool, not a contract. For anything that must survive a re-run, filter by label or score first (VLMFilterDetections) and select within a stable subset. And remember it's zero-based - the "first" object is index 0, and 1 is already the second one.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| detections | VLM_DETECTIONS | — | |
| index | INT | 0 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| selection | VLM_DETECTIONS | — |