Files
LlamaCasty/TASKS/task-51-webcam-bg-effects.md
T
gramps 9f3c154d84 TASK 51 slice 1: background-effects engine — bundled MediaPipe Selfie Segmenter (ONNX) + Remove (Unit: bg-effects engine)
- Model: Google's official MediaPipe Selfie Segmenter (landscape, Apache-2.0 per model card),
  converted to ONNX by tools/selfie-seg/convert_tflite_to_onnx.py (custom op
  Convolution2DTransposeBias -> ConvTranspose) and verified against MediaPipe's own runtime
  (verify_against_mediapipe.py: max |diff| 5e-5, 100% binary agreement). Embedded resource, 430 KB.
- Services/BackgroundEffects: IPersonSegmenter seam, OnnxPersonSegmenter (onnxruntime 1.31.0 CPU,
  never throws), BackgroundEffectProcessor (None passthrough, Remove = alpha mask). Not wired yet.
- Tests: Remove integration test (fake segmenter) + bundled-model contract test vs MediaPipe
  reference mask. Full suite 407/408 — the one failure is the documented interactive-desktop flake
  RealMouseDrag_OnTheLayerList_PersistsTheReorder (passed in the run before; code path untouched).
- Docs: ai.md reversal + section + licensing guard, THIRD-PARTY-NOTICES 11-12, TASK 51, indexes,
  MyMistakes recipe, HANDOFF.

References: obs-backgroundremoval (approach only — ONNX Runtime on CPU, 2 threads; GPL-3.0, no code
used) https://github.com/royshil/obs-backgroundremoval ; MediaPipe image segmenter
https://ai.google.dev/edge/mediapipe/solutions/vision/image_segmenter
2026-10-09 09:24:13 -07:00

