"""SHM round-trip for portrait daemon with a fake mask.""" import time import numpy as np from frame_shm import LatestFrameReader, LatestFrameWriter, wait_for_ready from portrait import bgr_to_i420, i420_nbytes, i420_to_bgr, person_present from portrait_daemon import CamSlot, tick_once def test_tick_blurs_bg_and_keeps_person(tmp_path): w, h = 64, 48 bgr = np.zeros((h, w, 3), dtype=np.uint8) bgr[::3, :] = 255 bgr[:, ::3] = 255 bgr[8:40, 16:48] = (20, 200, 20) payload = bgr_to_i420(bgr) src = tmp_path / "raw" / "cam-01.i420" dst = tmp_path / "por" / "cam-01.i420" writer = LatestFrameWriter(str(src), w, h) writer.write(payload) mask = np.zeros((h, w), dtype=np.float32) mask[8:40, 16:48] = 1.0 def infer(_bgr): return mask slot = CamSlot( identity="cam-01", width=w, height=h, reader=LatestFrameReader(str(src)), writer=LatestFrameWriter(str(dst), w, h), infer_hz=30.0, hold_s=0.8, blur_px=9, ) n = tick_once([slot], infer, time.monotonic(), infer_budget_s=0.05) assert n == 1 out_r = LatestFrameReader(str(dst)) buf = bytearray(i420_nbytes(w, h)) seq = out_r.copy_into(buf) assert seq == 1 out = i420_to_bgr(buf, w, h) roi = out[12:36, 20:44] assert abs(int(roi[:, :, 1].mean()) - 200) < 25 bg = out[0:6, :] assert float(bg.var()) < float(bgr[0:6, :].var()) * 0.6 def test_tick_blurs_when_empty(tmp_path): w, h = 32, 32 bgr = np.zeros((h, w, 3), dtype=np.uint8) bgr[::3, :] = 255 bgr[:, ::3] = 255 payload = bgr_to_i420(bgr) src = tmp_path / "raw" / "cam-02.i420" dst = tmp_path / "por" / "cam-02.i420" LatestFrameWriter(str(src), w, h).write(payload) def infer(_bgr): return np.zeros((h, w), dtype=np.float32) slot = CamSlot( identity="cam-02", width=w, height=h, reader=LatestFrameReader(str(src)), writer=LatestFrameWriter(str(dst), w, h), infer_hz=30.0, hold_s=0.2, blur_px=9, ) tick_once([slot], infer, time.monotonic(), infer_budget_s=0.05) buf = bytearray(i420_nbytes(w, h)) assert LatestFrameReader(str(dst)).copy_into(buf) == 1 y0 = np.frombuffer(payload, dtype=np.uint8, count=w * h).reshape(h, w) y1 = np.frombuffer(buf, dtype=np.uint8, count=w * h).reshape(h, w) assert float(y1.var()) < float(y0.var()) * 0.6 assert person_present(np.zeros((h, w), dtype=np.float32)) is False def test_wait_ready_helper(tmp_path): p = tmp_path / "ready" assert wait_for_ready(str(p), timeout=0.05) is False p.write_text("ok\n") assert wait_for_ready(str(p), timeout=0.2) is True