diff --git a/src/lerobot/utils/foxglove_visualization.py b/src/lerobot/utils/foxglove_visualization.py index 2b0bccd2f..08c9f655d 100644 --- a/src/lerobot/utils/foxglove_visualization.py +++ b/src/lerobot/utils/foxglove_visualization.py @@ -186,28 +186,20 @@ def _log_foxglove_image( ) -> None: """Log an image on a cached per-topic channel. - Encoding is chosen from the frame's channel count and dtype: - - - Single channel => depth map, logged uncompressed as ``16UC1`` (integer) or ``32FC1`` (float). - Plain ``uint8`` grayscale (with no ``depth_range``) is the exception and is sent as ``mono8``. - - Three channels => ``rgb8``. - - Four channels => ``rgba8``. - - When ``compress_images`` is set, ``mono8`` and ``rgb8`` frames are JPEG-encoded instead; depth - and ``rgba8`` frames are always sent raw. + Frames are cast to ``uint8`` and the encoding is chosen from the channel count: 1 => ``mono8``, + 3 => ``rgb8`` (float input assumed in [0, 1]), 4 => ``rgba8``; other counts are skipped with a + warning. When ``compress_images`` is set, ``mono8`` and ``rgb8`` are JPEG-encoded instead. Args: topic: Foxglove topic to log on. frame_id: Frame id stamped on the message. - arr: Image as HWC or CHW (CHW is transposed to HWC), any dtype. Non-depth floating-point - images are assumed normalized to [0, 1] and scaled to uint8. - compress_images: JPEG-encode ``mono8`` and ``rgb8`` frames; ignored for depth and ``rgba8``. + arr: Image as HWC or CHW (CHW is transposed to HWC), any dtype. + compress_images: JPEG-encode ``mono8`` and ``rgb8`` frames; ignored for ``rgba8``. channels: Per-topic channel cache to reuse (see :func:`_log_foxglove_scalars`). log_time: Message time in nanoseconds, also written to the header timestamp; when ``None`` the server's receive time is used. - depth_range: ``(lo, hi)`` bounds that normalize depth to ``[0, 1]`` ``32FC1`` so Foxglove's - default panel scaling matches rerun's ``depth_range`` contrast (a ``RawImage`` carries - no value range itself). + depth_range: ``(lo, hi)`` bounds used to clip a single-channel frame before it is encoded as + a regular image. """ from foxglove.channels import CompressedImageChannel, RawImageChannel @@ -225,39 +217,12 @@ def _log_foxglove_image( height, width = arr.shape[0], arr.shape[1] n_channels = 1 if arr.ndim == 2 else arr.shape[2] - # Single-channel => depth, unless it's plain uint8 grayscale (kept as mono8 below). Foxglove - # renders both 16UC1 (uint16) and 32FC1 (float32) depth with a colormap. - if n_channels == 1 and (depth_range is not None or arr.dtype != np.uint8): - depth = arr if arr.ndim == 2 else arr[..., 0] - if depth_range is not None: - lo, hi = depth_range - depth = depth.astype(np.float32) - depth = np.clip((depth - lo) / (hi - lo), 0.0, 1.0) if hi > lo else np.zeros_like(depth) - encoding, step = "32FC1", width * 4 - elif np.issubdtype(depth.dtype, np.floating): - encoding, step = "32FC1", width * 4 - else: - depth = np.clip(np.rint(depth), 0, 65535).astype("