181 lines
5.6 KiB
Python
181 lines
5.6 KiB
Python
from pathlib import Path
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
import orisys
|
|
from orisys.finger import TactileProcessor, load_finger_export_bundle, resolve_export_paths
|
|
from orisys.finger.exports import DEFAULT_FINGER_MAP_CACHE
|
|
from orisys.finger.runtime import resolve_finger_geometry
|
|
|
|
|
|
def _touch_bundle(root: Path):
|
|
for name in ("mesh.npz", "camera_intrinsics.npz", "world_to_cam.npy"):
|
|
(root / name).write_bytes(b"")
|
|
|
|
|
|
def test_resolve_export_paths_returns_expected_bundle(tmp_path):
|
|
_touch_bundle(tmp_path)
|
|
|
|
bundle = resolve_export_paths(tmp_path)
|
|
|
|
assert bundle.export_dir == tmp_path.resolve()
|
|
assert bundle.mesh.name == "mesh.npz"
|
|
assert bundle.intrinsics.name == "camera_intrinsics.npz"
|
|
assert bundle.pose.name == "world_to_cam.npy"
|
|
|
|
|
|
def test_load_finger_export_bundle_rehomes_default_map_cache(tmp_path, monkeypatch):
|
|
_touch_bundle(tmp_path)
|
|
|
|
import orisys.finger.exports as exports_mod
|
|
|
|
monkeypatch.setattr(
|
|
exports_mod,
|
|
"load_exported_data",
|
|
lambda *args: {"K": np.eye(3), "width": 1280, "height": 720},
|
|
)
|
|
monkeypatch.setattr(exports_mod, "compute_uv_distortion_metrics", lambda data: {"ok": True})
|
|
monkeypatch.setattr(exports_mod, "recommend_edge_expand", lambda _: 1.2)
|
|
|
|
bundle = load_finger_export_bundle(
|
|
tmp_path,
|
|
map_cache=DEFAULT_FINGER_MAP_CACHE,
|
|
source_scale=1.0,
|
|
)
|
|
|
|
assert Path(bundle.map_cache) == (tmp_path / "unroll_map_uv.npz").resolve()
|
|
assert bundle.edge_expand == 1.2
|
|
|
|
|
|
def test_resolve_finger_geometry_uses_config_defaults(tmp_path, monkeypatch):
|
|
_touch_bundle(tmp_path)
|
|
|
|
import orisys.finger.exports as exports_mod
|
|
import orisys.finger.runtime as runtime_mod
|
|
|
|
monkeypatch.setattr(
|
|
runtime_mod,
|
|
"load_config",
|
|
lambda _: {"camera": {"resolution_stitch": [280, 300], "source_scale": 0.4}},
|
|
)
|
|
monkeypatch.setattr(
|
|
exports_mod,
|
|
"load_exported_data",
|
|
lambda *args: {"K": np.eye(3), "width": 1280, "height": 720},
|
|
)
|
|
monkeypatch.setattr(exports_mod, "compute_uv_distortion_metrics", lambda data: {"ok": True})
|
|
monkeypatch.setattr(exports_mod, "recommend_edge_expand", lambda _: 1.2)
|
|
|
|
geometry = resolve_finger_geometry(
|
|
export_dir=tmp_path,
|
|
config="dd02-ov",
|
|
)
|
|
|
|
assert geometry.out_width == 280
|
|
assert geometry.out_height == 300
|
|
assert geometry.source_scale == 0.4
|
|
assert geometry.source_width == 512
|
|
assert geometry.source_height == 288
|
|
assert Path(geometry.map_cache) == (tmp_path / "unroll_map_uv_s0.4.npz").resolve()
|
|
|
|
|
|
def test_default_map_cache_rehomes_to_resolved_export_dir(tmp_path, monkeypatch):
|
|
_touch_bundle(tmp_path)
|
|
|
|
import orisys.finger.exports as exports_mod
|
|
import orisys.finger.runtime as runtime_mod
|
|
|
|
monkeypatch.setattr(
|
|
runtime_mod,
|
|
"load_config",
|
|
lambda _: {"camera": {"resolution_stitch": [280, 300], "source_scale": 1.0}},
|
|
)
|
|
monkeypatch.setattr(
|
|
exports_mod,
|
|
"load_exported_data",
|
|
lambda *args: {"K": np.eye(3), "width": 1280, "height": 720},
|
|
)
|
|
monkeypatch.setattr(exports_mod, "compute_uv_distortion_metrics", lambda data: {"ok": True})
|
|
monkeypatch.setattr(exports_mod, "recommend_edge_expand", lambda _: 1.2)
|
|
|
|
geometry = resolve_finger_geometry(
|
|
export_dir=tmp_path,
|
|
config="dd02-ov",
|
|
map_cache=DEFAULT_FINGER_MAP_CACHE,
|
|
)
|
|
|
|
assert Path(geometry.map_cache) == (tmp_path / "unroll_map_uv.npz").resolve()
|
|
|
|
|
|
def test_orisys_root_exports_finger_module():
|
|
assert hasattr(orisys, "finger")
|
|
|
|
|
|
def test_tactile_processor_push_frame_uses_default_valid_mask():
|
|
class DummySensor:
|
|
info = object()
|
|
|
|
def __init__(self):
|
|
self.calls = []
|
|
self.frame = None
|
|
self.img = None
|
|
self.flow = None
|
|
self.vnormal = None
|
|
self.vshear = None
|
|
self.depth_map = None
|
|
self.mask_stats = {}
|
|
self.valid_mask = None
|
|
|
|
def get_img(self, **kwargs):
|
|
self.calls.append(kwargs)
|
|
self.frame = kwargs["frame"]
|
|
self.valid_mask = kwargs["valid_mask"]
|
|
return "ok"
|
|
|
|
sensor = DummySensor()
|
|
default_mask = np.array([[True, False], [False, True]])
|
|
tactile = TactileProcessor(sensor, default_valid_mask=default_mask)
|
|
frame = np.zeros((2, 2), dtype=np.uint8)
|
|
|
|
result = tactile.push_frame(frame, already_gray=True)
|
|
|
|
assert result == "ok"
|
|
assert sensor.calls[0]["frame"] is frame
|
|
assert sensor.calls[0]["already_processed"] is True
|
|
assert sensor.calls[0]["already_gray"] is True
|
|
assert sensor.calls[0]["valid_mask"] is default_mask
|
|
|
|
|
|
def test_finger_runtime_get_img_returns_none_on_capture_failure():
|
|
from orisys.finger.runtime import FingerRuntime
|
|
|
|
runtime = object.__new__(FingerRuntime)
|
|
runtime.grab_and_process = lambda *, color=False: (False, None)
|
|
assert runtime.get_img() is None
|
|
|
|
|
|
def test_finger_runtime_get_img_returns_unrolled_frame_on_success():
|
|
from orisys.finger.runtime import FingerRuntime
|
|
|
|
frame = np.zeros((2, 2), dtype=np.uint8)
|
|
runtime = object.__new__(FingerRuntime)
|
|
runtime.grab_and_process = lambda *, color=False: (True, frame)
|
|
assert runtime.get_img(color=True) is frame
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"video,expected",
|
|
[
|
|
("0", 0),
|
|
(" 1 ", 1),
|
|
(r".\data\dd02\0607_1.mp4" + "\\", r".\data\dd02\0607_1.mp4"),
|
|
(0, 0),
|
|
("./clip.mp4", "./clip.mp4"),
|
|
],
|
|
)
|
|
def test_normalize_video_source(video, expected):
|
|
from orisys.finger.runtime import normalize_video_source
|
|
|
|
assert normalize_video_source(video) == expected
|