feat(v1): chinese screenshot labels via Pillow with ASCII fallback

annotate_frame draws Chinese labels (e.g. '确认摔倒 P-0001') using a CJK
font via Pillow when available (Windows uses Microsoft YaHei), and falls
back to the ASCII cv2 label when Pillow or a CJK font is missing. 86 tests
pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ila
2026-07-22 00:10:07 +08:00
co-authored by Claude Opus 4.8
parent c5e4d87b42
commit 8b33f61112
6 changed files with 129 additions and 9 deletions
+35
View File
@@ -4,12 +4,16 @@ from datetime import datetime, timezone
import numpy as np
import pytest
import os
from v1.alerts import (
AlertDispatcher,
AlertSink,
EventArtifactWriter,
annotate_frame,
annotation_label,
screenshot_label,
_find_font,
)
from v1.fall_state import FallEvent, FallState
from v1.view_model import MonitorViewState, PersonOverlay, Point, StatusColor
@@ -141,3 +145,34 @@ def test_annotate_draws_red_border_only_for_confirmed():
corner = confirmed[0, 0].tolist()
assert corner == [40, 40, 198] # critical red in BGR
assert confirmed.shape == image.shape
def test_annotation_label_is_chinese():
assert annotation_label("P-0001", FallState.CONFIRMED) == "确认摔倒 P-0001"
def test_find_font_returns_none_when_missing_and_path_when_present(tmp_path):
assert _find_font("/no/such/font.ttf") is None
font = tmp_path / "x.ttf"
font.write_bytes(b"stub")
assert _find_font(str(font)) == str(font)
def test_annotate_falls_back_without_a_font():
image = np.full((60, 80, 3), 30, dtype=np.uint8)
out = annotate_frame(image, _confirmed_view(), font_path="/no/such/font.ttf")
assert out.shape == image.shape # ASCII fallback ran, no crash
def test_annotate_draws_labels_with_a_ttf_font():
font = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
if not os.path.isfile(font):
import pytest
pytest.skip("no ttf available to exercise the PIL path")
out = annotate_frame(np.full((60, 80, 3), 30, dtype=np.uint8), _confirmed_view(), font_path=font)
assert out.shape == (60, 80, 3)