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:
@@ -147,6 +147,67 @@ public class BackgroundEffectEngineTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>TASK 51 blur-heavy fix — the integration test: an all-background frame with one
|
||||
/// bright pixel. The default 0.5 strength must keep the halo tight (quadratic curve: radius 2
|
||||
/// small px) while full strength spreads it far (radius 6) — the maker complained the default
|
||||
/// was heavy under the old linear 1..12 range.</summary>
|
||||
[Fact]
|
||||
public void Blur_default_strength_is_gentle_and_full_strength_is_strong()
|
||||
{
|
||||
const int w = 128, h = 64;
|
||||
var pixels = new byte[w * h * 4];
|
||||
for (var y = 0; y < h; y++)
|
||||
for (var x = 0; x < w; x++)
|
||||
{
|
||||
var p = (y * w + x) * 4;
|
||||
if (x < w / 2) pixels[p] = 200;
|
||||
pixels[p + 1] = 180;
|
||||
pixels[p + 2] = 160;
|
||||
pixels[p + 3] = 255;
|
||||
}
|
||||
var frame = new VideoFrame(w, h, pixels) { IsOpaque = true };
|
||||
|
||||
// All background — the whole frame blurs, no person boundary to confuse the edge spread.
|
||||
var mask = new SegmentationMask(4, 2, new float[8]);
|
||||
var processor = new BackgroundEffectProcessor(new FakeSegmenter(mask));
|
||||
|
||||
var gentle = processor.Apply(frame, BackgroundEffect.Blur, BackgroundEffectProcessor.DefaultStrength);
|
||||
var strong = processor.Apply(frame, BackgroundEffect.Blur, 1.0);
|
||||
|
||||
// The radius mapping itself: quadratic, not the old linear 1..12. Default 0.5 = 2 small px
|
||||
// (was 6), max = 6 small px (was 12) — the reason the default felt heavy before.
|
||||
Assert.Equal(1, BackgroundEffectProcessor.BlurRadius(0.0));
|
||||
Assert.Equal(2, BackgroundEffectProcessor.BlurRadius(BackgroundEffectProcessor.DefaultStrength));
|
||||
Assert.Equal(BackgroundEffectProcessor.MinBlurRadius, BackgroundEffectProcessor.BlurRadius(0.0));
|
||||
Assert.Equal(BackgroundEffectProcessor.MaxBlurRadius, BackgroundEffectProcessor.BlurRadius(1.0));
|
||||
|
||||
// Behaviour at a step edge: the default smears light only ~9px into the dark half (measured),
|
||||
// full strength smears ~26px — a gentle default with a real range above it.
|
||||
var (reachGentle, sumGentle) = EdgeReach(gentle);
|
||||
var (reachStrong, sumStrong) = EdgeReach(strong);
|
||||
Assert.True(reachGentle <= 12, $"default blur reach {reachGentle}px (expected <= 12)");
|
||||
Assert.True(reachStrong >= 20, $"max blur reach {reachStrong}px (expected >= 20)");
|
||||
Assert.True(reachStrong > reachGentle);
|
||||
Assert.True(sumStrong > sumGentle * 2, "max strength should smear visibly more light than default");
|
||||
}
|
||||
|
||||
/// <summary>Largest x into the dark half (x = w/2) still carrying light, and the total light
|
||||
/// in the dark half — the blur's smearing distance at a step edge.</summary>
|
||||
private static (int Reach, double Sum) EdgeReach(VideoFrame f)
|
||||
{
|
||||
var edge = f.Width / 2;
|
||||
var reach = 0;
|
||||
double sum = 0;
|
||||
for (var y = 0; y < f.Height; y++)
|
||||
for (var x = edge; x < f.Width; x++)
|
||||
{
|
||||
var v = f.BgraPixels[(y * f.Width + x) * 4];
|
||||
if (v >= 32) reach = Math.Max(reach, x - edge);
|
||||
sum += v;
|
||||
}
|
||||
return (reach, sum);
|
||||
}
|
||||
|
||||
private static int Alpha(VideoFrame f, int x, int y) => f.BgraPixels[(y * f.Width + x) * 4 + 3];
|
||||
|
||||
private static string Fixture(string name) => Path.Combine(AppContext.BaseDirectory, "Fixtures", name);
|
||||
|
||||
Reference in New Issue
Block a user