test: raw frameset, frameset_seq, calibration keys, host-align comparison

On the fake camera: /api/raw/latest holds color and depth of one frameset
(frame number in the pixels), waits with after=N and times out with 504,
shares its color JPEG with the color channel; /api/capture's frameset_seq;
/api/intrinsics has sizes, models and depth_scale_m; compare_depths counts
and differences; the comparison script end to end through the API with
identical geometry (median |diff| 0, > 90% exact: rs.align itself changes
~3% of the fake's pure-noise depth where pixel footprints overlap).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
OliviaCandClaude Opus 5.5 committed 2026-10-01 10:14:55 +02:00
1 parent 23299001f5
commit 5165d77dfc
1 file changed
+119
+119
View File
@@ -0,0 +1,119 @@
"""Raw frameset endpoint, frameset_seq, full calibration and the host-align comparison, on the fake camera."""
import base64
import importlib.util
from pathlib import Path
import cv2
import numpy as np
import pytest
pytest.importorskip("pyrealsense2")
from starlette.testclient import TestClient # noqa: E402
from src.backend.api import routes, websocket # noqa: E402
from src.backend.main import app # noqa: E402
from src.backend.services.camera import (CameraExtrinsics, CameraIntrinsics, Distortion, # noqa: E402
RealSenseD435)
from tests.fake_realsense import FakeAlign, FakePipeline, frame_number_of_color, open_fake_camera # noqa: E402
SCRIPT = Path(__file__).resolve().parent.parent / "scripts" / "compare_host_align.py"
def _load_script():
spec = importlib.util.spec_from_file_location("compare_host_align", SCRIPT)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def _identity_calibration(cam):
"""Same intrinsics for both streams, identity extrinsics: host align must reproduce the depth."""
cam.intrinsics = CameraIntrinsics(610.0, 610.0, 320.0, 240.0, 610.0, 610.0, 320.0, 240.0)
cam.distortion_ir = cam.distortion_rgb = Distortion(0, 0, 0, 0, 0)
cam.extrinsics = CameraExtrinsics(rotation=(1, 0, 0, 0, 1, 0, 0, 0, 1), translation=(0.0, 0.0, 0.0))
cam.stream_sizes = {"ir": (640, 480), "rgb": (640, 480)}
cam.distortion_models = {"ir": "brown_conrady", "rgb": "brown_conrady"}
@pytest.fixture
def client():
cam = RealSenseD435()
open_fake_camera(cam, FakePipeline(fps=30), FakeAlign(delay_s=0.0))
_identity_calibration(cam)
routes.set_camera(cam)
websocket.set_camera(cam)
yield TestClient(app)
cam.close()
routes.set_camera(None)
websocket.set_camera(None)
def _decode(b64: str, flags: int) -> np.ndarray:
return cv2.imdecode(np.frombuffer(base64.b64decode(b64), np.uint8), flags)
def test_raw_frameset_holds_color_and_depth_of_one_frameset(client):
data = client.get("/api/raw/latest").json()["data"]
color = _decode(data["color_jpeg_b64"], cv2.IMREAD_COLOR)
depth = _decode(data["depth_png_b64"], cv2.IMREAD_UNCHANGED)
assert color.shape == tuple(data["color_shape"]) and depth.shape == tuple(data["depth_shape"])
assert depth.dtype == np.uint16 and data["depth_units"] == "mm"
assert frame_number_of_color(color) == int(depth[0, 0]) % 256 # one frameset
assert {"frameset_seq", "camera_timestamp_ms", "timestamp_domain", "host_timestamp"} <= set(data)
def test_raw_frameset_waits_for_a_newer_one_and_times_out(client):
seq = client.get("/api/raw/latest").json()["data"]["frameset_seq"]
newer = client.get("/api/raw/latest", params={"after": seq, "timeout_ms": 1000}).json()["data"]
assert newer["frameset_seq"] > seq
assert client.get("/api/raw/latest", params={"after": seq + 10_000, "timeout_ms": 50}).status_code == 504
def test_raw_and_color_channel_share_the_color_jpeg(client):
"""The raw payload's color JPEG is the color channel's encoding of that frameset (encoded once)."""
data = client.get("/api/raw/latest").json()["data"]
shared = [enc for enc in routes._encoded_colors if enc.seq == data["frameset_seq"]]
assert len(shared) == 1
assert base64.b64decode(data["color_jpeg_b64"]) == shared[0].jpeg()
def test_capture_carries_the_frameset_seq_of_its_frameset(client):
capture = client.get("/api/capture").json()["data"]
assert capture["frameset_seq"] >= 1
color = _decode(capture["rgb_jpeg_b64"], cv2.IMREAD_COLOR)
depth = _decode(capture["depth_png_b64"], cv2.IMREAD_UNCHANGED)
assert frame_number_of_color(color) == int(depth[0, 0]) % 256
def test_intrinsics_have_what_an_external_align_needs(client):
data = client.get("/api/intrinsics").json()["data"]
for stream in ("ir", "rgb"):
assert {"fx", "fy", "cx", "cy", "distortion", "width", "height", "model"} <= set(data[stream])
assert data["depth_scale_m"] == pytest.approx(0.001)
assert len(data["extrinsics_ir_to_rgb"]["rotation"]) == 9
def test_compare_depths_counts_and_differences():
cha = _load_script()
pc2 = np.array([[100, 0], [300, 400]], np.uint16)
host = np.array([[100, 200], [0, 410]], np.uint16)
result = cha.compare_depths(pc2, host)
assert (result["valid_both"], result["only_pc2"], result["only_host"]) == (2, 1, 1)
assert result["abs_diff_mm"]["max"] == 10 and result["equal_fraction_of_valid_both"] == 0.5
def test_comparison_script_end_to_end_on_the_fake_camera(client):
"""With identical geometry the host align reproduces the PC2 ("fake align" = identity) depth.
Not every pixel: rs.align splats each depth pixel's footprint and keeps the
nearest where they overlap, which on the fake's pure-noise depth changes ~3%.
"""
cha = _load_script()
calibration = cha._data(client.get("/api/intrinsics"))
with cha.HostAligner(calibration) as aligner:
result = cha.compare_one(client, aligner, tries=20)
assert result["valid_both"] > 0.9 * result["pixels"]
assert result["abs_diff_mm"]["median"] == 0
assert result["equal_fraction_of_valid_both"] > 0.9