Nodes/toobusy/2BZ Crop Each BBox (list)
ComfyUI Node

2BZ Crop Each BBox (list)

Crop Every Box the Detector Found, Not One Big Blob of All of Them

By nicekriss·Created about a year ago·Updated a day ago· 21
2BZ Crop Each BBox (list)
  • image
  • bboxes
  • crops
  • used_bboxes
  • count
◄padding_percent6.0►
◄target_megapixels4.0►
◄multiple_of32►
◄orderleft_to_right►
◄max_items0►
◄resize_methodlanczos►

What it's for

This is the front half of the automatic detail pass: detect → crop each thing → re-render it bigger → paste it back. The KB's framing of the whole loop is one corpus sentence - "All detailers are doing is zooming in on a mask, upscaling the image, and then diffusing the upscaled image to add details."

The catch is the crop step. Core's Crop By Bounding Boxes takes the union of every box on the frame, so a sheet with six people becomes one crop containing six small people - which defeats the point, since the reason you're here is that a face occupying 200 px has no latent budget to spend. 2BZ Crop Each BBox (list) cuts one image per box, each padded and resized to its own megapixel budget, and emits them as a list. Everything downstream then runs once per crop.

How it works

It reads boxes from a BOUNDING_BOX input - SAM3 Detect, RT-DETR, Create Bounding Boxes all qualify - and tolerates the shapes detectors emit (per-frame lists, a flat list, a single dict, a JSON string). It works off the frame's first boxes only.

Per box it pads by padding_percent of the box's longer edge, clamps to the image, drops anything that ends up thinner than 8 px, keeps the aspect ratio while scaling to target_megapixels, then rounds width and height to the nearest multiple_of. Rounding matters more than it looks: models want multiples of 16 or 32. Then it sorts by order, trims to max_items, and returns.

Inputs and outputs that matter

Three widgets are the ones you'll actually touch:

  • target_megapixels (default 4) - the resolution budget each crop is scaled to, aspect preserved. 4 MP is roughly a 2K square, the native budget for Qwen-Image 2.1 class models. 0 keeps the native crop size. The author's measured example: 2–3 minutes per 4 MP crop on a 3090, so six detections is a ~20 minute queue job.
  • padding_percent (default 6) - extra margin on every side. Chins and hairlines get clipped at 0.
  • max_items (default 0 = all) - keep only the first N boxes after ordering. The honest reason is that this is a per-crop sampler run, so the count is your render time. Pair it with order = largest_first on a busy sheet.

Then multiple_of (32), order (left_to_right), and resize_method (lanczos) - leave them unless you have a reason.

Outputs:

  • crops - an IMAGE list. Wire it into VAEEncode / TextEncodeQwenImage21 → KSampler → VAEDecode. Because it's a list, those nodes execute once per crop: six detections, six sampling runs, one sampler node.
  • used_bboxes - the coordinates after padding and clamping. Feed this to 2BZ Paste Crops Back, not the detector's raw boxes. The padded box is where the crop came from.
  • count - an INT for a primitive or a display node.

Install

It ships in the toobusy pack by 너무바쁜베짱이 (registry publisher neobabae). These two BBox nodes need v0.5.3 or newer.

cd ComfyUI/custom_nodes
git clone https://github.com/nicekriss/toobusy.git toobusy
# update later:
cd toobusy && git pull

Manager works too, but the README is upfront about registry lag: a Manager install can silently land on an older release where the newest nodes simply don't appear, with no error to explain it. If something you expect is missing, use Install via Git URL with https://github.com/nicekriss/toobusy, or clone. Restart ComfyUI after; hard-refresh the browser if the frontend changed.

No model downloads and no extra pip packages for this node - the pack's core dependency list is empty, and the requirements_*.txt files belong to other nodes. SAM3's checkpoint does live in models/checkpoints/, loaded through the core Load Checkpoint.

Where people get tripped up

Nothing detected isn't an error. With an empty box list the node passes the whole frame through as a single crop and sets used_bboxes to the full frame. The graph runs, you get output, it looks fine - and you just spent the whole queue on a full-image pass. Check the box count first.

The detection prompt needs the count. SAM3 Detect uses target:max grammar - person:8, face:4, or comma-separated person:6, rifle:2. Without the :N you get exactly one object per category, and people reasonably conclude detection is broken. Raise the threshold for fewer boxes, lower it for more.

SAM3 Detect is core and it needs a current ComfyUI. Community threads about it are almost all installation confusion: it's behind recent core versions, and sam3.1_multiplex_fp16.safetensors goes in models/checkpoints/ loaded via Load Checkpoint, which is not where anyone expects a detector to live.

The pairs are positional. Crops are matched back to boxes by order, so don't reorder the list in between and don't hand the paste node the detector's raw boxes. If the detection looks wrong, put Draw BBoxes → Preview Image off the detector and look before you spend twenty minutes rendering.

Categorytoobusy/Detail

Inputs (8)

NameTypeDefaultDescription
imageIMAGE—
bboxesBOUNDING_BOX—
padding_percentFLOAT6.00–100Extra margin on every side, as a percent of the box's longer edge.
target_megapixelsFLOAT4.00–16Each crop is resized (aspect kept) to about this many megapixels. 0 keeps the native crop size.
multiple_ofINT328–128Crop width and height are rounded to this multiple.
orderCOMBOleft_to_right4 options: left_to_right, top_to_bottom, largest_first, detection
max_itemsINT00–64Keep at most this many boxes after ordering. 0 = all.
resize_methodCOMBOlanczos4 options: lanczos, bicubic, area, bilinear

Outputs (3)

NameTypeDescription
cropsIMAGE—
used_bboxesBOUNDING_BOX—
countINT—