Merge branch 'main' of ssh://892887cvmk08.aicp.io:24928/orisys-tech/orisys-app

This commit is contained in:
ykcheungab
2026-10-10 14:16:03 +08:00
parent f5ba64e01a
commit cf86bd0702
14 changed files with 118 additions and 4 deletions
@@ -598,6 +598,7 @@ def depth_map_to_bgr(
*,
value_range: tuple[float, float] | None = None,
invalid_mask: np.ndarray | None = None,
threshold: float = 0.0,
) -> np.ndarray | None:
"""Convert a float depth/divergence map to a colormap BGR image.
@@ -608,6 +609,9 @@ def depth_map_to_bgr(
``invalid_mask`` marks samples that carry no depth. They are painted with a
neutral grey so "no data" can never be mistaken for "zero depth".
``threshold`` only changes valid pixels' colours: below it they use the
first ramp colour, while the source depth and the colour span stay intact.
"""
if depth is None:
return None
@@ -628,6 +632,8 @@ def depth_map_to_bgr(
scaled = np.zeros(arr.shape, dtype=np.float64)
scaled = np.clip(scaled, 0.0, 1.0)
normalized = (scaled * 255.0).astype(np.uint8)
if threshold > 0.0:
normalized[finite & (arr < threshold)] = 0
image = cv2.applyColorMap(
normalized, cv2.COLORMAP_JET if colormap is None else colormap
)
@@ -418,6 +418,7 @@ def render_image(
theme: str = "dark",
draw_style: str = "box",
depth_range: tuple[float, float] | None = None,
depth_threshold: float = 0.0,
canvas_bgr: Sequence[int] | None = None,
domain_mask: np.ndarray | None = None,
arrow_policy=None,
@@ -441,6 +442,9 @@ def render_image(
with, so both figures trigger at the same strength. ``None`` means the draw style's
own defaults.
``depth_threshold`` changes depth colouring only. It never changes the frame's
measured depth, its valid mask or the arrows drawn over it.
``orientation`` is a **display** convention for the domain-grid views: the picture is
turned or mirrored once it has been drawn, so the frame's own ``flow``, ``valid_mask``
and ``image_bgr`` are untouched — a recorded session's flow is stored in the domain's
@@ -460,6 +464,7 @@ def render_image(
frame.depth,
flow_colormap(theme),
value_range=depth_range,
threshold=depth_threshold,
invalid_mask=boundary,
)
if wanted == DEPTH:
@@ -650,6 +650,8 @@ class DisplaySettings:
#: refits both views to the current frame's finite minimum and maximum — the
#: earlier per-frame colour bar. A fixed colour scale still wins over either.
depth_scale_adaptive: bool = False
#: Paint depth response below this relative value with the base ramp colour.
depth_threshold: float = 0.0
@dataclass(frozen=True)
+14
View File
@@ -52,6 +52,20 @@ def test_depth_arrows_draws_the_flow_on_the_depth_picture():
assert not np.array_equal(over, plain)
def test_depth_display_threshold_uses_base_colour_without_changing_source():
depth = np.array([[0.1, 0.4, 0.8]], dtype=np.float32)
original = depth.copy()
frame = backend.ImageFrame(_image(1, 3), depth=depth)
plain = backend.render_image(frame, mode="depth", depth_range=(0.0, 1.0))
tuned = backend.render_image(
frame, mode="depth", depth_range=(0.0, 1.0), depth_threshold=0.5
)
assert plain is not None and tuned is not None
assert np.array_equal(tuned[0, 0], tuned[0, 1])
assert np.array_equal(tuned[0, 2], plain[0, 2])
assert np.array_equal(depth, original)
def test_a_recorded_frame_is_raw_and_says_so():
"""No flow and no depth: the frame *is* the picture, and the note explains it."""
plan = backend.plan_image(backend.ImageFrame(_image(), source=backend.SOURCE_REPLAY))