Project_Demo / tests /test_showcase_drawing.py
steveyehtw's picture
Preserve air-drawing canvas across browser webcam resolution changes
30230a7
Raw History Blame Contribute Delete
2.5 kB
import runpy
import sys
import types
import unittest
from pathlib import Path
from unittest.mock import Mock, patch
import cv2
import numpy as np
class ShowcaseDrawingTests(unittest.TestCase):
def test_webcam_resolution_changes_preserve_drawing_without_add_error(self):
# The runner's waiting frame is 640x480; browser webcam frames are 480x360.
shapes = [(480, 640, 3), (480, 640, 3), (360, 480, 3), (480, 640, 3), (640, 480, 3)]
camera = Mock()
camera.read.side_effect = [(True, np.zeros(shape, dtype=np.uint8)) for shape in shapes] + [(False, None)]
landmarks = [types.SimpleNamespace(x=0.25, y=0.7) for _ in range(21)]
landmarks[8].y = 0.3
landmarks[12].y = 0.8
detector = Mock()
detector.detect.side_effect = [
types.SimpleNamespace(hand_landmarks=[landmarks]),
*[types.SimpleNamespace(hand_landmarks=[]) for _ in shapes[1:]],
]
mp = types.ModuleType("mediapipe")
tasks = types.ModuleType("mediapipe.tasks")
python = types.ModuleType("mediapipe.tasks.python")
vision = types.ModuleType("mediapipe.tasks.python.vision")
mp.Image = Mock()
mp.ImageFormat = types.SimpleNamespace(SRGB=1)
python.BaseOptions = Mock()
vision.HandLandmarkerOptions = Mock()
vision.HandLandmarker = types.SimpleNamespace(create_from_options=Mock(return_value=detector))
mp.tasks, tasks.python, python.vision = tasks, python, vision
modules = {module.__name__: module for module in (mp, tasks, python, vision)}
displayed = []
script = Path(__file__).resolve().parents[1] / "projects/DEMO/展示用學生/03_手指空中畫畫/draw_game_student.py"
with patch.dict(sys.modules, modules), \
patch.object(cv2, "VideoCapture", return_value=camera), \
patch.object(cv2, "imshow", side_effect=lambda title, frame: displayed.append(frame.copy())), \
patch.object(cv2, "waitKey", return_value=-1), \
patch.object(cv2, "destroyAllWindows"):
runpy.run_path(str(script), run_name="__main__")
self.assertEqual([frame.shape for frame in displayed], shapes)
self.assertTrue(all(frame.dtype == np.uint8 for frame in displayed))
self.assertTrue(all(np.any(frame) for frame in displayed), "Existing drawing must survive size changes")
camera.release.assert_called_once()
if __name__ == "__main__":
unittest.main()