TASK 51 blur 'heavy' fix: quadratic blur radius. BlurRadius(strength) = 1 + 5s^2, MaxBlurRadius 12 -> 6 downscaled px (~24 full px max). Default 0.5 is now radius 2 small px (was the old linear 6) - ~3x lighter perceived spread, matching the creator's real-camera finding. Range from the established tools: StreamFX defaults its Box blur Size to 5 and its author stops downscale-based blurs around 8px. One integration test pins the mapping (0 -> 1, 0.5 -> 2, 1 -> 6) and step-edge behaviour (light reaches 9px at default vs 26px at full); the existing slice-2 blur test passes unchanged. 419/419 pass. Refs: https://github.com/Vhonowslend/StreamFX-Public/wiki/Filter-Blur https://xaymar.com/articles/2020/04/26/optimizing-streamfx-in-your-obs-scenes/ (Unit: bg-blur heavy fix)
This commit is contained in:
+19
-25
@@ -1,4 +1,4 @@
|
||||
# HANDOFF — 2026-10-09 (TASK 51 quality pass: jitter FIXED; blur-heavy is the next unit)
|
||||
# HANDOFF — 2026-10-09 (TASK 51 quality pass COMPLETE: jitter + blur-heavy both fixed)
|
||||
|
||||
## Branch
|
||||
- main (no feature branch). Pushed through `5685c5d` (TRAX toggle); everything after is local,
|
||||
@@ -17,31 +17,25 @@
|
||||
the not-mine files WILL flag. Pass them to the script as declared-known (checksums unchanged since
|
||||
`5685c5d`) or let the script's output be reconciled before committing.
|
||||
|
||||
## What just happened — temporal jitter fix
|
||||
- Creator check: bg Remove is "jittery", Blur is "heavy". User picked **jitter first**.
|
||||
- Root cause: `OnnxPersonSegmenter` classifies each frame independently (256×144 mask, bilinear
|
||||
upsample) → zero temporal coherence → edge flutter. There is no temporal smoothing upstream.
|
||||
- **Fix: `MaskSmoother`** — per-session blend of each raw mask with the previous smoothed one,
|
||||
0.75×new + 0.25×previous (`CurrentWeight`, internal). Wired at the ONE production point
|
||||
(`CameraManager.RunEffectWorker` → `session.Smoother.Smooth(TrySegment(source))`); state on
|
||||
`CameraSession`, NOT the segmenter (segmenter is shared app-wide and contract-pinned to raw output).
|
||||
Null mask resets history; first frame/size-change passthrough; never aliases the caller's array; two
|
||||
ping-pong buffers, no per-frame LOH alloc. Weights: OBS obs-backgroundremoval 0.85 default test, Jitsi
|
||||
jitsi/jitsi-meet#17080 0.7/0.3 best (0.5/0.5 smears on motion).
|
||||
- **Test:** `CameraManagerTests.Temporal_Smoothing_Damps_Segmentation_Jitter_Across_Frames` — PASSED.
|
||||
A `SteppingMaskSegmenter` returns fresh masks per call: `{1,1,0,0}` then `{1,0.2,0,0}`; 16×4 frame,
|
||||
Remove 0.5. Asserts x=6: frame1 = 255 (passthrough), frame2 smoothed = **58**, raw-unsmoothed = 0;
|
||||
person core x=1 = 255, background x=14 = 0. ⚠️ Gotcha: the worker's latest-frame-drop guard treats a
|
||||
re-queued IDENTICAL frame reference as "no new frame" — pump frame2 as a NEW `VideoFrame` instance.
|
||||
- `Assert.Equal(255, first[...])`/`58`/`0` predictions were hand-verified; other pixels differ by
|
||||
float rounding (e.g. x=5 Python 34 vs C# 36) — only assert x=6/x=1/x=14.
|
||||
## What just happened — two commits
|
||||
1. **Jitter fix (`3057069`) — `MaskSmoother`**: per-session blend 0.75×new + 0.25×previous at the
|
||||
ONE worker (`CameraManager.RunEffectWorker` → `session.Smoother.Smooth(TrySegment(source))`).
|
||||
State on `CameraSession`, NOT the segmenter (shared app-wide, contract-pinned to raw output). Null
|
||||
resets history; first frame passes through; never aliases caller's array; ping-pong buffers (no
|
||||
per-frame LOH alloc). Weights: OBS obs-backgroundremoval 0.85 default, Jitsi 0.7/0.3 best
|
||||
(0.5/0.5 smears). Test `Temporal_Smoothing_Damps_Segmentation_Jitter_Across_Frames`: x=6 → first
|
||||
255 / smoothed 58 / raw-unsmoothed 0. ⚠️ Gotcha: worker guards a re-queued identical frame
|
||||
reference — pump frame2 as a NEW instance.
|
||||
2. **Blur "heavy" fix (this commit) — quadratic radius**: `BlurRadius(strength)` = 1 + 5·s²,
|
||||
`MaxBlurRadius` 12→6 small px (≈ 24 full px max). Default 0.5 = 2 small px (was 6 under the old
|
||||
linear curve) — ~3× lighter spread. Rationale: StreamFX defaults Box blur Size to 5, author stops
|
||||
downscaled blurs ~8px. Test `Blur_default_strength_is_gentle_and_full_strength_is_strong` pins the
|
||||
mapping and step-edge behaviour (reach 9px default vs 26px max). Point-source probes vanish below
|
||||
the 0.5 rounding (3 box passes dilute a spike) — use a step edge, not a spike, to measure blur.
|
||||
|
||||
## Next step
|
||||
1. Run `./scripts/verify.sh` with the declared file list; reconcile the not-mine dirty files with
|
||||
scope-check; commit the unit (message `…(Unit: bg-removal jitter fix)` + OBS/Jitsi citations).
|
||||
2. Next unit = **Blur "heavy"** — soften the radius curve in `BackgroundEffectProcessor.ApplyBlur`
|
||||
(`MinBlurRadius=1 / MaxBlurRadius=12` at ¼ res ≈ 26–50 full px; strength 0.5 → 6 small px). The
|
||||
creator needs a retry pass on the real camera after both.
|
||||
- Creator re-runs the app: webcam → Layers properties → Background → Remove / Blur + Strength, and
|
||||
reports whether the jitter is gone and the blur feels right at the slider's default and full range.
|
||||
|
||||
## Also still open
|
||||
- **Vertical-format regression (STALE, not fixed):** 1080p60 vertical selection no longer shrinks the
|
||||
@@ -53,7 +47,7 @@
|
||||
- **Vertical recording file closed:** the recording itself is 1080×1920 60fps correctly; the
|
||||
"whitespace" was the app's preview UI, not the file. Audio loudness (`ebur128`) for the private video
|
||||
was never run and the thread is closed unless the user reopens it.
|
||||
- Blur-heaviness = next unit (above). Yellow-border regression = stale thread.
|
||||
- Blur-heaviness = fixed (above). Yellow-border regression = stale thread.
|
||||
- ⛔ Sudo password rotation pending (user; then update both password lines in `CREDENTIALS.md`).
|
||||
- TASK 56 secret scan before `gramps/LlamaCasty` goes public. TASK 55 disk hygiene queued.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user