withoutbg/withoutbg-openweights-onnx
withoutBG Open Weights (ONNX)
Open-source background removal and alpha matting from RGB images. This repository hosts the OSS variant exported as a self-contained ONNX graph for ONNX Runtime.
The graph includes DepthAnythingV2 and a ConvNeXt-fused matting head — no PyTorch checkpoints are needed at inference time.
- Try it live: withoutBG on Hugging Face Spaces
- Website: withoutbg.com/open-model
- Benchmarks: withoutbg.com/open-model/results
See the results
[Open Weights results →](https://withoutbg.com/open-model/results?utm_source=github&utm_medium=withoutbg-hf-readme&utm_campaign=main-readme) · [Cloud API results →](https://withoutbg.com/pro-model/results?utm_source=github&utm_medium=withoutbg-hf-readme&utm_campaign=main-readme) · [Compare →](https://withoutbg.com/compare/withoutbg-open-model-vs-pro-model?utm_source=github&utm_medium=withoutbg-hf-readme&utm_campaign=main-readme)
Model details
Files
Always distribute the ONNX file and its sidecar JSON together:
withoutbg-open-weights.onnx— inference graph (depth → ConvNeXt matting)withoutbg-open-weights.onnx.json— sidecar metadata (I/O names, shapes, SHA256, canvas size)
Read the sidecar first. It is the authoritative source for canvas_size (448), input/output names, precision, model version, depth_variant, convnext_size, and SHA256.
Architecture
v10 pipeline:
- Depth: DepthAnythingV2
vits(dav2s) - Matting: ConvNeXtFusedMattingUNet — frozen DINOv3 ConvNeXt backbone fused into a U-Net on 4-channel RGB+depth at 448²
Consumers letterbox RGB to the fixed ONNX input tensor (canvas_size in the sidecar) and run a single inference session. Depth is computed inside the graph.
Input / output contract
Max resolution is 448px. Input letterboxing and output alpha both use canvas_size (448).The graph expects a letterboxed RGB tensor sized to canvas_size from the sidecar:
Preprocessing (required):
- Convert image to RGB.
- Read
canvas_sizefrom the sidecar (448 for this export). - Resize longest side to
canvas_size, preserve aspect ratio. - Paste at top-left on a black
canvas_size×canvas_sizecanvas. - Normalize to float32
[0, 1], transpose HWC → CHW, add batch dim.
Postprocessing (required):
- Crop alpha to the resized image region (top-left, before padding).
- Resize alpha back to the original image dimensions.
- Attach as PNG alpha channel for cutout output.
Download
from huggingface_hub import hf_hub_download
model_path = hf_hub_download(
repo_id="withoutbg/withoutbg-openweights-onnx",
filename="withoutbg-open-weights.onnx",
)
sidecar_path = hf_hub_download(
repo_id="withoutbg/withoutbg-openweights-onnx",
filename="withoutbg-open-weights.onnx.json",
)Or with the CLI:
hf download withoutbg/withoutbg-openweights-onnx \
withoutbg-open-weights.onnx \
withoutbg-open-weights.onnx.jsonUsage
from pathlib import Path
import json
import numpy as np
import onnxruntime as ort
from PIL import Image
model_path = Path("withoutbg-open-weights.onnx")
sidecar = json.loads(model_path.with_suffix(model_path.suffix + ".json").read_text())
canvas = sidecar.get("canvas_size", 448)
input_name = sidecar.get("input_name", "rgb")
session = ort.InferenceSession(str(model_path), providers=["CPUExecutionProvider"])
image = Image.open("input.jpg").convert("RGB")
orig_w, orig_h = image.size
scale = canvas / max(orig_w, orig_h)
new_w = max(1, round(orig_w * scale))
new_h = max(1, round(orig_h * scale))
resized = image.resize((new_w, new_h), Image.Resampling.BILINEAR)
padded = Image.new("RGB", (canvas, canvas), (0, 0, 0))
padded.paste(resized, (0, 0))
rgb = np.asarray(padded, dtype=np.float32) / 255.0
rgb = np.transpose(rgb, (2, 0, 1))[None, ...]
alpha_canvas = session.run(None, {input_name: rgb})[0][0, 0]
alpha_crop = alpha_canvas[:new_h, :new_w]
alpha_u8 = np.clip(alpha_crop * 255.0, 0, 255).astype(np.uint8)
alpha = Image.fromarray(alpha_u8, "L").resize((orig_w, orig_h), Image.Resampling.BILINEAR)
out = image.copy()
out.putalpha(alpha)
out.save("output.png")Runtime dependencies
python >=3.11
numpy
pillow
onnxruntimeFor Hugging Face downloads, also install huggingface_hub.
More than weights
This repo hosts the ONNX weights. Same open-weights technology powers ready-made surfaces:
License
Apache-2.0 — see withoutbg.com/open-model/license.
Built with DINOv3.
Third-party terms
This distribution includes upstream components under their respective licenses. See THIRD_PARTY_NOTICES.md.
DINOv3
License: DINOv3 License
Depth Anything V2
License: Apache-2.0 — Depth Anything V2
