File size: 4,489 Bytes
37e3d5a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python3
"""Tests for stage1_intake/detect_reference_effects.py (pure stdlib, unittest).

Synthetic RGB PNGs are written with the verbatim helper below. Images are kept
comfortably above the shared segmenter's tiny-mask floor: build_foreground_mask
INVERTS any mask covering < 3.5% of the frame to "all foreground", so every
subject here is ~5-25% of the frame.
"""

import struct
import sys
import tempfile
import unittest
import zlib
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "stage1_intake"))
from detect_reference_effects import (  # noqa: E402
    detect_background_blur,
    detect_highlight_glow,
    recommend_effects,
)


# --- verbatim PNG helper (copied as instructed) --------------------------- #
import struct, zlib
PNG_SIGNATURE = b"\x89PNG\r\n\x1a\n"
def write_rgb_png(path, w, h, pixel_fn):
    def chunk(tag, data):
        c = struct.pack(">I", len(data)) + tag + data
        return c + struct.pack(">I", zlib.crc32(tag + data) & 0xFFFFFFFF)
    raw = bytearray()
    for y in range(h):
        raw.append(0)
        for x in range(w):
            raw += bytes(pixel_fn(x, y, w, h))
    ihdr = struct.pack(">IIBBBBB", w, h, 8, 2, 0, 0, 0)
    path.write_bytes(PNG_SIGNATURE + chunk(b"IHDR", ihdr) + chunk(b"IDAT", zlib.compress(bytes(raw), 9)) + chunk(b"IEND", b""))
# -------------------------------------------------------------------------- #


class ReferenceEffectTests(unittest.TestCase):
    def setUp(self):
        self.tmp = Path(tempfile.mkdtemp())

    def _sharp_scene(self, x, y, w, h):
        # Colored (red) checkerboard subject block on a sharp grayscale
        # checkerboard background. The red block is caught by the saturation
        # path of the mask (coverage ~25%); the background stays highly
        # textured so its gradient energy is NOT far below the subject.
        checker = (x + y) % 2 == 0
        in_subject = 30 <= x < 90 and 30 <= y < 90
        if in_subject:
            return (210, 50, 50) if checker else (110, 20, 20)
        return (200, 200, 200) if checker else (60, 60, 60)

    def _shallow_dof(self, x, y, w, h):
        # High-contrast grayscale checkerboard subject block (~25% coverage)
        # on a perfectly FLAT uniform background (zero gradient energy).
        in_subject = 30 <= x < 90 and 30 <= y < 90
        if in_subject:
            return (200, 200, 200) if (x + y) % 2 == 0 else (20, 20, 20)
        return (120, 120, 120)

    def _flat_gray(self, x, y, w, h):
        return (120, 120, 120)

    def _glow(self, x, y, w, h):
        # Concentric brightness: small white core (luma > 0.92) surrounded by a
        # gradual gray halo (~0.7 luma) fading to a dark background.
        dx = x - w // 2
        dy = y - h // 2
        dd = dx * dx + dy * dy
        if dd <= 9:            # core radius 3 -> ~0.8% hot pixels on a 60x60 frame
            return (250, 250, 250)
        if dd <= 81:           # halo radius 4..9
            return (180, 180, 180)
        return (30, 30, 30)

    def test_sharp_scene_no_blur(self):
        path = self.tmp / "sharp.png"
        write_rgb_png(path, 120, 120, self._sharp_scene)
        result = detect_background_blur(path)
        self.assertFalse(result["blurred"], result["reason"])

    def test_shallow_dof_flagged(self):
        path = self.tmp / "dof.png"
        write_rgb_png(path, 120, 120, self._shallow_dof)
        result = detect_background_blur(path)
        self.assertTrue(result["blurred"], result["reason"])
        self.assertLess(result["ratio"], 0.5)

    def test_no_glow_on_flat_image(self):
        path = self.tmp / "flat.png"
        write_rgb_png(path, 60, 60, self._flat_gray)
        result = detect_highlight_glow(path)
        self.assertFalse(result["glow"], result["reason"])

    def test_glow_flagged(self):
        path = self.tmp / "glow.png"
        write_rgb_png(path, 60, 60, self._glow)
        result = detect_highlight_glow(path)
        self.assertTrue(result["glow"], result["reason"])
        self.assertGreater(result["hotFraction"], 0.005)
        self.assertGreater(result["haloFraction"], 0.5)

    def test_recommend_effects_shape(self):
        path = self.tmp / "shape.png"
        write_rgb_png(path, 120, 120, self._sharp_scene)
        result = recommend_effects(path)
        for key in ("dof", "bloom", "blur", "glow"):
            self.assertIn(key, result)


if __name__ == "__main__":
    unittest.main(verbosity=2)