import pytest import numpy as np from dodgeballtracker.metadata import (VideoMetadata, KnownImagePoint, BirdViewPoint, KnownPoint) @pytest.fixture def simple_transformation_matrix() -> np.matrix: m = np.matrix([[2, 1], [1, 1]]) assert np.linalg.det(m) > 0.1 return m def create_know_point(v, m) -> KnownPoint: u = (m @ v).A[0] return KnownPoint(image=KnownImagePoint.from_vec(v), bird_view=BirdViewPoint.from_vec(u)) @pytest.fixture def four_known_points(simple_transformation_matrix: np.matrix) -> list[ KnownPoint]: return [ create_know_point([x, y], simple_transformation_matrix) for x in [-100, 100] for y in [-100, 100] ] @pytest.fixture def eight_known_points(simple_transformation_matrix: np.matrix, four_known_points: list[KnownPoint]) -> list[KnownPoint]: return [ create_know_point([x, y], simple_transformation_matrix) for x in [-50, 50] for y in [-50, 50] ] + four_known_points @pytest.fixture def simple_video_metadata(four_known_points) -> VideoMetadata: return VideoMetadata(knownPoints=four_known_points) @pytest.fixture def mega_video_metadata(eight_known_points) -> VideoMetadata: return VideoMetadata(knownPoints=eight_known_points) @pytest.fixture def broken_video_metadata(four_known_points) -> VideoMetadata: return VideoMetadata(knownPoints=four_known_points[:2]) def test_get_view_perspective_matrix(simple_video_metadata: VideoMetadata) -> None: m = simple_video_metadata.get_view_perspective_matrix() expt = np.array([ [200, 100, 0], [100, 100, 0], [0, 0, 1] ]) np.testing.assert_array_almost_equal(m, expt) @pytest.mark.xfail def test_get_view_perspective_matrix_mega(mega_video_metadata: VideoMetadata) -> None: """ The issue with this test is that the transformation matrix can only be computed is there's exactly 4 known points. Obviously, in the real world we want more known points and find a way to get a better estimate. """ m = mega_video_metadata.get_view_perspective_matrix() expt = np.array([ [200, 100, 0], [100, 100, 0], [0, 0, 1] ]) np.testing.assert_array_almost_equal(m, expt) def test_get_view_perspective_matrix_without_enough_data(broken_video_metadata: VideoMetadata) -> None: m = broken_video_metadata.get_view_perspective_matrix() assert m is None