Nodes/Storyboard Layout & BBox Engine/BBox from Reference Image
ComfyUI Node

BBox from Reference Image

Borrow a composition instead of hand-drawing boxes

By SurrealByDesign·Created 3 months ago·Updated 3 months ago· 1
BBox from Reference Image
  • image
  • bbox_json
max_subjects4
threshold_factor1.0
close_size5

The rest of this pack takes a shot definition and makes boxes. This node flips the direction: give it an image and it finds the boxes. Drop in a reference frame - a film still, a storyboard sketch, a composition you like - and it extracts the prominent regions as normalized bounding boxes in the exact same bbox_json format the BBox Generator produces, so it plugs into the Preview Renderer and Export Tools interchangeably. The pitch: you can bootstrap a whole layout plan from a picture you already like instead of reasoning out coordinates by hand.

How it works (and how it's different)

Here's the headline: there is no neural network in this node. It's classical computer vision, using frequency-tuned saliency (the Achanta et al. 2009 method) to highlight whole contrasting regions, an Otsu adaptive threshold to decide what counts as "salient", morphological closing to merge fragmented detections, and connected components to turn the mask into boxes. All of it in pure numpy, all of it deterministic. The author is upfront that this is a deliberate baseline, not a trained detector - read the pack's docs/COMPUTATION_STRATEGY.md if you want the reasoning, but the short version is "dependency-free and no black box, at the cost of detection quality."

The inputs, and what you'll actually fiddle with:

  • image (required) - any IMAGE tensor. First image in the batch is used.
  • max_subjects (default 4, range 1–16) - caps how many boxes you get. Handy when the image is busy and you only want the top regions.
  • threshold_factor (default 1.0, range 0.2–5.0) - scales how aggressive the saliency cutoff is. Lower it to keep more (fainter regions count), raise it to keep only strong, high-contrast regions.
  • close_size (default 5, range 1–15, odd values) - the size of the morphological closing kernel. Bigger merges nearby fragments into one box; smaller keeps detections separate.

The output bbox_json is a {subject: {x, y, width, height}} map with generated names subject_1, subject_2, and so on, numbered in descending region area - the schema doesn't care what they're called, so downstream nodes won't complain. If nothing passes the threshold, it falls back to a single centered box rather than erroring, so the output always satisfies the bbox schema.

Where you'll love it, and where it'll let you down

It genuinely shines on clean, high-contrast inputs - a few distinct shapes on a plain background, a storyboard sketch with bold outlines. That's the intended use case.

Real talk about the limits, because the author lists them plainly and so should I:

  • Busy or low-contrast photos → coarser, noisier boxes. This is inherent to mean/Otsu-based saliency. A cluttered real-world photo will not give you clean subject boxes; it'll give you blobs.
  • It assumes the subject is a minority of the frame. A single subject filling most of the image gets mis-segmented - the saliency method needs background to contrast against. Fine for establishing/wide framings, useless for close-ups.
  • Don't expect instance-level detection. Two people standing together will likely become one box, not two.

If the output is too noisy, threshold_factor and close_size are your knobs, but there's a hard ceiling on what this approach can do. Treat it as a starting point for the pipeline, not a finished layout - and if you need real object detection, this node isn't that, by design.

Install

It's part of the same pack, so the install is the shared one:

cd ComfyUI/custom_nodes
git clone https://github.com/SurrealByDesign/ComfyUI-Storyboard-Layout

Restart, and it appears alongside the other five nodes under storyboard/layout. Notably, this one needs no new dependencies - no OpenCV, no models to download. It only requires numpy + Pillow, which ComfyUI already provides. That zero-dependency stance is the whole reason the classical approach was chosen in the first place. It's the optional sixth node, and it's worth having around for the cases where it works - just know what you're getting before you trust its boxes.

Categorystoryboard/layout

Inputs (4)

NameTypeDefaultDescription
imageIMAGE
max_subjectsoptINT41–16
threshold_factoroptFLOAT1.00.2–5
close_sizeoptINT51–15

Outputs (1)

NameTypeDescription
bbox_jsonSTRING