From 35b1ac5609164b2cf0cb5b5fc6eaeb37bf0f2f86 Mon Sep 17 00:00:00 2001 From: Bamdad Dashtban Date: Thu, 30 Jul 2026 14:16:42 +0100 Subject: [PATCH 1/2] =?UTF-8?q?feat(viz):=203D=20scene=20viewer=20?= =?UTF-8?q?=E2=80=94=20camera=20locations=20+=20trajectory=20in=20world=20?= =?UTF-8?q?space?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A static 3D world view of a scene manifest: each camera drawn as a view-cone at its calibrated world position, a ground plane, and every entity's ground-truth 3D trajectory. Makes camera coverage and overlap directly visible instead of inferring it from per-camera tiles. Schema-driven, works on any manifest; defaults to the bundled MTMC golden fixture. matplotlib is lazy-imported and headless-safe (Agg), so it is not a package dependency. uv run --with matplotlib python scripts/view_scene_3d.py Featured in the README next to the existing hero renders. --- README.md | 5 + docs/assets/scene_3d.png | Bin 0 -> 93452 bytes scripts/view_scene_3d.py | 207 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+) create mode 100644 docs/assets/scene_3d.png create mode 100644 scripts/view_scene_3d.py diff --git a/README.md b/README.md index a1de056..447a3bf 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,11 @@ the pure-numpy rasterizer, with the object's analytic projected box drawn in every view that sees it. Reproduce: `uv run --with pillow python scripts/render_multiview_hero.py`.* +![A 3D world view of a scene: a translucent ground plane with three cameras drawn as red view-cones at their calibrated world positions, each pointing at the scene, and the object's ground-truth 3D trajectory as a blue polyline crossing the space.](docs/assets/scene_3d.png) + +*The scene in 3D: every camera drawn as a view-cone at its real calibrated world position, the ground plane, and the object's ground-truth trajectory across the frames. +One picture of where the cameras are and what they cover — camera coverage and overlap are visible directly, not inferred from per-camera tiles. Works on any manifest; reproduce: `uv run --with matplotlib python scripts/view_scene_3d.py`.* + ![Three MTMC camera stations with non-overlapping fields of view watch one object cross a corridor on a synced timeline; it hands off from camera 0 to 1 to 2, with blind-gap frames where no camera sees it.](docs/assets/hero_grid.gif) *One object, three cameras with **disjoint** views, one timeline — a green border diff --git a/docs/assets/scene_3d.png b/docs/assets/scene_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..dccd3cfbc88f8aae2bdc41f45b17f3dc8da41f17 GIT binary patch literal 93452 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 PF8Fb>b0$_1{OJD$cAz|* literal 0 HcmV?d00001 diff --git a/scripts/view_scene_3d.py b/scripts/view_scene_3d.py new file mode 100644 index 0000000..476aad3 --- /dev/null +++ b/scripts/view_scene_3d.py @@ -0,0 +1,207 @@ +"""Render a scene manifest as one 3D world view: camera locations + trajectory. + +A single static 3D figure showing where every camera sits in the world (drawn as +a small view-cone / frustum pointing along its optical axis), a ground plane, and +each entity's ground-truth 3D trajectory over the frames. This is the "see the +space" view -- unlike the per-camera tiles of ``record_multiview.py``, it draws +the whole scene once so camera coverage and overlap are directly visible. + +Geometry follows ``multicam_sim.cameras.Camera``: ``R`` is the world->camera +rotation with rows ``[right, down, forward]`` (OpenCV, +z forward) and ``t`` is +the world->camera translation, so the camera centre is ``C = -R^T @ t`` and the +frustum edges are the back-projected image corners ``R^T @ (K^-1 @ [u, v, 1])``. +World up is +z; the ground plane is drawn at z = 0. + +Works on any manifest with the standard schema (``cameras[*].{K,R,t,width, +height}`` and ``entities[*].frames[*].points[*].xyz_gt``); defaults to the +bundled MTMC golden fixture. + +``matplotlib`` is imported lazily inside :func:`main` (it is not a package +dependency), mirroring the lazy-import pattern in ``scripts/record_multiview.py``. +Run:: + + uv run --with matplotlib python scripts/view_scene_3d.py + uv run --with matplotlib python scripts/view_scene_3d.py --manifest PATH --out PATH +""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import TYPE_CHECKING, Any + +import numpy as np + +if TYPE_CHECKING: + from numpy.typing import NDArray + +_ROOT = Path(__file__).resolve().parent.parent +_DEFAULT_MANIFEST = _ROOT / "tests" / "fixtures" / "manifest_golden" / "mtmc.json" +_DEFAULT_OUT = _ROOT / "docs" / "assets" / "scene_3d.png" + +# How far in front of each camera to draw the frustum apex (world units). +_FRUSTUM_DEPTH = 1.2 + + +def _camera_centre( + rotation: NDArray[np.float64], translation: NDArray[np.float64] +) -> NDArray[np.float64]: + """World-space camera centre ``C = -R^T @ t``.""" + return -rotation.T @ translation + + +def _frustum_corners( + intrinsics: NDArray[np.float64], + rotation: NDArray[np.float64], + centre: NDArray[np.float64], + width: float, + height: float, + depth: float, +) -> NDArray[np.float64]: + """The four image-corner rays back-projected to ``depth`` in world space. + + A pixel ``[u, v, 1]`` back-projects to the world ray direction + ``R^T @ (K^-1 @ [u, v, 1])``; scaling so the forward (+z camera) component + equals ``depth`` puts the corner a fixed distance in front of the camera. + """ + inv_k = np.linalg.inv(intrinsics) + corners_px = np.array( + [[0.0, 0.0], [width, 0.0], [width, height], [0.0, height]], + dtype=np.float64, + ) + out = np.empty((4, 3), dtype=np.float64) + for i, (u, v) in enumerate(corners_px): + cam_ray = inv_k @ np.array([u, v, 1.0], dtype=np.float64) + cam_ray = cam_ray / cam_ray[2] * depth # forward (+z) component == depth + out[i] = centre + rotation.T @ cam_ray + return out + + +def _load_manifest(path: Path) -> dict[str, Any]: + with path.open("r", encoding="utf-8") as fh: + data: dict[str, Any] = json.load(fh) + return data + + +def _trajectories(manifest: dict[str, Any]) -> list[tuple[str, NDArray[np.float64]]]: + """Per-(entity, point) ground-truth 3D polylines over the frames.""" + out: list[tuple[str, NDArray[np.float64]]] = [] + for entity in manifest.get("entities", []): + by_point: dict[str, list[list[float]]] = {} + for frame in entity.get("frames", []): + for name, point in frame.get("points", {}).items(): + xyz = point.get("xyz_gt") + if xyz is not None: + by_point.setdefault(name, []).append(list(xyz)) + for name, coords in by_point.items(): + label = entity.get("id", "object") + label = label if name == "center" else f"{label}:{name}" + out.append((str(label), np.asarray(coords, dtype=np.float64))) + return out + + +def render(manifest: dict[str, Any], out_path: Path) -> Path: + """Render the 3D scene view to ``out_path`` (PNG) and return the path.""" + import matplotlib + + matplotlib.use("Agg") # headless-safe: no display needed + import matplotlib.pyplot as plt + + fig = plt.figure(figsize=(9, 7)) + ax = fig.add_subplot(111, projection="3d") + + all_points: list[NDArray[np.float64]] = [] + + # Cameras: centre marker + a wireframe frustum to the four image corners. + for cam in manifest.get("cameras", []): + intrinsics = np.asarray(cam["K"], dtype=np.float64) + rotation = np.asarray(cam["R"], dtype=np.float64) + translation = np.asarray(cam["t"], dtype=np.float64) + centre = _camera_centre(rotation, translation) + corners = _frustum_corners( + intrinsics, + rotation, + centre, + float(cam["width"]), + float(cam["height"]), + _FRUSTUM_DEPTH, + ) + ax.scatter(*centre, color="crimson", s=40, depthshade=False) + ax.text(*centre, f" cam {cam['id']}", color="crimson", fontsize=8) + for corner in corners: + edge = np.vstack([centre, corner]) + ax.plot(edge[:, 0], edge[:, 1], edge[:, 2], color="crimson", linewidth=0.8) + loop = np.vstack([corners, corners[0]]) + ax.plot(loop[:, 0], loop[:, 1], loop[:, 2], color="crimson", linewidth=0.8) + all_points.append(centre[None, :]) + all_points.append(corners) + + # Trajectories: one polyline per entity point. + for label, coords in _trajectories(manifest): + ax.plot( + coords[:, 0], + coords[:, 1], + coords[:, 2], + marker="o", + markersize=3, + linewidth=1.5, + label=f"trajectory: {label}", + ) + all_points.append(coords) + + if not all_points: + raise ValueError("manifest has no cameras or trajectories to draw") + pts = np.vstack(all_points) + + # Ground plane at z = 0 spanning the scene's xy extent. + pad = 1.0 + x_min, y_min = pts[:, 0].min() - pad, pts[:, 1].min() - pad + x_max, y_max = pts[:, 0].max() + pad, pts[:, 1].max() + pad + gx, gy = np.meshgrid( + np.linspace(x_min, x_max, 2), + np.linspace(y_min, y_max, 2), + ) + ax.plot_surface(gx, gy, np.zeros_like(gx), alpha=0.12, color="steelblue") + + ax.set_xlabel("x") + ax.set_ylabel("y") + ax.set_zlabel("z (up)") + ax.set_title("Scene: camera locations and object trajectory") + ax.legend(loc="upper left", fontsize=8) + + # Equal aspect over the combined bounds so directions are not skewed. + span = pts.max(axis=0) - pts.min(axis=0) + span = np.where(span > 0, span, 1.0) + ax.set_box_aspect(tuple(span)) + + out_path.parent.mkdir(parents=True, exist_ok=True) + fig.savefig(out_path, dpi=130, bbox_inches="tight") + plt.close(fig) + return out_path + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--manifest", + type=Path, + default=_DEFAULT_MANIFEST, + help="scene manifest JSON (default: bundled MTMC golden fixture)", + ) + parser.add_argument( + "--out", + type=Path, + default=_DEFAULT_OUT, + help="output PNG path (default: docs/assets/scene_3d.png)", + ) + args = parser.parse_args() + + manifest = _load_manifest(args.manifest) + out_path = render(manifest, args.out) + size = out_path.stat().st_size + print(f"wrote {out_path} ({size} bytes)") + + +if __name__ == "__main__": + main() From 8df404bec617231debe2fc578fc5389c047ac65c Mon Sep 17 00:00:00 2001 From: Bamdad Dashtban Date: Thu, 30 Jul 2026 15:03:37 +0100 Subject: [PATCH 2/2] =?UTF-8?q?feat(scene):=20overlapping-camera=20scenes?= =?UTF-8?q?=20=E2=80=94=20assembly=20line=20+=20left-to-right=20handoff?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two domain-neutral multi-camera scenes with overlapping coverage, both deterministic and covered by tests: - assembly_line: an operator walks five workstations under five cameras with graduated overlap (issue #84); topology + per-station dwell + golden manifest. - handoff_ltr: one object crosses the space left-to-right under four cameras — a left camera that sees it then loses it, two right cameras that pick it up with overlap bands (no near-camera blind gap), and a wide camera off the far-right end looking down the line that sees the object every frame. Both read coverage off the manifest's own per-camera in_view flags. The 3D scene viewer (scripts/view_scene_3d.py) draws either. --- docs/assets/handoff_ltr_3d.png | Bin 0 -> 96168 bytes src/multicam_sim/__init__.py | 4 + src/multicam_sim/assembly_line.py | 149 + src/multicam_sim/handoff_ltr.py | 126 + .../manifest_golden/assembly_line.json | 2938 +++++++++++++++++ tests/test_assembly_line.py | 120 + tests/test_handoff_ltr.py | 115 + tests/test_manifest_golden.py | 8 +- 8 files changed, 3459 insertions(+), 1 deletion(-) create mode 100644 docs/assets/handoff_ltr_3d.png create mode 100644 src/multicam_sim/assembly_line.py create mode 100644 src/multicam_sim/handoff_ltr.py create mode 100644 tests/fixtures/manifest_golden/assembly_line.json create mode 100644 tests/test_assembly_line.py create mode 100644 tests/test_handoff_ltr.py diff --git a/docs/assets/handoff_ltr_3d.png b/docs/assets/handoff_ltr_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..ec7b663e203d488480aa953effcfdaf687e18549 GIT binary patch literal 96168 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

IW?*rI2hk`-a(tVwdE(u3F0v1!e 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 station_5``, pausing (a **dwell**, the operation) at each + station before moving on; + * five **cameras** stand back off the line, one framing each station, aimed so + that adjacent cameras' fields of view overlap over the walkway *between* + stations. + +The overlap is graduated, not universal: while the operator dwells at a station +it is in exactly one camera's view, and while it *transits* between two adjacent +stations it is in view on BOTH covering cameras at once. That two-camera transit +interval is the overlap this scene exists to demonstrate (issue #84) — the +manifest's per-camera ``in_view`` flags record it with no schema change, and a +consumer can triangulate the operator wherever two cameras cover it. + +The operator keeps ONE stable ``entity.id`` throughout, the cross-camera +ground-truth identity a tracker must preserve down the line. The scene carries a +:class:`CameraTopology` whose stations name each workstation's covering camera +and whose directed :class:`TransitEdge` s chain the walk ``station_i -> +station_{i+1}`` (and back) with the transit time between them. + +v1 models the operator as a single point target ("center"), which keeps the +overlap proof unambiguous (one point in view on two cameras) and the manifest +compact; a COCO-17 skeleton operator (as in :mod:`examples.assembly_station`) is +a deliberate future extension, not a gap. +""" + +from __future__ import annotations + +from .cameras import Camera +from .dsl.motion import Path, PathUnion +from .dsl.rig import CameraRig, StationView +from .entities import Entity +from .scene import Scene +from .topology import CameraTopology, Station, TransitEdge + +_WIDTH = 1280 +_HEIGHT_PX = 720 +_FPS = 10.0 + +_NUM_STATIONS = 5 +#: Spacing between adjacent workstations along the walkway (world units, +x). +_STATION_STEP = 3.0 +#: Height of the tracked operator point (torso, world +z). +_OPERATOR_Z = 1.0 +#: Cameras stand back off the line along -y, looking toward the walkway. +_CAM_Y = -4.0 +_CAM_Z = 2.2 +#: Wide-ish FOV so adjacent cameras' cones overlap over the walkway. +_CAM_FOV_DEG = 70.0 + +#: Seconds the operator walks between two adjacent stations. +_WALK_S = 0.5 +#: Seconds the operator dwells (pauses, the operation) at each station. +_DWELL_S = 0.4 + +OPERATOR_ID = "operator-1" +#: Domain-neutral workstation ids down the line. +STATION_IDS = [f"station_{i + 1}" for i in range(_NUM_STATIONS)] + + +def _station_x(index: int) -> float: + """World ``x`` of workstation ``index`` (0-based) along the walkway.""" + return index * _STATION_STEP + + +def _station_views() -> list[StationView]: + """One camera per workstation, standing back off the line and framing that + station. The wide FOV makes adjacent cones overlap over the walkway between + stations, so a transiting operator is seen by two cameras at once.""" + return [ + StationView( + position=(_station_x(i), _CAM_Y, _CAM_Z), + look_at=(_station_x(i), 0.0, _OPERATOR_Z), + fov_deg=_CAM_FOV_DEG, + ) + for i in range(_NUM_STATIONS) + ] + + +def _cameras() -> list[Camera]: + return CameraRig.stations(_station_views(), width=_WIDTH, height_px=_HEIGHT_PX) + + +def _operator_path() -> PathUnion: + """A timed walk ``station_1 -> station_5`` with a dwell at each station. + + Built from the motion DSL: a zero-length ``linear(p, p).over(dwell)`` segment + holds the operator in place for the dwell, chained by ``.then`` with a + ``linear(p_i, p_{i+1}).over(walk)`` transit segment for each leg. The dwell + segments make the operator's position constant across consecutive frames at + each station; the transit segments carry it (and its overlapping two-camera + coverage) between them. + """ + points = [(_station_x(i), 0.0, _OPERATOR_Z) for i in range(_NUM_STATIONS)] + path: PathUnion = Path.linear(points[0], points[0]).over(_DWELL_S) + for i in range(_NUM_STATIONS - 1): + walk = Path.linear(points[i], points[i + 1]).over(_WALK_S) + dwell = Path.linear(points[i + 1], points[i + 1]).over(_DWELL_S) + path = path.then(walk).then(dwell) + return path + + +def _num_frames(path: PathUnion) -> int: + """Frame count covering the whole timed walk at :data:`_FPS`, inclusive.""" + return int(round(path.total_duration() * _FPS)) + 1 + + +def build_assembly_line_scene() -> Scene: + """Construct the deterministic overlapping assembly-line scene. + + Five cameras with overlapping coverage watch one operator walk five + workstations, dwelling at each. Returns a :class:`Scene` carrying the + per-station :class:`CameraTopology` and no occluders. + """ + cameras = _cameras() + + path = _operator_path() + num_frames = _num_frames(path) + frames = path.compile_frames(_FPS, num_frames, name="center") + operator = Entity(id=OPERATOR_ID, frames=frames) + + # Each workstation is covered by its own camera (same index); the walk chains + # station_i <-> station_{i+1} with the transit time between them. + transit_s = _WALK_S + stations = [Station(id=station_id, camera_ids=[i]) for i, station_id in enumerate(STATION_IDS)] + edges: list[TransitEdge] = [] + for i in range(_NUM_STATIONS - 1): + src, dst = STATION_IDS[i], STATION_IDS[i + 1] + edges.append(TransitEdge(src=src, dst=dst, transit_time_s=transit_s)) + edges.append(TransitEdge(src=dst, dst=src, transit_time_s=transit_s)) + topology = CameraTopology(stations=stations, edges=edges) + + return Scene( + fps=_FPS, + num_frames=num_frames, + cameras=cameras, + entities=[operator], + occluders=[], + topology=topology, + ) diff --git a/src/multicam_sim/handoff_ltr.py b/src/multicam_sim/handoff_ltr.py new file mode 100644 index 0000000..d278296 --- /dev/null +++ b/src/multicam_sim/handoff_ltr.py @@ -0,0 +1,126 @@ +"""Left-to-right handoff scene: an object crosses the space, camera to camera. + +A domain-neutral scenario built to show a moving object being handed off across +overlapping cameras as it travels in a straight line from left to right (world +``-x -> +x``): + + * a **left** camera frames the left of the space: the object starts fully in + its view and gradually leaves it as it moves right; + * two **right** cameras frame the middle and right of the space with + overlapping fields of view, so as the object leaves the left camera it + appears first in the middle-right camera and then, over an overlap band, in + both right cameras at once; + * a **wide** camera stands well back and frames the whole line, so it sees the + object on EVERY frame — the always-on reference view. + +The result is a graduated coverage hand-off recorded in the manifest's per-camera +``in_view`` flags with no schema change: the left camera's ``in_view`` falls from +true to false as the object exits, the two right cameras' rise as it enters (with +an overlap band where both are true), and the wide camera is true throughout. The +object keeps ONE stable ``entity.id``, the cross-camera identity a tracker must +preserve across the hand-off. +""" + +from __future__ import annotations + +from .cameras import Camera +from .dsl.motion import Path +from .dsl.rig import CameraRig, StationView +from .entities import Entity +from .scene import Scene +from .topology import CameraTopology, Station, TransitEdge + +_WIDTH = 1280 +_HEIGHT_PX = 720 +_FPS = 10.0 +_NUM_FRAMES = 40 + +#: The object travels this straight line, left to right, at torso height. +_START_X = -8.0 +_END_X = 8.0 +_OBJECT_Y = 0.0 +_OBJECT_Z = 1.0 + +#: Near cameras stand back off the line along -y, looking toward it. +_CAM_Y = -5.0 +_CAM_Z = 1.8 +#: The wide reference camera stands off the FAR RIGHT end of the line and looks +#: down its length toward the far left, so the whole path stays in its frustum. +_WIDE_CAM_X = 13.0 +_WIDE_CAM_Y = -6.0 +_WIDE_CAM_Z = 3.0 + +OBJECT_ID = "object-1" + +#: Camera ids, in declaration order. +CAM_LEFT = 0 +CAM_MID_RIGHT = 1 +CAM_RIGHT = 2 +CAM_WIDE = 3 + + +def _station_views() -> list[StationView]: + """Four cameras: left, middle-right, right, and a wide always-on reference. + + The three near cameras are aimed at successive x-regions of the line with a + moderate FOV so their coverage overlaps in bands; the wide camera sits far + back with a large FOV so the whole line stays inside its frustum every frame. + """ + return [ + # Left camera: frames the left of the line; the object starts here. + StationView(position=(-5.0, _CAM_Y, _CAM_Z), look_at=(-5.0, 0.0, _OBJECT_Z), fov_deg=70.0), + # Middle-right camera: frames the centre; picks the object up while it is + # still in the left camera (an overlap band, no blind gap), overlapping + # both neighbours. + StationView(position=(0.0, _CAM_Y, _CAM_Z), look_at=(0.0, 0.0, _OBJECT_Z), fov_deg=75.0), + # Right camera: frames the right end; overlaps the middle-right camera in + # a band, then holds the object to the end. + StationView(position=(6.0, _CAM_Y, _CAM_Z), look_at=(6.0, 0.0, _OBJECT_Z), fov_deg=60.0), + # Wide reference camera: stands off the FAR RIGHT end and looks down the + # length of the line toward the far left, so the whole left-to-right path + # runs away from it and stays in view every frame. + StationView( + position=(_WIDE_CAM_X, _WIDE_CAM_Y, _WIDE_CAM_Z), + look_at=(_START_X, 0.0, _OBJECT_Z), + fov_deg=90.0, + ), + ] + + +def _cameras() -> list[Camera]: + return CameraRig.stations(_station_views(), width=_WIDTH, height_px=_HEIGHT_PX) + + +def build_handoff_ltr_scene() -> Scene: + """Construct the deterministic left-to-right cross-camera handoff scene.""" + cameras = _cameras() + + start = (_START_X, _OBJECT_Y, _OBJECT_Z) + end = (_END_X, _OBJECT_Y, _OBJECT_Z) + frames = Path.linear(start, end).compile_frames(_FPS, _NUM_FRAMES, name="center") + entity = Entity(id=OBJECT_ID, frames=frames) + + # Topology: three near stations left -> middle-right -> right, plus the wide + # reference station. Directed transit edges chain the left-to-right hand-off. + transit_s = _NUM_FRAMES / _FPS / 3.0 + topology = CameraTopology( + stations=[ + Station(id="left", camera_ids=[CAM_LEFT]), + Station(id="mid_right", camera_ids=[CAM_MID_RIGHT]), + Station(id="right", camera_ids=[CAM_RIGHT]), + Station(id="wide", camera_ids=[CAM_WIDE]), + ], + edges=[ + TransitEdge(src="left", dst="mid_right", transit_time_s=transit_s), + TransitEdge(src="mid_right", dst="right", transit_time_s=transit_s), + ], + ) + + return Scene( + fps=_FPS, + num_frames=_NUM_FRAMES, + cameras=cameras, + entities=[entity], + occluders=[], + topology=topology, + ) diff --git a/tests/fixtures/manifest_golden/assembly_line.json b/tests/fixtures/manifest_golden/assembly_line.json new file mode 100644 index 0000000..3b29e35 --- /dev/null +++ b/tests/fixtures/manifest_golden/assembly_line.json @@ -0,0 +1,2938 @@ +{ + "cameras": [ + { + "id": 0, + "K": [ + [ + 914.0147243149534, + 0.0, + 640.0 + ], + [ + 0.0, + 914.0147243149534, + 360.0 + ], + [ + 0.0, + 0.0, + 1.0 + ] + ], + "R": [ + [ + 1.0, + -0.0, + 0.0 + ], + [ + 0.0, + -0.28734788556634544, + -0.9578262852211513 + ], + [ + 0.0, + 0.9578262852211513, + -0.28734788556634544 + ] + ], + "t": [ + 0.0, + 0.9578262852211512, + 4.463470489130565 + ], + "width": 1280, + "height": 720, + "convention": "opencv_rdf" + }, + { + "id": 1, + "K": [ + [ + 914.0147243149534, + 0.0, + 640.0 + ], + [ + 0.0, + 914.0147243149534, + 360.0 + ], + [ + 0.0, + 0.0, + 1.0 + ] + ], + "R": [ + [ + 1.0, + -0.0, + 0.0 + ], + [ + 0.0, + -0.28734788556634544, + -0.9578262852211513 + ], + [ + 0.0, + 0.9578262852211513, + -0.28734788556634544 + ] + ], + "t": [ + -3.0, + 0.9578262852211512, + 4.463470489130565 + ], + "width": 1280, + "height": 720, + "convention": "opencv_rdf" + }, + { + "id": 2, + "K": [ + [ + 914.0147243149534, + 0.0, + 640.0 + ], + [ + 0.0, + 914.0147243149534, + 360.0 + ], + [ + 0.0, + 0.0, + 1.0 + ] + ], + "R": [ + [ + 1.0, + -0.0, + 0.0 + ], + [ + 0.0, + -0.28734788556634544, + -0.9578262852211513 + ], + [ + 0.0, + 0.9578262852211513, + -0.28734788556634544 + ] + ], + "t": [ + -6.0, + 0.9578262852211512, + 4.463470489130565 + ], + "width": 1280, + "height": 720, + "convention": "opencv_rdf" + }, + { + "id": 3, + "K": [ + [ + 914.0147243149534, + 0.0, + 640.0 + ], + [ + 0.0, + 914.0147243149534, + 360.0 + ], + [ + 0.0, + 0.0, + 1.0 + ] + ], + "R": [ + [ + 1.0, + -0.0, + 0.0 + ], + [ + 0.0, + -0.28734788556634544, + -0.9578262852211513 + ], + [ + 0.0, + 0.9578262852211513, + -0.28734788556634544 + ] + ], + "t": [ + -9.0, + 0.9578262852211512, + 4.463470489130565 + ], + "width": 1280, + "height": 720, + "convention": "opencv_rdf" + }, + { + "id": 4, + "K": [ + [ + 914.0147243149534, + 0.0, + 640.0 + ], + [ + 0.0, + 914.0147243149534, + 360.0 + ], + [ + 0.0, + 0.0, + 1.0 + ] + ], + "R": [ + [ + 1.0, + -0.0, + 0.0 + ], + [ + 0.0, + -0.28734788556634544, + -0.9578262852211513 + ], + [ + 0.0, + 0.9578262852211513, + -0.28734788556634544 + ] + ], + "t": [ + -12.0, + 0.9578262852211512, + 4.463470489130565 + ], + "width": 1280, + "height": 720, + "convention": "opencv_rdf" + } + ], + "fps": 10.0, + "num_frames": 41, + "entities": [ + { + "id": "operator-1", + "frames": [ + { + "frame": 0, + "points": { + "center": { + "xyz_gt": [ + 0.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + -16.600496021019993, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -673.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -1329.8014880630594, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1986.4019840840797, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 1, + "points": { + "center": { + "xyz_gt": [ + 0.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + -16.600496021019993, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -673.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -1329.8014880630594, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1986.4019840840797, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 2, + "points": { + "center": { + "xyz_gt": [ + 0.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + -16.600496021019993, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -673.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -1329.8014880630594, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1986.4019840840797, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 3, + "points": { + "center": { + "xyz_gt": [ + 0.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + -16.600496021019993, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -673.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -1329.8014880630594, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1986.4019840840797, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 4, + "points": { + "center": { + "xyz_gt": [ + 0.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + -16.600496021019993, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -673.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -1329.8014880630594, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1986.4019840840797, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 5, + "points": { + "center": { + "xyz_gt": [ + 0.5999999999999999, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 771.3200992042039, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 114.71960318318396, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -541.880892837836, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -1198.4813888588558, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1855.0818848798758, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 6, + "points": { + "center": { + "xyz_gt": [ + 1.1999999999999997, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 902.6401984084079, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 246.0397023873879, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -410.56079363363204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -1067.1612896546517, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1723.761785675672, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 7, + "points": { + "center": { + "xyz_gt": [ + 1.7999999999999996, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1033.9602976126118, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 377.3598015915918, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -279.2406944294281, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -935.8411904504477, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1592.441686471468, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 8, + "points": { + "center": { + "xyz_gt": [ + 2.4000000000000004, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1165.280396816816, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 508.6799007957961, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -147.92059522522393, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -804.5210912462436, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1461.1215872672637, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 9, + "points": { + "center": { + "xyz_gt": [ + 3.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -673.2009920420397, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1329.8014880630599, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 10, + "points": { + "center": { + "xyz_gt": [ + 3.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -673.2009920420397, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1329.8014880630599, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 11, + "points": { + "center": { + "xyz_gt": [ + 3.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -673.2009920420397, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1329.8014880630599, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 12, + "points": { + "center": { + "xyz_gt": [ + 3.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -673.2009920420397, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1329.8014880630599, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 13, + "points": { + "center": { + "xyz_gt": [ + 3.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 639.9999999999999, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -673.2009920420397, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1329.8014880630599, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 14, + "points": { + "center": { + "xyz_gt": [ + 3.599999999999999, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1427.9205952252235, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 771.3200992042036, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 114.71960318318365, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -541.880892837836, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1198.4813888588562, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 15, + "points": { + "center": { + "xyz_gt": [ + 4.199999999999999, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1559.2406944294275, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 902.6401984084076, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 246.03970238738768, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -410.56079363363193, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -1067.1612896546521, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 16, + "points": { + "center": { + "xyz_gt": [ + 4.800000000000001, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1690.5607936336319, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1033.9602976126123, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 377.35980159159215, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -279.2406944294275, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -935.8411904504477, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 17, + "points": { + "center": { + "xyz_gt": [ + 5.3999999999999995, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1821.8808928378355, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1165.2803968168157, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 508.67990079579573, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -147.92059522522388, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -804.521091246244, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 18, + "points": { + "center": { + "xyz_gt": [ + 6.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1296.60049602102, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 640.0, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -16.600496021019627, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -673.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 19, + "points": { + "center": { + "xyz_gt": [ + 6.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1296.60049602102, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 640.0, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -16.600496021019627, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -673.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 20, + "points": { + "center": { + "xyz_gt": [ + 6.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1296.60049602102, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 640.0, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -16.600496021019627, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -673.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 21, + "points": { + "center": { + "xyz_gt": [ + 6.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1296.60049602102, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 640.0, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -16.600496021019627, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -673.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 22, + "points": { + "center": { + "xyz_gt": [ + 6.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1296.60049602102, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 640.0, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + -16.600496021019627, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -673.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 23, + "points": { + "center": { + "xyz_gt": [ + 6.599999999999998, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2084.521091246243, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1427.9205952252235, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 771.3200992042034, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 114.71960318318375, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -541.8808928378364, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 24, + "points": { + "center": { + "xyz_gt": [ + 7.199999999999998, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2215.8411904504474, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1559.2406944294275, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 902.6401984084074, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 246.0397023873878, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -410.5607936336324, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 25, + "points": { + "center": { + "xyz_gt": [ + 7.799999999999999, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2347.1612896546517, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1690.5607936336316, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1033.9602976126118, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 377.35980159159203, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -279.2406944294281, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 26, + "points": { + "center": { + "xyz_gt": [ + 8.399999999999999, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2478.481388858855, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1821.8808928378355, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1165.2803968168155, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 508.67990079579585, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -147.9205952252243, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 27, + "points": { + "center": { + "xyz_gt": [ + 9.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1953.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 28, + "points": { + "center": { + "xyz_gt": [ + 9.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1953.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 29, + "points": { + "center": { + "xyz_gt": [ + 9.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1953.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 30, + "points": { + "center": { + "xyz_gt": [ + 9.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1953.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 31, + "points": { + "center": { + "xyz_gt": [ + 9.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 1953.2009920420398, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1296.6004960210198, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + -16.60049602102006, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 32, + "points": { + "center": { + "xyz_gt": [ + 9.600000000000001, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2741.121587267264, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 2084.521091246244, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1427.9205952252244, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 771.3200992042046, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + 114.7196031831844, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 33, + "points": { + "center": { + "xyz_gt": [ + 10.2, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 2872.4416864714676, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 2215.841190450448, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1559.240694429428, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 902.6401984084082, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + 246.03970238738802, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 34, + "points": { + "center": { + "xyz_gt": [ + 10.799999999999999, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 3003.7617856756715, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 2347.1612896546512, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1690.5607936336314, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 1033.9602976126118, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + 377.35980159159163, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 35, + "points": { + "center": { + "xyz_gt": [ + 11.399999999999999, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 3135.0818848798754, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 2478.481388858855, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1821.8808928378355, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 1165.2803968168157, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + 508.6799007957956, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 36, + "points": { + "center": { + "xyz_gt": [ + 12.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 3266.40198408408, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 1296.6004960210203, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 37, + "points": { + "center": { + "xyz_gt": [ + 12.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 3266.40198408408, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 1296.6004960210203, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 38, + "points": { + "center": { + "xyz_gt": [ + 12.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 3266.40198408408, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 1296.6004960210203, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 39, + "points": { + "center": { + "xyz_gt": [ + 12.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 3266.40198408408, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 1296.6004960210203, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + } + ] + } + } + }, + { + "frame": 40, + "points": { + "center": { + "xyz_gt": [ + 12.0, + 0.0, + 1.0 + ], + "per_cam": [ + { + "cam": 0, + "uv": [ + 3266.40198408408, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 1, + "uv": [ + 2609.80148806306, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 2, + "uv": [ + 1953.20099204204, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 3, + "uv": [ + 1296.6004960210203, + 360.0 + ], + "in_view": false, + "visible": false, + "occ_frac": 0.0 + }, + { + "cam": 4, + "uv": [ + 640.0000000000001, + 360.0 + ], + "in_view": true, + "visible": true, + "occ_frac": 0.0 + } + ] + } + } + } + ] + } + ], + "topology": { + "stations": [ + { + "id": "station_1", + "camera_ids": [ + 0 + ] + }, + { + "id": "station_2", + "camera_ids": [ + 1 + ] + }, + { + "id": "station_3", + "camera_ids": [ + 2 + ] + }, + { + "id": "station_4", + "camera_ids": [ + 3 + ] + }, + { + "id": "station_5", + "camera_ids": [ + 4 + ] + } + ], + "edges": [ + { + "src": "station_1", + "dst": "station_2", + "transit_time_s": 0.5 + }, + { + "src": "station_2", + "dst": "station_1", + "transit_time_s": 0.5 + }, + { + "src": "station_2", + "dst": "station_3", + "transit_time_s": 0.5 + }, + { + "src": "station_3", + "dst": "station_2", + "transit_time_s": 0.5 + }, + { + "src": "station_3", + "dst": "station_4", + "transit_time_s": 0.5 + }, + { + "src": "station_4", + "dst": "station_3", + "transit_time_s": 0.5 + }, + { + "src": "station_4", + "dst": "station_5", + "transit_time_s": 0.5 + }, + { + "src": "station_5", + "dst": "station_4", + "transit_time_s": 0.5 + } + ] + } +} \ No newline at end of file diff --git a/tests/test_assembly_line.py b/tests/test_assembly_line.py new file mode 100644 index 0000000..456424f --- /dev/null +++ b/tests/test_assembly_line.py @@ -0,0 +1,120 @@ +"""Assembly-line overlapping-coverage scene. + +One operator walks a line of five workstations, dwelling at each, watched by five +cameras with deliberately OVERLAPPING fields of view. Exercises the serialized +contract end to end: build the scene, write the manifest (strict JSON, +``allow_nan=False``), reload it, and assert determinism, the down-the-line +topology, the per-station dwell, and — the point of the scene — that the operator +is ``in_view`` on at least two cameras at once during station-to-station +transits. Overlap is read straight off the manifest's per-camera ``in_view`` +flags (the sim's own projection/visibility), never recomputed here. +""" + +from __future__ import annotations + +import json +import math +from pathlib import Path + +from multicam_sim import build_assembly_line_scene, build_manifest, write_manifest +from multicam_sim.assembly_line import OPERATOR_ID, STATION_IDS + + +def _load(tmp_path: Path) -> dict: + scene = build_assembly_line_scene() + path = tmp_path / "assembly_line.json" + write_manifest(scene, path) + return json.loads(path.read_text()) + + +def _frames(manifest: dict) -> list[dict]: + return manifest["entities"][0]["frames"] + + +def _in_view(frame: dict) -> list[bool]: + return [o["in_view"] for o in frame["points"]["center"]["per_cam"]] + + +def test_manifest_is_strict_finite_json(tmp_path: Path) -> None: + """Every uv is finite — behind/out-of-frame projections are sanitised, so the + manifest is valid strict JSON (no Infinity/NaN) for the consumer.""" + manifest = _load(tmp_path) + for frame in _frames(manifest): + for obs in frame["points"]["center"]["per_cam"]: + assert all(math.isfinite(c) for c in obs["uv"]) + + +def test_deterministic_byte_stable_manifest() -> None: + """The builder is deterministic: two independent builds serialise to the exact + same JSON bytes (no unseeded RNG anywhere in the scene).""" + first = build_manifest(build_assembly_line_scene()).to_json() + second = build_manifest(build_assembly_line_scene()).to_json() + assert first == second + + +def test_visible_implies_in_view(tmp_path: Path) -> None: + """visible == in_view AND unoccluded, so visible is never true where in_view + is false.""" + manifest = _load(tmp_path) + for frame in _frames(manifest): + for obs in frame["points"]["center"]["per_cam"]: + if obs["visible"]: + assert obs["in_view"] + + +def test_operator_in_view_on_two_cameras_simultaneously(tmp_path: Path) -> None: + """The overlap proof: on some frame(s) the operator is in_view on AT LEAST + two cameras at once. Those frames are the station-to-station transits, and the + two covering cameras are always an ADJACENT pair (graduated overlap down the + line, not every camera seeing everything).""" + manifest = _load(tmp_path) + frames = _frames(manifest) + coverage = [sum(_in_view(f)) for f in frames] + + two_cam = [i for i, c in enumerate(coverage) if c >= 2] + assert two_cam, "expected >=2-camera overlap frames during transits" + + # Every overlap frame is covered by exactly an adjacent pair of cameras. + for i in two_cam: + seen = [cam for cam, iv in enumerate(_in_view(frames[i])) if iv] + assert len(seen) == 2, f"frame {i}: expected an adjacent pair, saw {seen}" + assert seen[1] - seen[0] == 1, f"frame {i}: cameras {seen} are not adjacent" + + # It is genuine graduated overlap, not universal: no frame is seen by all cams. + assert max(coverage) < len(manifest["cameras"]) + # The operator is always seen by at least one camera (no blind gap here). + assert min(coverage) >= 1 + + +def test_operator_dwells_at_each_station(tmp_path: Path) -> None: + """The dwell (the operation): the operator holds a constant position across + consecutive frames, once per workstation x.""" + manifest = _load(tmp_path) + xs = [round(f["points"]["center"]["xyz_gt"][0], 6) for f in _frames(manifest)] + + held = [a for a, b in zip(xs[:-1], xs[1:], strict=True) if a == b] + assert held, "expected held (dwell) frames where the operator pauses" + + # A dwell happens at each of the five workstation x positions. + dwell_xs = {x for x, nxt in zip(xs[:-1], xs[1:], strict=True) if x == nxt} + assert len(dwell_xs) == len(STATION_IDS) + + +def test_stable_identity_and_line_topology(tmp_path: Path) -> None: + """One operator with a stable id across every frame; topology emitted with a + station per workstation (its covering camera) and directed transit edges + chaining the line both ways.""" + manifest = _load(tmp_path) + assert len(manifest["entities"]) == 1 + assert manifest["entities"][0]["id"] == OPERATOR_ID + + topo = manifest["topology"] + assert [s["id"] for s in topo["stations"]] == STATION_IDS + by_id = {s["id"]: s["camera_ids"] for s in topo["stations"]} + for i, station_id in enumerate(STATION_IDS): + assert by_id[station_id] == [i] + + pairs = {(e["src"], e["dst"]) for e in topo["edges"]} + for a, b in zip(STATION_IDS[:-1], STATION_IDS[1:], strict=True): + assert (a, b) in pairs and (b, a) in pairs + assert all(e["transit_time_s"] > 0 for e in topo["edges"]) diff --git a/tests/test_handoff_ltr.py b/tests/test_handoff_ltr.py new file mode 100644 index 0000000..a9a74bb --- /dev/null +++ b/tests/test_handoff_ltr.py @@ -0,0 +1,115 @@ +"""Left-to-right cross-camera handoff scene. + +One object crosses the space in a straight line (world ``-x -> +x``) under four +cameras: a LEFT camera that sees it first and loses it, two RIGHT cameras +(mid-right, right) that pick it up as it enters — with overlap bands where two +near cameras see it at once — and a WIDE camera off the far-right end, looking +down the length of the line toward the far left, that sees the object on EVERY +frame. Coverage is read straight off the manifest's per-camera ``in_view`` flags +(the sim's own projection/visibility), never recomputed here. +""" + +from __future__ import annotations + +import json +import math +from pathlib import Path + +from multicam_sim import build_handoff_ltr_scene, build_manifest, write_manifest +from multicam_sim.handoff_ltr import ( + CAM_LEFT, + CAM_MID_RIGHT, + CAM_RIGHT, + CAM_WIDE, + OBJECT_ID, +) + + +def _load(tmp_path: Path) -> dict: + scene = build_handoff_ltr_scene() + path = tmp_path / "handoff_ltr.json" + write_manifest(scene, path) + return json.loads(path.read_text()) + + +def _frames(manifest: dict) -> list[dict]: + return manifest["entities"][0]["frames"] + + +def _in_view(frame: dict) -> list[bool]: + return [o["in_view"] for o in frame["points"]["center"]["per_cam"]] + + +def test_deterministic_byte_stable_manifest() -> None: + """Two independent builds serialise to the exact same JSON bytes.""" + first = build_manifest(build_handoff_ltr_scene()).to_json() + second = build_manifest(build_handoff_ltr_scene()).to_json() + assert first == second + + +def test_manifest_is_strict_finite_json(tmp_path: Path) -> None: + """Every projected uv is finite (valid strict JSON, no Infinity/NaN).""" + manifest = _load(tmp_path) + for frame in _frames(manifest): + for obs in frame["points"]["center"]["per_cam"]: + assert all(math.isfinite(c) for c in obs["uv"]) + + +def test_object_moves_left_to_right(tmp_path: Path) -> None: + """The object's world x is monotonically non-decreasing across the frames.""" + manifest = _load(tmp_path) + xs = [f["points"]["center"]["xyz_gt"][0] for f in _frames(manifest)] + assert xs[0] < xs[-1], "object should travel toward +x" + assert all(b >= a for a, b in zip(xs[:-1], xs[1:], strict=True)) + + +def test_wide_camera_sees_object_every_frame(tmp_path: Path) -> None: + """The far-right wide camera (looking down the line to the far left) is the + always-on reference: the object is in_view on it on EVERY frame.""" + manifest = _load(tmp_path) + frames = _frames(manifest) + assert all(_in_view(f)[CAM_WIDE] for f in frames) + + +def test_left_camera_sees_then_loses_the_object(tmp_path: Path) -> None: + """The LEFT camera sees the object at the start and loses it once the object + has moved right (a true->false transition, and it does not come back).""" + manifest = _load(tmp_path) + seen = [_in_view(f)[CAM_LEFT] for f in _frames(manifest)] + assert seen[0], "left camera should see the object at the start" + assert not seen[-1], "left camera should have lost the object by the end" + # One contiguous seen-then-gone run: after the first drop it never returns. + last_seen = max(i for i, v in enumerate(seen) if v) + assert all(not v for v in seen[last_seen + 1 :]) + assert all(seen[: last_seen + 1]), "left coverage is one contiguous run" + + +def test_right_cameras_pick_the_object_up(tmp_path: Path) -> None: + """The two RIGHT cameras enter after the start (the object is NOT in either at + frame 0) and hold it at the end, and the right camera is the final holder.""" + manifest = _load(tmp_path) + frames = _frames(manifest) + first = _in_view(frames[0]) + last = _in_view(frames[-1]) + assert not first[CAM_MID_RIGHT] and not first[CAM_RIGHT], ( + "right cameras should not yet see the object at the start" + ) + assert last[CAM_RIGHT], "the right camera should hold the object at the end" + + +def test_handoff_has_overlap_and_no_near_camera_blind_gap(tmp_path: Path) -> None: + """The handoff is smooth: on some frames two NEAR cameras (left/mid/right, not + the wide reference) see the object at once (overlap bands), and there is never + a frame where NO near camera sees it (no blind gap in the near coverage).""" + manifest = _load(tmp_path) + near = (CAM_LEFT, CAM_MID_RIGHT, CAM_RIGHT) + near_counts = [sum(_in_view(f)[c] for c in near) for f in _frames(manifest)] + assert max(near_counts) >= 2, "expected an overlap band of >=2 near cameras" + assert min(near_counts) >= 1, "no near-camera blind gap along the path" + + +def test_stable_identity(tmp_path: Path) -> None: + """One object with a stable id across every frame.""" + manifest = _load(tmp_path) + assert len(manifest["entities"]) == 1 + assert manifest["entities"][0]["id"] == OBJECT_ID diff --git a/tests/test_manifest_golden.py b/tests/test_manifest_golden.py index 86092e9..cd871af 100644 --- a/tests/test_manifest_golden.py +++ b/tests/test_manifest_golden.py @@ -21,7 +21,12 @@ import pytest -from multicam_sim import build_manifest, build_mtmc_scene, build_smoke_scene +from multicam_sim import ( + build_assembly_line_scene, + build_manifest, + build_mtmc_scene, + build_smoke_scene, +) from multicam_sim.scene import Scene _FIXTURES = Path(__file__).parent / "fixtures" / "manifest_golden" @@ -67,6 +72,7 @@ def _same_shape(got: object, ref: object, path: str = "") -> None: ("smoke", build_smoke_scene), ("mtmc", build_mtmc_scene), ("assembly", _assembly_scene), + ("assembly_line", build_assembly_line_scene), ], ) def test_manifest_json_matches_golden(name: str, scene_factory: object) -> None: