✂️ Gemini Garment Auto Crop
Strip the studio backdrop off a product shot automatically
- image
- cropped_image
- cropped_mask
- x
- y
- width
- height
Gemini Garment Auto Crop removes the empty studio backdrop around a garment and returns a tight crop plus a garment mask. It's built for one specific input - a garment centered on a fairly uniform light backdrop, the standard e-commerce product shot - and for that input, the author's claim is worth taking literally: the defaults work for the vast majority of cases. Plug it in, get a clean crop out. No API, no key, all local.
If you've ever batch-processed product photos, you know the fiddly reality underneath: dark vignette frames, a color-matching chart sitting in the corner, a light-on-light garment that the background logic wants to erase. This node was written by someone who clearly processed a lot of these, because it handles all three without you touching a knob.
How it works
The core is a flood fill. The node samples the backdrop color from the image border, then flood-fills inward from the edges - whatever the fill can't reach is the garment. Then it cleans up and crops to the garment's bounding box plus a small margin. The details are where it gets clever:
- Dark frames and vignettes -
ignore_border_objects(default on) ignores anything that touches the image edge, so a dark backdrop border or vignette doesn't blow the crop out. It auto-disables if it would erase the whole subject (garment filling the frame). - Color charts and hang tags -
min_object_size(default 0.10) discards detected objects smaller than a tenth of the biggest one, which is exactly the chart-or-tag size relative to a garment. Set it to 0 if your garment fragments into scattered logos/trim and you want every piece kept. - Light-on-light garments - the node retries at a lower tolerance when the garment is low-contrast, so a white shirt on white doesn't vanish.
- Speed - detection runs on a downscaled copy (
detection_size, default 1024 long side) even for 8000+ px images, and the crop is applied at full resolution.
The safety net is min_coverage (default 0.01): if the detected garment covers less than 1% of the image, it assumes detection failed and returns the image uncropped rather than handing you a garbage crop.
Inputs and outputs
The knobs you might actually touch: bg_tolerance (default 0.09) - raise it if bits of garment leak away on a light garment/light backdrop, lower it if backdrop texture or shadow gets kept; padding (default 0.02) - margin as a fraction of the longer side; close_gaps (default 8) - bridges texture/logo gaps so the garment reads as one region.
Outputs: cropped_image, cropped_mask (the garment silhouette as a MASK), and the crop box as x, y, width, height integers - handy when you need to apply the identical crop somewhere else, like a batch of related shots.
The honest limitation
The README admits the one thing it can't do: if a color chart sits inside a wide garment's bounding box, a rectangular crop can't remove it - the mask still excludes it, but the rectangle has to include it. That's geometry, not a bug. Similarly, it's tuned for fairly uniform light backdrops; a busy or dark studio background will fight the flood fill.
Install
ComfyUI Manager search "ComfyUI_Gemini", or:
cd ComfyUI/custom_nodes
git clone https://github.com/aarnoatchi/ComfyUI_Gemini
pip install -r ComfyUI_Gemini/requirements.txt
This is one of the two nodes in the pack that genuinely want scipy installed (the other is Separate Mask Components) - the fast connected-component and hole-filling paths use it, and without it there's a slower, cruder fallback. Restart and it's under AI/Image Analysis/Google. When a crop comes out wrong, the three fixes in order of likelihood: bump bg_tolerance up for leaky garments, drop min_object_size to keep stray pieces, and check ignore_border_objects is doing what you think on dark-backdrop shots.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | A garment photographed on a fairly uniform light backdrop. | |
| bg_toleranceopt | FLOAT | 0.0900.01–1 | How close to the backdrop colour a pixel must be to count as background. The backdrop is flood-filled inward from the edges; whatever it can't reach is the garment. Raise it if bits of garment leak away (light garment on light backdrop); lower it if backdrop texture/shadow gets kept. |
| paddingopt | FLOAT | 0.0200–0.5 | Margin kept around the garment, as a fraction of its longer side. 0.02 = ~2% breathing room. |
| border_sampleopt | FLOAT | 0.0400.005–0.25 | How thick a frame around the edge to sample for the backdrop colour. Keep small so the garment never gets sampled. |
| close_gapsopt | INT | 80–64 | Bridge texture/logo gaps in the garment so it reads as one solid region before cropping (detection-scale px). |
| ignore_border_objectsopt | BOOLEAN | true | Ignore anything that touches the image edge — removes dark backdrop borders / vignette frames so they don't blow up the crop. Auto-disabled if it would erase the whole subject (garment fills the frame). |
| min_object_sizeopt | FLOAT | 0.100–1 | Discard detected objects smaller than this fraction of the biggest one — removes the colour-matching chart, hang tags and clutter. 0 = keep every piece (use for light garments that fragment into scattered logos/trim). |
| detection_sizeopt | INT | 1024128–4096 | Longest side used for detection. The crop itself is always full resolution. |
| min_coverageopt | FLOAT | 0.0100–1 | Safety net: if the detected garment covers less than this fraction of the image, assume detection failed and return the image uncropped. |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| cropped_image | IMAGE | — |
| cropped_mask | MASK | — |
| x | INT | — |
| y | INT | — |
| width | INT | — |
| height | INT | — |