fix(studio): harden runtime integration and dependency defaults
Stabilize studio publish/visualization flow and tighten export behavior while aligning project dependencies with the monorepo runtime expectations.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
import copy
|
||||
from contextlib import suppress
|
||||
import inspect
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import time
|
||||
@@ -146,6 +148,8 @@ class ScoliosisPipeline:
|
||||
_visualizer: OpenCVVisualizer | None
|
||||
_last_viz_payload: _VizPayload | None
|
||||
_frame_pacer: _FramePacer | None
|
||||
_visualizer_accepts_pose_data: bool | None
|
||||
_visualizer_signature_owner: object | None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -205,6 +209,31 @@ class ScoliosisPipeline:
|
||||
self._visualizer = None
|
||||
self._last_viz_payload = None
|
||||
self._frame_pacer = _FramePacer(target_fps) if target_fps is not None else None
|
||||
self._visualizer_accepts_pose_data = None
|
||||
self._visualizer_signature_owner = None
|
||||
|
||||
def _detect_visualizer_pose_kwarg(self) -> bool:
|
||||
visualizer = self._visualizer
|
||||
if visualizer is None:
|
||||
return False
|
||||
if (
|
||||
self._visualizer_signature_owner is visualizer
|
||||
and self._visualizer_accepts_pose_data is not None
|
||||
):
|
||||
return self._visualizer_accepts_pose_data
|
||||
update_fn = getattr(visualizer, "update", None)
|
||||
if update_fn is None or not callable(update_fn):
|
||||
self._visualizer_signature_owner = visualizer
|
||||
self._visualizer_accepts_pose_data = False
|
||||
return False
|
||||
try:
|
||||
signature = inspect.signature(update_fn)
|
||||
accepts_pose_data = "pose_data" in signature.parameters
|
||||
except (ValueError, TypeError):
|
||||
accepts_pose_data = False
|
||||
self._visualizer_signature_owner = visualizer
|
||||
self._visualizer_accepts_pose_data = accepts_pose_data
|
||||
return accepts_pose_data
|
||||
|
||||
@staticmethod
|
||||
def _extract_int(meta: dict[str, object], key: str, fallback: int) -> int:
|
||||
@@ -459,7 +488,7 @@ class ScoliosisPipeline:
|
||||
viz_payload = None
|
||||
try:
|
||||
viz_payload = self.process_frame(frame_u8, metadata)
|
||||
except (RuntimeError, ValueError, TypeError, OSError) as frame_error:
|
||||
except (RuntimeError, ValueError, OSError) as frame_error:
|
||||
logger.warning(
|
||||
"Skipping frame %d due to processing error: %s",
|
||||
frame_idx,
|
||||
@@ -474,6 +503,9 @@ class ScoliosisPipeline:
|
||||
viz_payload_dict = cast(_VizPayload, viz_payload)
|
||||
cached: _VizPayload = {}
|
||||
for k, v in viz_payload_dict.items():
|
||||
if k == "pose" and isinstance(v, dict):
|
||||
cached[k] = cast(dict[str, object], copy.deepcopy(v))
|
||||
continue
|
||||
copy_method = cast(
|
||||
Callable[[], object] | None, getattr(v, "copy", None)
|
||||
)
|
||||
@@ -531,8 +563,7 @@ class ScoliosisPipeline:
|
||||
confidence = None
|
||||
pose_data = None
|
||||
|
||||
# Try keyword arg for pose_data (backward compatible with old signatures)
|
||||
try:
|
||||
if self._detect_visualizer_pose_kwarg():
|
||||
keep_running = self._visualizer.update(
|
||||
frame_u8,
|
||||
bbox,
|
||||
@@ -546,8 +577,7 @@ class ScoliosisPipeline:
|
||||
ema_fps,
|
||||
pose_data=pose_data,
|
||||
)
|
||||
except TypeError:
|
||||
# Fallback for legacy visualizers that don't accept pose_data
|
||||
else:
|
||||
keep_running = self._visualizer.update(
|
||||
frame_u8,
|
||||
bbox,
|
||||
@@ -676,7 +706,7 @@ class ScoliosisPipeline:
|
||||
"frame": pa.array(frames, type=pa.int64()),
|
||||
"track_id": pa.array(track_ids, type=pa.int64()),
|
||||
"timestamp_ns": pa.array(timestamps, type=pa.int64()),
|
||||
"silhouette": pa.array(silhouettes, type=pa.list_(pa.float64())),
|
||||
"silhouette": pa.array(silhouettes, type=pa.list_(pa.float32())),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -746,7 +776,7 @@ class ScoliosisPipeline:
|
||||
track_ids.append(result["track_id"])
|
||||
labels.append(result["label"])
|
||||
confidences.append(result["confidence"])
|
||||
windows.append(result["window"])
|
||||
windows.append(int(result["window"]))
|
||||
timestamps.append(result["timestamp_ns"])
|
||||
|
||||
table = pa.table(
|
||||
|
||||
Reference in New Issue
Block a user