108 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TASK 51 — Webcam background effects: Remove + Blur (v1 requirement)
> Catalog: [`TASKS.md`](../TASKS.md) — status and requirements live here.
> **Booked 2026-10-08 by creator ruling** — *"we're doing the bg removal and blur for v1 - book it, Danno"*.
> This **reverses** the 2026-10-05 "background removal: out of product" exclusion (TASK 3 item 19).
**Status:** 🔶 In progress — **slice 1 (engine: bundled model + runner + Remove) shipped 2026-10-09**.
Next: slice 2 (Blur), then config + persistence, then the camera-path hookup + UI.
**Goal:** per-webcam **Background Remove** and **Background Blur** on the live webcam layer,
selected per element in its properties panel, composited into stream + recording like any
other layer. No external downloads, no hardware requirement, works on any machine.
Replacement backgrounds are **free via layers** — drop any element behind the webcam.
---
## Why this is now IN (and what changed)
The 2026-10-05 exclusion was based on: an in-app AI model = a runtime, a GPU/driver matrix,
per-scene lighting tuning, and "a vcam app does it free." The ruling is reversed because the
delivery shape changed:
1. **Bundled small ONNX model (~2–5 MB)** — MediaPipe Selfie-Segmentation family —
shipped in the installer/fixture (TASK 48 MSIX), executed by **onnxruntime** (CPU default;
DirectML optional later). No NVIDIA SDK, no GPU requirement, no per-client download.
2. **Quality reality (creator):** a 720p webcam displays at ~15% of a 1080p frame — premium
segmentation quality is invisible at that size; commodity class is sufficient.
3. **⛔ Ruled out: NVIDIA Video Effects SDK (VFX / Maxine, AI Green Screen + Background Blur).**
Works on RTX 2000+/R570+ only, and needs a ~1 GB user-side redistributable on first use.
Creator: *"I don't think I'm putting a 1gb download requirement on a client box."*
## Constraints — non-negotiable
1. **No external download at runtime.** Model ships in the installer. (Store policy 10.2.2 —
same posture as the ffmpeg bundling in TASK 48 item 1.)
2. **No hardware requirement.** CPU path must work; DirectML is an optional accelerator.
3. **Per-element (Meld-style), not global.** Each webcam element carries its own effect.
4. **No feature gating.** Everything is free (free-forever ruling 2026-10-08, TASK 54 — the old
"only the branding flash is paid" line here was superseded).
5. **Scene change / webcam add/remove must not crash or stall the pump** — a failing model
run skips to passthrough, never drops the layer.
## Out of scope for v1 (same engine later)
- ❌ **"Remove chair"-style object selection / quality tiers** — not a picker engine
- ❌ **Super resolution / denoise / prettify passes**
- ❌ **Virtual camera output** — permanently out of product (no vcam)
## 1. Engine
- ✅ **Model bundled (slice 1, 2026-10-09):** Google's official MediaPipe Selfie Segmenter
**landscape** (144×256, Apache-2.0 per the model card — license + changes recorded in
THIRD-PARTY-NOTICES item 12). Converted to ONNX by `tools/selfie-seg/convert_tflite_to_onnx.py`
(custom op `Convolution2DTransposeBias` → `ConvTranspose`); verified against MediaPipe's own
runtime by `tools/selfie-seg/verify_against_mediapipe.py` (max |diff| 5e-5). 430 KB,
`EmbeddedResource` in the exe. Rejected sources: PINTO #109 (ML Kit-extracted, unclear license),
obs-backgroundremoval code (GPL-3.0) — referenced for approach only (ONNX Runtime, CPU, 2 threads).
- ✅ `Microsoft.ML.OnnxRuntime` 1.31.0, CPU EP (`OnnxPersonSegmenter`). Failing load/run →
logs once, returns null, caller passes through. DirectML still optional/later.
- ☐ Blur = **separable in-app blur** (box/gaussian) over the masked background region — slice 2.
- ✅ Remove = alpha = mask outside the person (`BackgroundEffectProcessor`), `IsOpaque = false`.
The compositor already alpha-blends per element — no compositor change expected (confirm in
the hookup slice).
- ☐ Feed the **VideoFrame seam** (`Services/VideoFrame.cs` doc explicitly anticipates
*"every future capture source (screen, background-removed webcam) feeds the same seam"*):
the frame handed to BOTH the preview bitmap path and the compositor's
`_cameraManager.GetLatestFrame` is the processed frame. One processing point, two consumers.
## 2. ☐ Config surface + persistence
- ☐ `WebcamSceneConfig` gains `BackgroundEffect` (`None | Remove | Blur`) + `Strength`.
- ☐ Persist via the existing `WebcamSceneConfig` table path in `LayoutStore.Save.cs`/
`Load.cs` (new columns + migration). Follow `LayoutStore.Migrations.cs` conventions.
- ☐ Properties panel: effect dropdown + strength slider, per webcam element.
- ☐ Replace-background affordance: **none in v1** — the creator drops any layer behind the
webcam. Effect preview must not obscure the fact that layers below still show through.
## 3. ☐ Test seam (Good Dog — one integration test per unit)
- ✅ Model-runner interface seam (`IPersonSegmenter`) so tests inject a fake segmenter.
- ☐ Assert the **processed frame reaches both consumers** (preview bitmap + compositor frame).
- ✅ `None` = same-instance passthrough of the raw frame (`BackgroundEffectEngineTests`).
- ✅ `Remove` = alpha 0 outside the person, RGB untouched, non-opaque (`BackgroundEffectEngineTests`);
☐ `Blur` = background region blurred, person sharp.
- ✅ **Bundled-model contract:** the embedded ONNX model through the C# preprocessing reproduces
MediaPipe's reference mask on a fixture (≥99.5% agreement). This is a fixed, deterministic
contract check of the shipped bytes — not a camera/lighting quality test.
- ☐ Config → persistence roundtrip (per webcam element).
- ☐ Engine failure → passthrough + single log, layer never dropped (code path exists; dedicated
test lands with the hookup slice).
- ☐ Real inference: **manual on the creator's box** (camera + lighting), not in CI.
- ☐ **Perf check in the hookup slice:** time `Segment` + `Apply` per 720p frame on the creator's
box before wiring it into the 60fps path (expect a few ms; the mask can run at a lower rate
than the camera if needed).
## 4. Sequencing
- ✅ Separate work unit after the zoom build (zoom shipped 2026-10-08).
- Slice order: 1 engine ✅ → 2 Blur → 3 config + persistence → 4 camera-path hookup (one
processing point, both consumers) + perf check → 5 properties-panel UI.
## Related (not duplicated here)
- [`task-48-distribution-msix.md`](task-48-distribution-msix.md) — the model ships in the
MSIX; bundled-binary posture established by the ffmpeg work.
- `TASKS.md` Webcam cadence section — the "⛔ no background removal" line is superseded
by this ruling; the **judder/compositor cost work is unaffected and still heads its lane.**
- `research-store-certification.md` — 11.12/10.2.2 posture; nothing here sends data off-box.