Source: tests/test_mechanism_calibration.py · Plain text

tests/test_mechanism_calibration.py

import numpy as np
import pytest

from mcss.mechanism_pilot.calibration import calibrated_intrinsics


def row(matrix):
    return {f"M_cam_from_uv_{i}{j}": matrix[i][j] for i in range(3) for j in range(3)}


def test_shifted_anisotropic_rays_match_published_formula():
    m = np.array([[0.58, 0.02, 0.09], [0, 0.43, -0.04], [0, 0, -1.0]])
    h, w = 128, 160
    k = calibrated_intrinsics(row(m), (h, w))
    for x, y in [(0, 0), (35, 77), (w - 1, h - 1)]:
        expected = np.diag([1, -1, -1]) @ m @ [2 * (x + 0.5) / w - 1, 1 - 2 * (y + 0.5) / h, 1]
        actual = np.linalg.inv(k) @ [x, y, 1]
        np.testing.assert_allclose(
            actual / np.linalg.norm(actual), expected / np.linalg.norm(expected), atol=1e-12
        )


def test_resize_scales_axes_independently_with_half_pixel_centers():
    m = row([[0.57735, 0, 0], [0, 0.433013, 0], [0, 0, -1]])
    original = calibrated_intrinsics(m, (768, 1024))
    small = calibrated_intrinsics(m, (128, 160))
    assert small[0, 0] == pytest.approx(original[0, 0] * 160 / 1024)
    assert small[1, 1] == pytest.approx(original[1, 1] * 128 / 768)
    assert small[0, 2] == pytest.approx((original[0, 2] + 0.5) * 160 / 1024 - 0.5)
    assert small[0, 0] != pytest.approx(small[1, 1])


def test_invalid_calibration_never_falls_back_to_fov():
    with pytest.raises(ValueError):
        calibrated_intrinsics(row(np.zeros((3, 3))), (128, 160))
    with pytest.raises(KeyError):
        calibrated_intrinsics({}, (128, 160))