Lint the commits being pushed and scope overlay failures per sensor
The pre-push gate linted only the dirty tree, so the commits about to be pushed went unchecked; and every failed overlay projection was sticky, which cost a finger result its overlay over one bad frame while box results were retried nowhere. gate.ps1 now takes -LintBase (default origin/main, exit 2 on an unknown ref), the projector declares whether its own failures are permanent, and serve_stored_view decides before it sets the view. Verified with gate.ps1 (PASS: 569 studio + 485 shared tests, 632 ui_check checks) and the two round-2 red samples kept in scratch.
This commit is contained in:
@@ -22,11 +22,23 @@ import numpy as np
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__all__ = ["OverlayBaseProjector"]
|
||||
__all__ = ["OverlayBaseProjector", "projection_failures_are_permanent"]
|
||||
|
||||
_CWD_LOCK = threading.Lock()
|
||||
|
||||
|
||||
def projection_failures_are_permanent(sensor_type: str) -> bool:
|
||||
"""Whether a failed projection for this sensor is worth retrying on the next frame.
|
||||
|
||||
Only the finger unroll has a per-frame remap, so one miss is that frame's problem. A
|
||||
box stitch failure is a property of the footage — the lenslet grid either converges
|
||||
on these pixels or it does not — so retrying it per cursor move rebuilds the same
|
||||
failure. This is the one place the policy is stated; both openers read it, and the
|
||||
analysis session reads the projector's declaration instead of deciding again.
|
||||
"""
|
||||
return str(sensor_type) != "finger"
|
||||
|
||||
|
||||
def _ensure_bgr(image: np.ndarray) -> np.ndarray:
|
||||
if image.ndim == 2:
|
||||
return cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
|
||||
@@ -38,7 +50,15 @@ def _ensure_bgr(image: np.ndarray) -> np.ndarray:
|
||||
|
||||
|
||||
class OverlayBaseProjector:
|
||||
"""Maps one camera frame onto the measurement domain for overlay views."""
|
||||
"""Maps one camera frame onto the measurement domain for overlay views.
|
||||
|
||||
``projection_failures_are_permanent`` says what a failed projection *means*, because
|
||||
only the projector knows: a finger unroll can lose one frame (a transient remap
|
||||
miss) and be fine on the next, while a box stitch that cannot rebuild the lenslet
|
||||
grid will not start working mid-session. The consumer cannot tell from the returned
|
||||
``None``, and must not try to infer it from an exception's text — it asks this
|
||||
declaration instead (see ``AnalysisSession.overlay_base``).
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -47,11 +67,14 @@ class OverlayBaseProjector:
|
||||
project,
|
||||
close=None,
|
||||
working: Path | None = None,
|
||||
projection_failures_are_permanent: bool = True,
|
||||
) -> None:
|
||||
self.sensor_type = str(sensor_type)
|
||||
self._project = project
|
||||
self._close = close
|
||||
self._working = None if working is None else Path(working)
|
||||
#: Default True: a projector only gets to be "retry next frame" if it says so.
|
||||
self.projection_failures_are_permanent = bool(projection_failures_are_permanent)
|
||||
self._cache_id: int | None = None
|
||||
self._cache: np.ndarray | None = None
|
||||
|
||||
@@ -124,7 +147,13 @@ class OverlayBaseProjector:
|
||||
return None
|
||||
return _ensure_bgr(unrolled)
|
||||
|
||||
return cls(sensor_type="finger", project=project)
|
||||
# One frame the unroll cannot map is that frame's problem: the next camera frame
|
||||
# has its own remap, so the session keeps offering the overlay (reported as R2).
|
||||
return cls(
|
||||
sensor_type="finger",
|
||||
project=project,
|
||||
projection_failures_are_permanent=projection_failures_are_permanent("finger"),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _open_box(cls, *, config_ref: str | None) -> OverlayBaseProjector | None:
|
||||
@@ -163,7 +192,15 @@ class OverlayBaseProjector:
|
||||
logger.debug("box overlay sensor disconnect skipped", exc_info=True)
|
||||
shutil.rmtree(working, ignore_errors=True)
|
||||
|
||||
return cls(sensor_type="box", project=project, close=close, working=working)
|
||||
# A box stitch that fails once fails for this footage: the lenslet grid is a
|
||||
# property of the recording, so retrying per scrub rebuilds the same failure.
|
||||
return cls(
|
||||
sensor_type="box",
|
||||
project=project,
|
||||
close=close,
|
||||
working=working,
|
||||
projection_failures_are_permanent=projection_failures_are_permanent("box"),
|
||||
)
|
||||
|
||||
def project(
|
||||
self, video_bgr: np.ndarray, *, frame_id: int | None = None
|
||||
|
||||
Reference in New Issue
Block a user