Atlas VLM Scale Cues π
Ask a Vision Model How Tall the World Is
- image
- scale_references
- summary
A camera solve tells you where the camera was, but a single photo has no idea how big the scene is. A 1.7 m camera height and a 17 m one produce identical-looking images - that's the metric-scale ambiguity that plagues every single-image 3D pipeline. AtlasVLMScaleCues is Atlas Camera's way of breaking it: it sends your photo to a vision-language model and asks it to spot objects with known real-world sizes - a person, a door, a car - and return their pixel bounding boxes. Those become scale references that let the solver assign real meters.
It's the VLM-as-a-node pattern the ComfyUI ecosystem has settled on (the same shape as a prompt enhancer or captioner: a language model dropped into the graph as a tool, running before the heavy stages). What's unusual here is the job being done - the VLM isn't describing the image for a prompt, it's doing measurement input, and the pack is careful to treat its output as candidates, never as fact.
How it works
The node saves your image, sends it to a vision-language model, and asks it to return pixel bounding boxes for any known-size objects it recognizes. The model's guesses get matched against a built-in reference registry - an average person at 1.75 m, a typical door at 2.10 m, cars, and yes, genuinely fun entries like railway gauge measured to the millimetre, complete with a warning about measuring across the railheads rather than rail centre. Each cue carries a confidence and a suggested reference ID, and the node emits them as scale_references JSON plus a human-readable summary.
The critical design decision: nothing is applied automatically. The output feeds AtlasApplyScaleReferences, and that node only rescales the camera's metric height when you flip its confirm toggle on. LLM cues are never auto-promoted - the pack's rule is the artist confirms, because a VLM that misreads a doorway as a person is a 25% scale error you'd otherwise ship.
The provider is the other thing to get right. provider defaults to ollama, and ollama/lmstudio/llamacpp all mean a local server you're already running - this node is a client, not a model loader. openai means any OpenAI-compatible cloud endpoint, set via base_url plus an API key. If no local server is up, the node fails soft and returns an empty list rather than crashing your graph.
The inputs that matter
image- your photo. The only required input.provider-ollama(default),lmstudio,llamacpp, oropenai. Local if you have a model; cloud if you don't.model/base_url- blank means the provider's default; setbase_urlonly if you're pointing at a non-default endpoint.min_confidence(0β1, default 0) - drop cues below this. If a busy scene returns garbage, raise it to ~0.6 and re-run.api_key- cloud only. The tooltip has the single most important warning in this node: it's saved into the workflow file. Prefer theOPENAI_API_KEYenvironment variable if the workflow might be shared.
Install & gotchas
The pack is a plain custom-nodes clone, and this node needs no extra pip packages - the VLM runs elsewhere, and the client is built into the pack:
cd ComfyUI/custom_nodes
git clone https://github.com/mikejamesvfx/atlas-camera.git
Restart ComfyUI and you're done - no [neural] tier, no GPU requirement, nothing to download.
Three things will bite you. First, a local provider with no server running just silently gives you an empty result - check that Ollama/LM Studio is actually up before debugging the node. Second, remember the model must be capable of returning pixel bounding boxes; a pure-captioning VLM isn't what this wants. Third, the security habit from the LLM-in-graph playbook applies: this node talks to a network endpoint by design, so know what it's calling. A local model keeps the whole thing offline, which is one more reason the local path is the right default here.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | β | |
| provideropt | COMBO | ollama | ollama/lmstudio/llamacpp are local; 'openai' is any OpenAI-compatible cloud endpoint (needs api_key). |
| modelopt | STRING | β | |
| base_urlopt | STRING | Blank = provider default URL | |
| min_confidenceopt | FLOAT | 0.000β1 | β |
| api_keyopt | STRING | API key for the 'openai' cloud provider (ignored by local providers). SAVED INTO THE WORKFLOW FILE β prefer the OPENAI_API_KEY environment variable for shared workflows. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| scale_references | STRING | β |
| summary | STRING | β |