| --- |
| license: apache-2.0 |
| library_name: onnxruntime |
| tags: |
| - background-removal |
| - image-segmentation |
| - alpha-matting |
| - onnx |
| - computer-vision |
| - remove-background |
| pipeline_tag: image-segmentation |
| --- |
| |
| # 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 the full WBGNet pipeline — upstream encoders, matting head, and |
| OSS refiner — so no PyTorch checkpoints are needed at inference time. |
|
|
| - **Try it live:** [withoutBG on Hugging Face Spaces](https://huggingface.co/spaces/withoutbg/withoutbg) |
| - **Website:** [withoutbg.com/open-weights-model](https://withoutbg.com/open-weights-model) |
| - **Benchmarks:** [withoutbg.com/open-weights-model/results](https://withoutbg.com/open-weights-model/results) |
|
|
| ## Model details |
|
|
| | Field | Value | |
| |-------|-------| |
| | Variant | `oss` | |
| | Version | `4.1.0` | |
| | Format | ONNX (opset 18) | |
| | Precision | fp32 | |
| | Max resolution | 768 | |
| | ONNX input tensor | 1024 × 1024 (fixed letterbox) | |
| | ONNX output tensor | 768 × 768 | |
| | Transformer opt | disabled | |
| | ORT offline opt | extended | |
| | Size | ~495 MB | |
| | SHA256 | `7873ec427ac6928bc91a3b6e1ddd32715a02d4b85836e78f0afacacee533b82f` | |
|
|
| ## Files |
|
|
| Always distribute the ONNX file and its sidecar JSON together: |
|
|
| - `withoutbg-open-weights.onnx` — inference graph (WBGNet pipeline with OSS upstreams and refiner) |
| - `withoutbg-open-weights.onnx.json` — sidecar metadata (I/O names, shapes, SHA256, canvas sizes) |
|
|
| Read the sidecar first. It is the authoritative source for `canvas_size` (ONNX |
| input letterbox size), `output_canvas_size` (768 — the fixed alpha tensor size), |
| `refiner_canvas_size` (768 — the effective max resolution), input/output names, |
| precision, model version, and SHA256. |
|
|
| ## Architecture |
|
|
| The OSS variant uses smaller open-source-friendly upstream models: |
|
|
| - **Depth:** DepthAnythingV2 `vits` |
| - **Foreground segmentation:** DINOv3 `vits16` |
| - **Semantic:** ISNet |
| - **Matting:** shared with the API variant |
| - **Refiner:** OSS refiner baked into the graph at **768px max resolution** |
|
|
| The refiner runs inside the ONNX graph. **Maximum output resolution is 768px** — |
| not 1024. Consumers letterbox to the fixed ONNX input tensor (`canvas_size` in the |
| sidecar) and run a single inference session. |
|
|
| ## Input / output contract |
|
|
| > **Max resolution is 768px.** Input letterboxing must match `canvas_size` (1024); |
| > the graph returns alpha at `output_canvas_size` (768). Detail refinement is |
| > capped at `refiner_canvas_size` (768). |
| |
| The graph expects a **letterboxed** RGB tensor sized to `canvas_size` from the sidecar: |
|
|
| | | Name | Shape | Dtype | Range | |
| |---|------|-------|-------|-------| |
| | Input | `rgb` | `[1, 3, 1024, 1024]` | float32 | `[0, 1]`, NCHW | |
| | Output | `alpha` | `[1, 1, 768, 768]` | float32 | `[0, 1]` | |
|
|
| Preprocessing (required): |
|
|
| 1. Convert image to RGB. |
| 2. Read `canvas_size` from the sidecar (1024 for this export). |
| 3. Resize longest side to `canvas_size`, preserve aspect ratio. |
| 4. Paste at top-left on a black `canvas_size` × `canvas_size` canvas. |
| 5. Normalize to float32 `[0, 1]`, transpose HWC → CHW, add batch dim. |
|
|
| Effective refinement is limited to **768px** (`refiner_canvas_size` in the sidecar). |
|
|
| Postprocessing (required): |
|
|
| 1. Scale the resized image dimensions from `canvas_size` to `output_canvas_size`. |
| 2. Crop alpha to that region on the output tensor (top-left, before padding). |
| 3. Resize alpha back to the original image dimensions. |
| 4. Attach as PNG alpha channel for cutout output. |
|
|
| ## Download |
|
|
| ```python |
| 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: |
|
|
| ```bash |
| hf download withoutbg/withoutbg-openweights-onnx \ |
| withoutbg-open-weights.onnx \ |
| withoutbg-open-weights.onnx.json |
| ``` |
|
|
| ## Usage |
|
|
| ```python |
| 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", 1024) |
| output_canvas = sidecar.get("output_canvas_size", sidecar["output_shape"][2]) |
| 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] |
| crop_h = max(1, round(new_h * output_canvas / canvas)) |
| crop_w = max(1, round(new_w * output_canvas / canvas)) |
| alpha_crop = alpha_canvas[:crop_h, :crop_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 |
|
|
| ```text |
| python >=3.11 |
| numpy |
| pillow |
| onnxruntime |
| ``` |
|
|
| For Hugging Face downloads, also install `huggingface_hub`. |
|
|
| ## License |
|
|
| Apache-2.0 — see [withoutbg.com/open-weights-model/license](https://withoutbg.com/open-weights-model/license). |
|
|
| ## Third-party terms |
|
|
| This model uses DINOv3 as an upstream component. See the |
| [DINOv3 license](https://ai.meta.com/resources/models-and-libraries/dinov3-license/). |
|
|
| ## Links |
|
|
| - [GitHub: withoutbg-inference](https://github.com/withoutbg/withoutbg-inference) |
| - [Python package (PyPI)](https://pypi.org/project/withoutbg/) |
| - [Docker Hub: app (CPU)](https://hub.docker.com/r/withoutbg/withoutbg-openweights-v3-app-cpu) |
| - [Docker Hub: service (CPU)](https://hub.docker.com/r/withoutbg/withoutbg-openweights-v3-service-cpu) |
| - [GIMP plugin](https://github.com/withoutbg/withoutbg-gimp) |
| - [Mac app](https://withoutbg.com/open-weights-model/mac-app) |
|
|