bulk-bg-remove 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bulk_bg_remove-0.1.0/.agents/plugins/marketplace.json +21 -0
- bulk_bg_remove-0.1.0/.claude-plugin/marketplace.json +17 -0
- bulk_bg_remove-0.1.0/.claude-plugin/plugin.json +13 -0
- bulk_bg_remove-0.1.0/.codex-plugin/plugin.json +29 -0
- bulk_bg_remove-0.1.0/.github/workflows/ci.yml +32 -0
- bulk_bg_remove-0.1.0/.gitignore +31 -0
- bulk_bg_remove-0.1.0/.python-version +1 -0
- bulk_bg_remove-0.1.0/AGENTS.md +105 -0
- bulk_bg_remove-0.1.0/BENCHMARK.md +202 -0
- bulk_bg_remove-0.1.0/CLAUDE.md +1 -0
- bulk_bg_remove-0.1.0/LICENSE +21 -0
- bulk_bg_remove-0.1.0/PKG-INFO +180 -0
- bulk_bg_remove-0.1.0/README.md +144 -0
- bulk_bg_remove-0.1.0/agents/bg-reviewer.md +14 -0
- bulk_bg_remove-0.1.0/assets/demo.webp +0 -0
- bulk_bg_remove-0.1.0/assets/logo-dark.svg +1 -0
- bulk_bg_remove-0.1.0/assets/logo-light.svg +1 -0
- bulk_bg_remove-0.1.0/assets/showcase.webp +0 -0
- bulk_bg_remove-0.1.0/benchmark/images.csv +31 -0
- bulk_bg_remove-0.1.0/benchmark/scores.csv +81 -0
- bulk_bg_remove-0.1.0/pyproject.toml +82 -0
- bulk_bg_remove-0.1.0/scripts/bench.py +206 -0
- bulk_bg_remove-0.1.0/scripts/bench_grids.py +154 -0
- bulk_bg_remove-0.1.0/scripts/ci.sh +77 -0
- bulk_bg_remove-0.1.0/skills/bulk-bg-remove/SKILL.md +281 -0
- bulk_bg_remove-0.1.0/skills/bulk-bg-remove/agents/openai.yaml +6 -0
- bulk_bg_remove-0.1.0/skills/bulk-bg-remove/references/json-events.md +70 -0
- bulk_bg_remove-0.1.0/skills/bulk-bg-remove/references/models.md +111 -0
- bulk_bg_remove-0.1.0/skills/bulk-bg-remove/references/reviewer.md +86 -0
- bulk_bg_remove-0.1.0/skills/bulk-bg-remove/references/troubleshooting.md +53 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/__init__.py +3 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/bulk/__init__.py +1 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/bulk/events.py +28 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/bulk/models.py +137 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/bulk/plan.py +262 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/bulk/runner.py +438 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/bulk/sample.py +165 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/bulk/scan.py +219 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/bulk/session.py +407 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/bulk/verify.py +89 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/cli.py +298 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/console.py +272 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/core/__init__.py +1 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/core/compositing.py +24 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/core/finish.py +171 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/core/io.py +122 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/core/matting.py +157 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/core/pipeline.py +94 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/doctor.py +107 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/domain.py +15 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/engine/__init__.py +1 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/engine/model.py +96 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/formats.py +74 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/paths.py +77 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/ui/__init__.py +1 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/ui/launch.py +46 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/ui/server.py +401 -0
- bulk_bg_remove-0.1.0/src/bulk_bg_remove/ui/static/index.html +452 -0
- bulk_bg_remove-0.1.0/tests/conftest.py +27 -0
- bulk_bg_remove-0.1.0/tests/fakes.py +59 -0
- bulk_bg_remove-0.1.0/tests/test_auto_model.py +134 -0
- bulk_bg_remove-0.1.0/tests/test_compositing.py +47 -0
- bulk_bg_remove-0.1.0/tests/test_finish.py +139 -0
- bulk_bg_remove-0.1.0/tests/test_finish_verify.py +71 -0
- bulk_bg_remove-0.1.0/tests/test_formats.py +61 -0
- bulk_bg_remove-0.1.0/tests/test_io.py +81 -0
- bulk_bg_remove-0.1.0/tests/test_matting.py +117 -0
- bulk_bg_remove-0.1.0/tests/test_models.py +55 -0
- bulk_bg_remove-0.1.0/tests/test_paths.py +57 -0
- bulk_bg_remove-0.1.0/tests/test_plan.py +125 -0
- bulk_bg_remove-0.1.0/tests/test_real_model.py +59 -0
- bulk_bg_remove-0.1.0/tests/test_review.py +136 -0
- bulk_bg_remove-0.1.0/tests/test_runner.py +201 -0
- bulk_bg_remove-0.1.0/tests/test_scan.py +33 -0
- bulk_bg_remove-0.1.0/tests/test_session_and_cli.py +217 -0
- bulk_bg_remove-0.1.0/tests/test_shop.py +115 -0
- bulk_bg_remove-0.1.0/tests/test_ui.py +177 -0
- bulk_bg_remove-0.1.0/uv.lock +1442 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bulk-bg-remove",
|
|
3
|
+
"interface": {
|
|
4
|
+
"displayName": "Bulk BG Remove"
|
|
5
|
+
},
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "bulk-bg-remove",
|
|
9
|
+
"source": {
|
|
10
|
+
"source": "url",
|
|
11
|
+
"url": "https://github.com/Btike/bulk-bg-remove.git",
|
|
12
|
+
"ref": "main"
|
|
13
|
+
},
|
|
14
|
+
"policy": {
|
|
15
|
+
"installation": "AVAILABLE",
|
|
16
|
+
"authentication": "ON_INSTALL"
|
|
17
|
+
},
|
|
18
|
+
"category": "Productivity"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
|
3
|
+
"name": "bulk-bg-remove",
|
|
4
|
+
"description": "Remove image backgrounds locally and in bulk. No uploads, no API keys.",
|
|
5
|
+
"owner": {
|
|
6
|
+
"name": "Btike",
|
|
7
|
+
"url": "https://github.com/Btike"
|
|
8
|
+
},
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "bulk-bg-remove",
|
|
12
|
+
"description": "Cut out every photo in a folder with BiRefNet, on your own machine. Lossless transparent PNG/WebP, originals untouched.",
|
|
13
|
+
"source": "./",
|
|
14
|
+
"category": "productivity"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bulk-bg-remove",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Remove image backgrounds locally and in bulk: one photo or whole folders, with BiRefNet. No uploads, no API keys, originals untouched.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Btike",
|
|
7
|
+
"url": "https://github.com/Btike"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/Btike/bulk-bg-remove",
|
|
10
|
+
"repository": "https://github.com/Btike/bulk-bg-remove",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": ["background-removal", "remove-background", "transparent-png", "birefnet", "bulk", "images"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bulk-bg-remove",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Remove image backgrounds locally and in bulk: one photo or whole folders, with BiRefNet. No uploads, no API keys, originals untouched.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Btike",
|
|
7
|
+
"url": "https://github.com/Btike"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/Btike/bulk-bg-remove",
|
|
10
|
+
"repository": "https://github.com/Btike/bulk-bg-remove",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": ["background-removal", "remove-background", "transparent-png", "birefnet", "bulk", "images"],
|
|
13
|
+
"skills": "./skills/",
|
|
14
|
+
"interface": {
|
|
15
|
+
"displayName": "Bulk BG Remove",
|
|
16
|
+
"shortDescription": "Remove image backgrounds locally, in bulk",
|
|
17
|
+
"longDescription": "Cut out the subject of one photo or whole folders on your own machine with BiRefNet. Lossless transparent PNG or WebP in a new <name>-no-bg folder; originals are never touched.",
|
|
18
|
+
"developerName": "Btike",
|
|
19
|
+
"category": "Productivity",
|
|
20
|
+
"capabilities": ["Instructions"],
|
|
21
|
+
"websiteURL": "https://github.com/Btike/bulk-bg-remove",
|
|
22
|
+
"defaultPrompt": [
|
|
23
|
+
"Remove the background from every photo in this folder.",
|
|
24
|
+
"Make a transparent PNG of this product photo.",
|
|
25
|
+
"Cut out the people in these HEIC photos."
|
|
26
|
+
],
|
|
27
|
+
"brandColor": "#0d1117"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Hosted CI for when the repo is public (public repos get free Actions minutes).
|
|
2
|
+
# While the repo is private every job is skipped, so it uses no minutes:
|
|
3
|
+
# run scripts/ci.sh locally instead.
|
|
4
|
+
name: ci
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
pull_request:
|
|
10
|
+
workflow_dispatch: # run it by hand from the Actions tab
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
if: ${{ !github.event.repository.private }}
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
19
|
+
python: ["3.11", "3.12", "3.13"]
|
|
20
|
+
runs-on: ${{ matrix.os }}
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: astral-sh/setup-uv@v6
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python }}
|
|
26
|
+
- run: uv lock --check
|
|
27
|
+
- run: uv run --locked ruff check .
|
|
28
|
+
- run: uv run --locked ruff format --check .
|
|
29
|
+
- run: uv run --locked mypy
|
|
30
|
+
- run: uv run --locked pytest -q
|
|
31
|
+
env:
|
|
32
|
+
BULK_BG_REMOVE_REAL_MODEL: "1" # also run the real-model smoke test
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
*.egg-info/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.mypy_cache/
|
|
11
|
+
|
|
12
|
+
# Env / secrets — never commit
|
|
13
|
+
.env
|
|
14
|
+
.env.local
|
|
15
|
+
*.key
|
|
16
|
+
|
|
17
|
+
# Local runtime output and test images
|
|
18
|
+
storage/
|
|
19
|
+
*-no-bg/
|
|
20
|
+
.playwright-mcp/
|
|
21
|
+
|
|
22
|
+
# Downloaded model weights
|
|
23
|
+
*.onnx
|
|
24
|
+
.u2net/
|
|
25
|
+
|
|
26
|
+
# OS
|
|
27
|
+
.DS_Store
|
|
28
|
+
Thumbs.db
|
|
29
|
+
|
|
30
|
+
# Local CI environments and builds
|
|
31
|
+
.ci/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# AGENTS.md — bulk-bg-remove
|
|
2
|
+
|
|
3
|
+
Remove image backgrounds in bulk, 100% locally, without touching a single subject
|
|
4
|
+
pixel. One engine, two entry points: a CLI/agent mode and a local drag-and-drop UI.
|
|
5
|
+
|
|
6
|
+
> Status: v0.1 under construction. Sections marked _(planned)_ do not exist yet.
|
|
7
|
+
|
|
8
|
+
## Stack
|
|
9
|
+
- **Python 3.11–3.13**, managed by **uv** (`.python-version` pins 3.12 for development)
|
|
10
|
+
- **rembg** (ONNX Runtime) with **BiRefNet** (MIT) — default model `birefnet-general-lite`
|
|
11
|
+
- **Pillow + numpy** — imaging; **pillow-heif** for HEIC/HEIF; **pymatting + scipy** — edge matting
|
|
12
|
+
- **FastAPI + Uvicorn** — local UI server
|
|
13
|
+
- **rich** — terminal logs · **psutil** — capacity probes
|
|
14
|
+
- **pytest · ruff · mypy (strict)** — quality gates
|
|
15
|
+
|
|
16
|
+
## Commands
|
|
17
|
+
- Install / sync: `uv sync`
|
|
18
|
+
- Tests: `uv run pytest`
|
|
19
|
+
- Lint: `uv run ruff check . && uv run ruff format --check .`
|
|
20
|
+
- Typecheck: `uv run mypy`
|
|
21
|
+
- Run: `uv run bulk-bg-remove PATH [--profile KIND] [--yes] [--json] [--clean-edges|--fast-edges]`
|
|
22
|
+
(`--model` defaults to `auto`; `--sample-sheet` with `--dry-run` writes a contact sheet)
|
|
23
|
+
- Check a machine: `uv run bulk-bg-remove doctor [--json]`
|
|
24
|
+
- **CI runs locally**: `scripts/ci.sh` (lock, ruff, mypy, tests on Python 3.11–3.13, wheel
|
|
25
|
+
build, plugin manifests); `--quick` for lint, types and tests only; `--linux` adds the suite
|
|
26
|
+
on Linux x86_64 in Docker with the real-model smoke test (~10 min, emulated: run it before a
|
|
27
|
+
merge or release). Hosted CI (`.github/workflows/ci.yml`, Linux/macOS/Windows) is skipped
|
|
28
|
+
while the repo is private. Run the full script before every commit.
|
|
29
|
+
- Linux arm64 VMs on Apple M4/M5 (Docker, UTM, Lima) advertise SVE the chip cannot run:
|
|
30
|
+
numba and ONNX Runtime die with SIGILL there. Test Linux as x86_64; the runner reports a
|
|
31
|
+
SIGILL crash in plain words (`crash_reason` in `bulk/runner.py`).
|
|
32
|
+
|
|
33
|
+
## Structure
|
|
34
|
+
- `src/bulk_bg_remove/core/` — pure image logic: `io.py`, `matting.py`, `compositing.py`,
|
|
35
|
+
`finish.py` (opt-in shop finishing), `pipeline.py`.
|
|
36
|
+
No CLI/UI/runner imports.
|
|
37
|
+
- `src/bulk_bg_remove/engine/model.py` — rembg session wrapper (load once per worker, reuse).
|
|
38
|
+
- `src/bulk_bg_remove/domain.py` — shared domain types.
|
|
39
|
+
- `src/bulk_bg_remove/bulk/` — the four phases: scan → plan → run → verify, plus `session.py`
|
|
40
|
+
(shared by CLI and UI), `events.py` (the JSON event contract), `models.py` (`--model auto`:
|
|
41
|
+
per-profile scores from the blind-judged bench) and `sample.py` (contact sheet for agents)
|
|
42
|
+
- `src/bulk_bg_remove/ui/` — local server + single-file page
|
|
43
|
+
- `skills/bulk-bg-remove/` — the agent skill (`SKILL.md` + `references/`); plugin manifests in
|
|
44
|
+
`.claude-plugin/`, `.codex-plugin/` and `.agents/plugins/`. The `--json` event contract is
|
|
45
|
+
documented in `references/json-events.md`: update it with any event change.
|
|
46
|
+
- `tests/` — unit tests for pure logic, integration tests with a fake model, and one
|
|
47
|
+
real-model smoke test (`test_real_model.py`, `silueta`, 43 MB download) that runs only with
|
|
48
|
+
`BULK_BG_REMOVE_REAL_MODEL=1` — set by `scripts/ci.sh --linux` and in hosted CI on
|
|
49
|
+
Linux, macOS and Windows.
|
|
50
|
+
|
|
51
|
+
## Quality contract (do not break)
|
|
52
|
+
- NEVER resample or re-encode the subject's RGB. Only the alpha mask is resized
|
|
53
|
+
(Lanczos); compositing copies RGB verbatim — see `core/compositing.py`. The one
|
|
54
|
+
opt-in exception is `--clean-edges`, which recolours semi-transparent edge pixels only.
|
|
55
|
+
- Output keeps the exact input dimensions. PNG is always lossless; WebP uses
|
|
56
|
+
`lossless=True, exact=True`.
|
|
57
|
+
- The other opt-in exception is finishing (`core/finish.py`: `--background`, `--square`,
|
|
58
|
+
`--pad`, `--size`, `--shop`): it blends edge pixels onto a colour, crops, resamples or
|
|
59
|
+
writes JPEG only when asked. Review sheets keep judging the transparent cut-out (a
|
|
60
|
+
preview saved before finishing), never the finished image.
|
|
61
|
+
- Originals are never modified, moved or deleted. Output always goes to a new
|
|
62
|
+
`<name>-no-bg/` folder.
|
|
63
|
+
|
|
64
|
+
## Conventions
|
|
65
|
+
- Strict typing (mypy strict, no `Any` escape hatches), frozen dataclasses, named exports.
|
|
66
|
+
- English only: code, comments, docs, UI copy, terminal output.
|
|
67
|
+
- Minimal dependencies — justify every new one.
|
|
68
|
+
- New logic ships with tests: unit for pure logic, integration for runner/CLI/UI.
|
|
69
|
+
- Conventional Commits on feature branches; never commit to `main` directly.
|
|
70
|
+
|
|
71
|
+
## Gotchas
|
|
72
|
+
- `bulk/models.py` scores come from `scripts/bench.py` plus blind vision judging (see
|
|
73
|
+
`references/models.md`). Re-run both before changing a score or adding a model; every
|
|
74
|
+
ranked model needs a measured entry in `MODEL_PEAK_GB`.
|
|
75
|
+
- rembg downloads model weights on first use to `~/.u2net/` (needs network once, ~224 MB).
|
|
76
|
+
- RAM is the real limit. Measured peak per worker without matting (CPU, tuned session):
|
|
77
|
+
`birefnet-general-lite` 9.4 GB · other BiRefNet variants 11.6 · `isnet-general-use` 2.4 ·
|
|
78
|
+
`u2net` 1.8 · `silueta` 0.7 (all 11 in `bulk/plan.py`). Nearly constant per model: each
|
|
79
|
+
model infers at a fixed size whatever the photo size.
|
|
80
|
+
- Edge matting adds ~0.35 GB per matted MP plus ~2.3 GB per million uncertain-band pixels
|
|
81
|
+
(a 4 MP wire chair: 4.9 GB; a product shot: 1.8 GB). `core/matting.py` shrinks the matting
|
|
82
|
+
resolution to fit a budget the worker sets from free RAM (0.6–3 GB), re-measuring after each
|
|
83
|
+
step (the eroded band shrinks slower than the area). Scaling the matte back to full
|
|
84
|
+
resolution costs ~0.03 GB/MP more (~0.065 with `--clean-edges`), outside that budget. The
|
|
85
|
+
start floor counts 0.6 GB of matting (lite: ~12 GB for 12 MP photos); parallel sizing, 3 GB.
|
|
86
|
+
- A long-lived worker's RSS creeps to ~3x one image's peak (heap fragmentation from images
|
|
87
|
+
of different sizes; `gc` and malloc pressure relief do not help). Workers restart when RSS
|
|
88
|
+
ends an image more than 1 GB above the model's peak (`recycle_above_gb`). Measured on the
|
|
89
|
+
edge-heavy bench: lite 15.7 → 12.3 GB, silueta 9.1 → 3.9 GB. They only restart while free RAM
|
|
90
|
+
is below reserve + full matting + margin (~5.5 GB): a reload costs ~2 s per image.
|
|
91
|
+
- Worker stdout goes to devnull: pymatting prints harmless "incomplete Cholesky" warnings there.
|
|
92
|
+
- On CPU a second worker adds only ~25% throughput (ONNX already uses every core);
|
|
93
|
+
more workers are slower. `OMP_NUM_THREADS` sets intra-op threads per worker.
|
|
94
|
+
- `rembg.remove(..., only_mask=True)` silently ignores `alpha_matting`. Edge matting is
|
|
95
|
+
done by `core/matting.py` instead — never pass matting flags to rembg.
|
|
96
|
+
- Matting runs at ≤ 4 MP; sure foreground/background come from the full-resolution
|
|
97
|
+
mask. Keep the trimap erosion separable (row pass + column pass): a square
|
|
98
|
+
structure is ~40× slower on large photos.
|
|
99
|
+
- CoreML is listed by onnxruntime on macOS but BiRefNet does not compile to it; treat
|
|
100
|
+
it as CPU.
|
|
101
|
+
- 16-bit greyscale must be scaled, not converted: Pillow's `I;16 -> RGB` clips to white.
|
|
102
|
+
- Bench: results in `BENCHMARK.md` + `benchmark/` (scores, image credits; photos stay out of
|
|
103
|
+
git). `scripts/bench.py INPUT RESULTS [--model M ...]` writes
|
|
104
|
+
before/after sheets, time per image and peak RAM; `scripts/bench_grids.py` makes blind
|
|
105
|
+
grids (models as letters) and close-ups for judging.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Benchmark
|
|
2
|
+
|
|
3
|
+
How well each background-removal model works, how fast it is and how much RAM
|
|
4
|
+
it needs, measured on 80 hard images and judged blind. These numbers drive
|
|
5
|
+
`--model auto` and the skill's model guide.
|
|
6
|
+
|
|
7
|
+
**In short**
|
|
8
|
+
|
|
9
|
+
- The default, `birefnet-general-lite`, scores **7.9/10** overall, against 8.0 for
|
|
10
|
+
`birefnet-general`, at **3.2 s per product photo** against 5.6 s.
|
|
11
|
+
- On 35 real product catalogue photos it scores **8.6/10**, the best of the 11
|
|
12
|
+
models, and never 3 or less.
|
|
13
|
+
- With **3.4 GB of free RAM**, `silueta` still scores 8.1 on clean product shots.
|
|
14
|
+
On hair, fur and plants the light models drop to ~5 against 7.6, so the skill
|
|
15
|
+
asks before using one.
|
|
16
|
+
- The cut-out reviewer flags **8 of 9** cut-outs the judges scored 5 or less.
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
- **Machine:** Apple M5 (4 performance cores), 34 GB RAM, CPU only (ONNX Runtime).
|
|
21
|
+
- **Engine:** `bulk-bg-remove` 0.1.0, one worker, edge matting on (the default),
|
|
22
|
+
everything else at defaults. Times are per image and include matting.
|
|
23
|
+
- **Models:** the 11 local models rembg ships with permissive licences.
|
|
24
|
+
Excluded: `bria-rmbg` (non-commercial licence), `withoutbg` and `atlascloud`
|
|
25
|
+
(cloud APIs, not local), `birefnet-general-fp16` (needs extra packages),
|
|
26
|
+
`birefnet-cod` (camouflage research model), `sam` (needs prompts).
|
|
27
|
+
|
|
28
|
+
## Images (80 judged)
|
|
29
|
+
|
|
30
|
+
| Set | Images | What it tests |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| edges | 10 | hair, fur, wire, bristles, branches, a dandelion |
|
|
33
|
+
| materials | 8 | glass, chrome, black on black, white on white, hard shadows |
|
|
34
|
+
| composition | 9 | groups, crowds, a logo, a cartoon, a shelf, a landscape with no subject |
|
|
35
|
+
| formats | 18 | HEIC, AVIF, WebP, TIFF, BMP, CMYK, 16-bit grey, palette PNG, ICC, EXIF rotation, a wrong extension, existing alpha, 180 px, 45 MP, a 5:1 panorama |
|
|
36
|
+
| catalogue | 35 | real product catalogue photos (cleaning products, mostly on white) |
|
|
37
|
+
|
|
38
|
+
The 27 photos in the first three sets, and the sources of the 45 MP,
|
|
39
|
+
panorama and portrait format tests, are public (CC0, CC BY, CC BY-SA or public
|
|
40
|
+
domain, from Wikimedia Commons); authors, licences and links are in
|
|
41
|
+
[`benchmark/images.csv`](benchmark/images.csv). The catalogue photos belong to
|
|
42
|
+
a company and are not redistributed; they appear as `catalogue-NN`, and the
|
|
43
|
+
other 14 format tests were made from them.
|
|
44
|
+
|
|
45
|
+
## Judging
|
|
46
|
+
|
|
47
|
+
Each image got one comparison grid: the original plus the 11 cut-outs on a
|
|
48
|
+
checkerboard, labelled A–K in a fixed shuffled order, so the judge could not
|
|
49
|
+
tell which model made which cut-out. The judge, a vision model (Claude), also
|
|
50
|
+
looked at full-resolution crops of the hardest regions, on black, white and
|
|
51
|
+
checkerboard. Every image was zoomed into.
|
|
52
|
+
|
|
53
|
+
Scores are 0–10 for how usable the cut-out is as a professional product or
|
|
54
|
+
portrait asset: **10** clean, complete subject, fine edges kept, no background
|
|
55
|
+
left · **7** small fixable flaws · **4** visible flaws (halo, chunks of
|
|
56
|
+
background, missing parts) · **1** unusable · **0** empty.
|
|
57
|
+
|
|
58
|
+
Every score, with the image's content tags, is in
|
|
59
|
+
[`benchmark/scores.csv`](benchmark/scores.csv).
|
|
60
|
+
|
|
61
|
+
## Results
|
|
62
|
+
|
|
63
|
+
Mean score per set (0–10), images scored 3 or less, speed and RAM. RAM is the
|
|
64
|
+
model alone and the free RAM the planner asks for before a run on 12 MP photos
|
|
65
|
+
(model, image buffers, edge matting and a 1.5 GB reserve).
|
|
66
|
+
|
|
67
|
+
| Model | All (80) | edges (10) | materials (8) | composition (9) | formats (18) | catalogue (35) | ≤ 3 | s/img catalogue | s/img edges | Model RAM | Free RAM needed |
|
|
68
|
+
|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
69
|
+
| `birefnet-general` | **8.0** | 7.0 | 7.8 | 6.8 | 8.4 | 8.4 | 1 | 5.6 | 9.6 | 11.6 GB | 14.3 GB |
|
|
70
|
+
| `birefnet-general-lite` (default) | **7.9** | 6.2 | 7.6 | 6.6 | 8.3 | 8.6 | 2 | 3.2 | 6.5 | 9.4 GB | 12.1 GB |
|
|
71
|
+
| `birefnet-hrsod` | **7.7** | 6.4 | 7.4 | 6.6 | 8.1 | 8.3 | 3 | 5.6 | 9.7 | 11.6 GB | 14.3 GB |
|
|
72
|
+
| `birefnet-massive` | **7.6** | 5.3 | 7.0 | 6.0 | 8.3 | 8.5 | 4 | 5.6 | 9.0 | 11.6 GB | 14.3 GB |
|
|
73
|
+
| `birefnet-dis` | **7.5** | 5.5 | 7.2 | 5.7 | 7.9 | 8.4 | 4 | 5.5 | 7.9 | 11.6 GB | 14.3 GB |
|
|
74
|
+
| `isnet-general-use` | **6.7** | 5.2 | 5.4 | 3.6 | 7.9 | 7.6 | 11 | 1.3 | 7.8 | 2.4 GB | 5.1 GB |
|
|
75
|
+
| `silueta` | **6.6** | 4.5 | 5.1 | 4.1 | 7.8 | 7.5 | 11 | 0.4 | 6.1 | 0.7 GB | 3.4 GB |
|
|
76
|
+
| `u2net` | **6.5** | 4.4 | 5.6 | 4.2 | 7.8 | 7.3 | 8 | 0.5 | 3.3 | 1.8 GB | 4.5 GB |
|
|
77
|
+
| `birefnet-portrait` | **6.5** | 5.6 | 3.5 | 4.0 | 7.7 | 7.4 | 15 | 5.5 | 12.4 | 11.6 GB | 14.3 GB |
|
|
78
|
+
| `u2net_human_seg` | **4.6** | 3.2 | 2.8 | 3.1 | 7.0 | 4.5 | 37 | 0.8 | 3.2 | 1.8 GB | 4.5 GB |
|
|
79
|
+
| `isnet-anime` | **2.2** | 0.5 | 2.0 | 2.2 | 1.4 | 3.1 | 64 | 1.2 | 1.3 | 2.2 GB | 4.9 GB |
|
|
80
|
+
|
|
81
|
+
All 11 models processed all 82 files with no failures (two catalogue files
|
|
82
|
+
sharing a name were timed but not judged).
|
|
83
|
+
|
|
84
|
+
### By kind of image (what `--model auto` uses)
|
|
85
|
+
|
|
86
|
+
Images grouped by their content tags into the profiles an agent picks from.
|
|
87
|
+
`auto` takes the highest score that fits in free RAM, and asks before using a
|
|
88
|
+
model more than 0.5 points below the best.
|
|
89
|
+
|
|
90
|
+
| Profile | n | Best | Next | Light models (~3.5–5 GB free) |
|
|
91
|
+
|---|---|---|---|---|
|
|
92
|
+
| `uniform` — products, objects | 39 | lite 8.6 · general 8.6 | hrsod 8.5 · massive 8.5 | u2net 8.1 · silueta 8.1 · isnet 7.7 |
|
|
93
|
+
| `complex` — hair, fur, plants, thin parts | 32 | general 7.6 | lite 7.4 · hrsod 7.3 | isnet 6.0 · silueta 5.2 · u2net 5.2 |
|
|
94
|
+
| `people` | 8 | general 7.8 | dis 7.4 · massive 7.2 | u2net 6.0 · silueta 5.8 · isnet 5.2 |
|
|
95
|
+
| `scene` — cluttered | 6 | general 6.3 | hrsod 5.7 | u2net 4.0 · silueta 4.0 · isnet 3.7 |
|
|
96
|
+
| `drawing` | 1 | isnet-anime 9.0 | lite 8.0 | — |
|
|
97
|
+
|
|
98
|
+
## RAM
|
|
99
|
+
|
|
100
|
+
Peak resident memory of a worker on the edge-heavy set, before and after
|
|
101
|
+
bounding edge matting and restarting workers whose heap had grown (both in
|
|
102
|
+
v0.1.0):
|
|
103
|
+
|
|
104
|
+
| Model | Before | After | Planner's figure |
|
|
105
|
+
|---|---|---|---|
|
|
106
|
+
| `birefnet-general-lite` | 15.7 GB | 12.3 GB | 12.6 GB |
|
|
107
|
+
| `birefnet-general` | 17.5 GB | 14.4 GB | 14.8 GB |
|
|
108
|
+
| `silueta` | 9.1 GB | 3.9 GB | 3.9 GB |
|
|
109
|
+
| `u2net` | 9.3 GB | 5.1 GB | 5.0 GB |
|
|
110
|
+
|
|
111
|
+
Edge matting costs ~0.35 GB per matted megapixel plus ~2.3 GB per million
|
|
112
|
+
pixels in the uncertain band, so a wire chair needs far more than a bottle.
|
|
113
|
+
18 of the 20 re-checked cut-outs came out pixel-identical after the change.
|
|
114
|
+
|
|
115
|
+
## The cut-out reviewer
|
|
116
|
+
|
|
117
|
+
Three reviewers (the skill's `bg-reviewer` guide, nothing else) looked at the
|
|
118
|
+
62 default-model cut-outs of the edges, materials, composition and catalogue
|
|
119
|
+
sets, without the judges' scores.
|
|
120
|
+
|
|
121
|
+
| | |
|
|
122
|
+
|---|---|
|
|
123
|
+
| Bad cut-outs (judge score ≤ 5) flagged | **8 of 9** |
|
|
124
|
+
| Good cut-outs (≥ 8) flagged | 5 of 45 (2 only for `--clean-edges`) |
|
|
125
|
+
| Proposed fixes that the judges score higher | 5 of 11 measurable (e.g. 5 → 8 on long fur, plants, curly hair) |
|
|
126
|
+
| …the same | 3 |
|
|
127
|
+
| …1 point lower | 3, all on cut-outs already ≥ 7 |
|
|
128
|
+
|
|
129
|
+
Because a second pass can make a good cut-out worse, the skill runs fixes into
|
|
130
|
+
a separate folder and keeps the new cut-out only when the reviewer judges it
|
|
131
|
+
better.
|
|
132
|
+
|
|
133
|
+
## End-to-end: a fresh agent, no context
|
|
134
|
+
|
|
135
|
+
A new Claude Code session, with only the plugin installed and no other
|
|
136
|
+
context, got one request: *"use the bulk-bg-remove skill to remove the
|
|
137
|
+
background from every photo in this folder"*, on a 248-image test folder (the
|
|
138
|
+
benchmark sets plus 151 catalogue photos and a deliberately messy folder). It
|
|
139
|
+
was allowed to run the engine and to copy files, nothing else.
|
|
140
|
+
|
|
141
|
+
- It installed the engine, looked at the sample sheet, picked `uniform` for the
|
|
142
|
+
folder and ran it in the background: **247 of 248 done**; the one failure was
|
|
143
|
+
a truncated file, reported as damaged. Non-images, a GIF, a hidden file and an
|
|
144
|
+
earlier output folder were listed as skipped, each with its reason.
|
|
145
|
+
- It split 21 review sheets across **4 `bg-reviewer` subagents** in parallel,
|
|
146
|
+
redid the flagged images in a side folder, had a fresh reviewer compare old
|
|
147
|
+
and new, and kept the new version for 4 of them (a handler's arm gone from a
|
|
148
|
+
dog, a wine glass stem recovered, a cutter tip and a jug shoulder restored).
|
|
149
|
+
- It reported what it could not fix (a colour tint on a dandelion and a plant,
|
|
150
|
+
two see-through metal handles) and what the user should decide (placeholder
|
|
151
|
+
"no photo" images, scenes with no clear subject, a 180 px original).
|
|
152
|
+
|
|
153
|
+
What it surfaced, and what changed since: agent file readers ignore
|
|
154
|
+
transparency and show the original background in the output PNG, so
|
|
155
|
+
reviewers now get flattened close-ups on black and white (`zoom`); and fixes
|
|
156
|
+
now go to a `<name>-retry-no-bg` folder next to the output instead of `/tmp`,
|
|
157
|
+
which needed extra approval to copy from.
|
|
158
|
+
|
|
159
|
+
A second fresh session with those fixes, from a clean install, did the same
|
|
160
|
+
job with close-ups: **5 reviewers**, 214 cut-outs fine, 20 redone in one
|
|
161
|
+
round with four different fixes (`--profile complex`, `--model
|
|
162
|
+
birefnet-general`, `--clean-edges`, `--model birefnet-portrait`), **8 kept**
|
|
163
|
+
because they were clearly better (long fur, curly and loose hair, a cat, a
|
|
164
|
+
wine glass, three catalogue products), 12 kept as they were and reported.
|
|
165
|
+
Every redone file differed from the first pass; none was copied over without
|
|
166
|
+
a reviewer's `keep: new`.
|
|
167
|
+
|
|
168
|
+
A third fresh session tested the shop flow from a clean install. The only
|
|
169
|
+
request was *"use the bulk-bg-remove skill to remove the background from every
|
|
170
|
+
photo in this folder; they are for my online store"*. It picked `--shop` on its
|
|
171
|
+
own and processed **247 of 248**: every output was a 2000×2000 white JPEG
|
|
172
|
+
carrying the `--shop` finish in its metadata. Five reviewers found 17 to
|
|
173
|
+
redo. The agent redid them with the same finishing flags and kept **9** that
|
|
174
|
+
were clearly better. In its report it listed the 5 that a second pass did not
|
|
175
|
+
fix, the placeholders and scenes that do not belong in a shop, and the small
|
|
176
|
+
originals that `--size 2000` had to enlarge, offering `--size 1000` as an
|
|
177
|
+
option. The whole session cost about $5.70 in model usage, most of it for
|
|
178
|
+
looking at review close-ups.
|
|
179
|
+
|
|
180
|
+
## Caveats
|
|
181
|
+
|
|
182
|
+
- One judge (a vision model) per image, no second opinion: read gaps under
|
|
183
|
+
~0.5 points as ties.
|
|
184
|
+
- Small samples behind some rows: `drawing` has 1 image, `scene` 6, `people` 8.
|
|
185
|
+
- The catalogue set is one product line (cleaning products, mostly on white);
|
|
186
|
+
fashion, food or jewellery may differ.
|
|
187
|
+
- One machine, CPU only, one worker. No GPU timings.
|
|
188
|
+
- `--clean-edges` and `--fast-edges` were not scored.
|
|
189
|
+
|
|
190
|
+
## Reproduce
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
uv sync
|
|
194
|
+
# 1. Run every model on a folder of photos (times, peak RAM, before/after sheets)
|
|
195
|
+
uv run python scripts/bench.py PHOTOS RESULTS --model birefnet-general-lite --model silueta ...
|
|
196
|
+
# 2. Blind grids for judging (models shown as letters; GRIDS/index.json maps them back)
|
|
197
|
+
uv run python scripts/bench_grids.py PHOTOS RESULTS GRIDS
|
|
198
|
+
# 3. Close-ups of one region while judging
|
|
199
|
+
uv run python scripts/bench_grids.py --zoom GRIDS wine-glass ORIGINAL,A,B 0.2 0.1 0.8 0.6
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The public photos can be downloaded from the links in `benchmark/images.csv`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Btike
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: bulk-bg-remove
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Remove image backgrounds locally and in bulk: an agent skill for Claude Code, Codex and any agent, plus the engine behind it.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Btike/bulk-bg-remove
|
|
6
|
+
Project-URL: Repository, https://github.com/Btike/bulk-bg-remove
|
|
7
|
+
Project-URL: Issues, https://github.com/Btike/bulk-bg-remove/issues
|
|
8
|
+
Project-URL: Benchmark, https://github.com/Btike/bulk-bg-remove/blob/main/BENCHMARK.md
|
|
9
|
+
Author: Btike
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: agent-skill,background-removal,birefnet,bulk,claude-code,codex,image-processing,rembg,remove-background,transparent-png
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Environment :: Web Environment
|
|
16
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
23
|
+
Requires-Python: <3.14,>=3.11
|
|
24
|
+
Requires-Dist: fastapi>=0.110
|
|
25
|
+
Requires-Dist: numpy>=1.26
|
|
26
|
+
Requires-Dist: pillow-heif>=0.18
|
|
27
|
+
Requires-Dist: pillow>=11.3
|
|
28
|
+
Requires-Dist: psutil>=5.9
|
|
29
|
+
Requires-Dist: pymatting>=1.1
|
|
30
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
31
|
+
Requires-Dist: rembg[cpu]>=2.0.86
|
|
32
|
+
Requires-Dist: rich>=13.7
|
|
33
|
+
Requires-Dist: scipy>=1.11
|
|
34
|
+
Requires-Dist: uvicorn>=0.29
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
<p align="center">
|
|
38
|
+
<picture>
|
|
39
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Btike/bulk-bg-remove/main/assets/logo-dark.svg">
|
|
40
|
+
<img src="https://raw.githubusercontent.com/Btike/bulk-bg-remove/main/assets/logo-light.svg" width="200" alt="bulk-bg-remove logo: a pixel-art monitor showing a green vase with a pink tulip on a transparency checkerboard">
|
|
41
|
+
</picture>
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
<h1 align="center">bulk-bg-remove</h1>
|
|
45
|
+
|
|
46
|
+
<p align="center"><em>Every photo in the folder. No background. Nothing leaves your machine.</em></p>
|
|
47
|
+
|
|
48
|
+
<p align="center">
|
|
49
|
+
<img alt="works with" src="https://img.shields.io/badge/works%20with-Claude%20Code%20·%20Codex%20·%20any%20agent-0d1117?style=flat-square">
|
|
50
|
+
<img alt="license" src="https://img.shields.io/badge/license-MIT-0d1117?style=flat-square">
|
|
51
|
+
<a href="https://pypi.org/project/bulk-bg-remove/"><img alt="PyPI" src="https://img.shields.io/pypi/v/bulk-bg-remove?style=flat-square&color=0d1117&label=pypi"></a>
|
|
52
|
+
</p>
|
|
53
|
+
|
|
54
|
+
<p align="center">
|
|
55
|
+
<img src="https://raw.githubusercontent.com/Btike/bulk-bg-remove/main/assets/demo.webp" width="880" alt="Demo: an agent is asked to remove the background from every photo in a folder; a bottle of olive oil loses its background, a reviewer catches background left by a cat's ear and keeps the redone cut-out, the products switch between white, mint and rose backgrounds and land in an online store">
|
|
56
|
+
</p>
|
|
57
|
+
|
|
58
|
+
<p align="center"><strong>Other skills run a model. This one checks every cut-out and redoes the bad ones.</strong></p>
|
|
59
|
+
|
|
60
|
+
<p align="center">
|
|
61
|
+
<strong>11 models benchmarked on 80 hard images, judged blind at zoom.</strong><br>
|
|
62
|
+
The default scored <strong>8.6/10 on real product catalogue photos</strong>, the best of the 11, at <strong>3.2 s per photo</strong> on a laptop CPU.<br>
|
|
63
|
+
<sub>Apple M5, CPU only, one worker. Method, every score and the RAM numbers: <a href="https://github.com/Btike/bulk-bg-remove/blob/main/BENCHMARK.md">BENCHMARK.md</a>.</sub>
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
## What it is
|
|
67
|
+
|
|
68
|
+
An agent skill plus the engine behind it. Ask your coding agent to *"remove the
|
|
69
|
+
background from every photo in this folder"* and it:
|
|
70
|
+
|
|
71
|
+
1. installs the engine (one `uv tool install`, ~500 MB with Python),
|
|
72
|
+
2. checks your machine (free RAM, formats) and plans the run,
|
|
73
|
+
3. looks at a sample, picks the best model that fits your free RAM (BiRefNet when there is
|
|
74
|
+
room), and cuts out every image in a queue or in parallel depending on RAM and CPU,
|
|
75
|
+
4. has a second agent, with fresh eyes, review every cut-out on black and on white,
|
|
76
|
+
redo the bad ones with a better setting and keep whichever version is better,
|
|
77
|
+
5. tells you what worked, what failed and why.
|
|
78
|
+
|
|
79
|
+
Output goes to a new `<name>-no-bg/` folder next to the input. Originals are never
|
|
80
|
+
touched, and the subject's pixels are copied bit for bit: only the alpha channel is new.
|
|
81
|
+
|
|
82
|
+
Selling online? `--shop` puts every product on white, square, 2000 px and ready to
|
|
83
|
+
upload; `--background "#E6F6EA"` uses your brand colour instead.
|
|
84
|
+
|
|
85
|
+
<p align="center">
|
|
86
|
+
<img src="https://raw.githubusercontent.com/Btike/bulk-bg-remove/main/assets/showcase.webp" width="880" alt="Four before-and-after pairs: three friends by train tracks, a black camera on black, a bottle of olive oil, and a white bicycle against a wall, each cut out onto a transparency checkerboard">
|
|
87
|
+
</p>
|
|
88
|
+
|
|
89
|
+
Reads JPG, PNG, HEIC, WebP, AVIF, TIFF and BMP (by content, not extension), follows
|
|
90
|
+
EXIF rotation, and handles CMYK, 16-bit and 45 MP photos.
|
|
91
|
+
|
|
92
|
+
## Install
|
|
93
|
+
|
|
94
|
+
Any agent ([skills CLI](https://github.com/vercel-labs/skills), needs Node.js 22.20 or newer):
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx skills add Btike/bulk-bg-remove
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
<details>
|
|
101
|
+
<summary>Claude Code</summary>
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
/plugin marketplace add Btike/bulk-bg-remove
|
|
105
|
+
```
|
|
106
|
+
```
|
|
107
|
+
/plugin install bulk-bg-remove@bulk-bg-remove
|
|
108
|
+
```
|
|
109
|
+
</details>
|
|
110
|
+
|
|
111
|
+
<details>
|
|
112
|
+
<summary>Codex</summary>
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
codex plugin marketplace add Btike/bulk-bg-remove
|
|
116
|
+
codex plugin add bulk-bg-remove@bulk-bg-remove
|
|
117
|
+
```
|
|
118
|
+
</details>
|
|
119
|
+
|
|
120
|
+
<details>
|
|
121
|
+
<summary>Just the command, no agent</summary>
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
uv tool install bulk-bg-remove
|
|
125
|
+
bulk-bg-remove ~/Pictures/products # → ~/Pictures/products-no-bg/
|
|
126
|
+
bulk-bg-remove # opens a drag-and-drop page in your browser
|
|
127
|
+
```
|
|
128
|
+
</details>
|
|
129
|
+
|
|
130
|
+
## Which model it picks
|
|
131
|
+
|
|
132
|
+
You do not choose: the agent looks at a few of your photos, tells the engine
|
|
133
|
+
what kind they are, and the engine takes the best model for that kind that
|
|
134
|
+
fits in your free RAM. Scores are from a [blind-judged benchmark](https://github.com/Btike/bulk-bg-remove/blob/main/BENCHMARK.md) (0–10):
|
|
135
|
+
|
|
136
|
+
| Your photos | Best model | With little RAM (~4 GB free) |
|
|
137
|
+
|---|---|---|
|
|
138
|
+
| Products, objects | `birefnet-general-lite` 8.6 | `silueta` 8.1, used on its own |
|
|
139
|
+
| Hair, fur, plants, wires | `birefnet-general` 7.6 | `silueta` 5.2, only if you say yes |
|
|
140
|
+
| People | `birefnet-general` 7.8 | `silueta` 5.8, only if you say yes |
|
|
141
|
+
| Busy scenes | `birefnet-general` 6.3 | `silueta` 4.0, only if you say yes |
|
|
142
|
+
| Drawings, anime | `isnet-anime` 9.0 | needs ~5 GB free |
|
|
143
|
+
|
|
144
|
+
## Options
|
|
145
|
+
|
|
146
|
+
| Flag | What it does |
|
|
147
|
+
|---|---|
|
|
148
|
+
| `--profile uniform\|complex\|people\|scene\|drawing` | what the photos are; the model follows |
|
|
149
|
+
| `--model NAME` | force a model instead of `auto` |
|
|
150
|
+
| `--format webp\|jpg` | smaller lossless files (PNG by default); JPEG only with a background |
|
|
151
|
+
| `--shop` | ready for a shop: white, square, product filling ~85%, 2000 px, JPEG |
|
|
152
|
+
| `--background white\|#RRGGBB` | a solid colour behind the subject |
|
|
153
|
+
| `--square` · `--pad PCT` · `--size PX` | square canvas · margin around the subject · longest side |
|
|
154
|
+
| `--clean-edges` | remove the old background's colour halo from hair and fur edges |
|
|
155
|
+
| `--fast-edges` | skip edge matting: faster, coarser hair |
|
|
156
|
+
| `--review-sheets` | sheets and close-ups for reviewing the cut-outs |
|
|
157
|
+
| `--only FILE` | redo just some images, keeping their output names |
|
|
158
|
+
| `--dry-run --json` | scan and plan only; one JSON event per line for agents |
|
|
159
|
+
| `doctor` | check the machine, and what `auto` would pick right now |
|
|
160
|
+
|
|
161
|
+
## Requirements
|
|
162
|
+
|
|
163
|
+
- Tested on macOS (Apple silicon), Linux and Windows, with a real-model run on each in CI
|
|
164
|
+
(Python 3.11–3.13). CPU by default; CUDA with `onnxruntime-gpu`.
|
|
165
|
+
- **3.5 GB of free RAM** is enough for product photos: the engine picks the best
|
|
166
|
+
model that fits (about 12 GB gets the best ones). For hair, fur and plants a
|
|
167
|
+
light model is clearly worse, so the agent asks before using one.
|
|
168
|
+
- The model downloads once (~220 MB). After that everything runs offline.
|
|
169
|
+
|
|
170
|
+
## Credits
|
|
171
|
+
|
|
172
|
+
Built on [rembg](https://github.com/danielgatis/rembg) and
|
|
173
|
+
[BiRefNet](https://github.com/ZhengPeng7/BiRefNet). Showcase and demo photos (CC0, via
|
|
174
|
+
Wikimedia Commons): Priscilla Du Preez, Dennis Klein, margenauer, Natasza Remesz,
|
|
175
|
+
Mona Magnussen, Tiko Giorgadze, Dmitry Ratushny. The demo film is drawn in code (GSAP, rendered frame by
|
|
176
|
+
frame in headless Chromium) from the engine's real output.
|
|
177
|
+
|
|
178
|
+
## License
|
|
179
|
+
|
|
180
|
+
MIT — see [LICENSE](https://github.com/Btike/bulk-bg-remove/blob/main/LICENSE).
|