Skip to content

DepthImage ​

SUMMARY

A metric depth map with optional aligned RGB data.

python
from telekinesis import datatypes
import numpy as np
depth_image = datatypes.DepthImage(np.ones((4, 4), dtype=np.float32))
API Reference
Complete API documentation for DepthImage, including parameters, attributes, and methods.
View Reference →

Parameters ​

ParameterTypeDefaultDescription
depthnp.ndarrayRequiredMetric depth values in metres with shape (H, W) and a supported dtype.
colorsnp.ndarray | NoneNoneOptional aligned RGB image with shape (H, W, 3) and dtype uint8. Its height and width must match the depth image.
compressionImageCompression | intImageCompression.NONECompression codec used during serialization.

Raises ​

ExceptionCondition
TypeErrordepth or colors (when not None) isn't an np.ndarray
ValueErrordepth's dtype isn't in the allowlist or its shape isn't (H, W); colors isn't dtype uint8/shape (H, W, 3) matching depth; or compression is invalid

Supported Dtypes ​

FieldDtypes
depthfloat16, float32, float64
colorsuint8

Attributes ​

AttributeTypeDescription
depthnp.ndarrayDefensive copy, shape (H, W), dtype one of SUPPORTED_DEPTH_DTYPES (meters). Read-only. Construct a new DepthImage to change it.
colorsnp.ndarray | NoneDefensive copy, shape (H, W, 3) uint8, or None. Read-only.
shapetuple[int, int]Shape of depth, (H, W).
heightintDepth map height.
widthintDepth map width.
has_colorsboolWhether an aligned color image is attached.
compressionImageCompressionOn-wire codec. Read-only.

Methods ​

MethodTypeDescription
DepthImage.coerce(value)DepthImageConverts array-like data into a DepthImage. If value is already a DepthImage, it is returned unchanged; otherwise a np.ndarray is wrapped as the depth map.
DepthImage.from_raw_buffer(buffer, shape, dtype, depth_scale=1.0, compression=NONE)DepthImageBuilds a depth image straight from a raw sensor-count buffer (e.g. uint16 values straight off a depth camera), scaling to meters by multiplying by depth_scale.
DepthImage.from_encoded_buffer(buffer, depth_scale=1.0, compression=NONE)DepthImageDecodes a single-channel encoded image (typically a 16-bit PNG) into raw sensor counts, then scales to meters the same way as from_raw_buffer.
DepthImage.from_path(path, depth_scale=1.0, compression=NONE)DepthImageReads an encoded depth image file from disk and decodes it the same way as from_encoded_buffer.
DepthImage.from_url(url, depth_scale=1.0, compression=NONE, connect_timeout=5.0, read_timeout=30.0)DepthImageDownloads an encoded depth image and decodes it the same way as from_encoded_buffer, with configurable connect/read timeouts.
to_numpy(copy=True)np.ndarrayReturns the depth map. With the default copy=True you get an independent copy; pass copy=False for a direct reference to the internal array instead. The aligned colors image, if any, isn't included; access it via the colors property.
copy()DepthImageReturns a new, independent DepthImage with the same depth (and color, if present) data and compression setting.
save_to_path(path, *, depth_scale=1.0)NoneWrites the depth map to disk as a 16-bit encoded image, the inverse of from_encoded_buffer/from_raw_buffer. The aligned color image, if any, isn't written.

Operators ​

OperationBehavior
di == otherCompare with another DepthImage value.
np.asarray(di)Convert the depth map to a NumPy array with np.asarray(di).

Visualization ​

python
import rerun as rr

# Your code block
# ....

rr.init("depth_image_example", spawn=True)
datatypes.visualize(depth_image, entity_path="/depth_image", label="DepthImage")

Example ​

python
"""Demonstrates the Telekinesis DepthImage datatype."""

import time
from pathlib import Path

import numpy as np
import rerun as rr
from loguru import logger

from telekinesis import datatypes

def depth_image_example():
    """Demonstrate creation, inspection, operations, visualization, and serialization."""

    # ======================= Create ============================================
    H, W = 480, 640
    depth = (np.random.rand(H, W) * 5.0).astype(np.float32)
    depth_image = datatypes.DepthImage(depth)
    logger.info(f"Created DepthImage: {depth_image}")

    depth_image_from_coerce = datatypes.DepthImage.coerce(depth)
    logger.info(f"DepthImage created via coerce: {depth_image_from_coerce}")

    depth_scale = 0.001
    raw_counts = np.round(depth / depth_scale).astype(np.uint16)
    depth_image_from_raw_buffer = datatypes.DepthImage.from_raw_buffer(
        raw_counts.tobytes(), shape=depth.shape, dtype=raw_counts.dtype, depth_scale=depth_scale
    )
    logger.info(f"DepthImage created from raw buffer: {depth_image_from_raw_buffer}")

    save_path = Path("results/depth_image_example.png")
    save_path.parent.mkdir(parents=True, exist_ok=True)
    depth_image.save_to_path(save_path, depth_scale=depth_scale)
    depth_image_from_path = datatypes.DepthImage.from_path(save_path, depth_scale=depth_scale)
    logger.info(f"DepthImage created from path: {depth_image_from_path}")

    encoded_buffer = save_path.read_bytes()
    depth_image_from_encoded_buffer = datatypes.DepthImage.from_encoded_buffer(
        encoded_buffer, depth_scale=depth_scale
    )
    logger.info(f"DepthImage created from encoded buffer: {depth_image_from_encoded_buffer}")

    # ======================= Inspect ===========================================
    logger.info(f"depth={depth_image.depth}")
    logger.info(f"colors={depth_image.colors}")
    logger.info(f"shape={depth_image.shape}")
    logger.info(f"height={depth_image.height}")
    logger.info(f"width={depth_image.width}")
    logger.info(f"has_colors={depth_image.has_colors}")
    logger.info(f"compression={depth_image.compression}")

    # ======================= Operations =========================================
    colors = np.random.randint(0, 255, (H, W, 3), dtype=np.uint8)
    rgbd_image = datatypes.DepthImage(depth, colors=colors)
    logger.info(f"RGB-D DepthImage: {rgbd_image}")

    zstd_image = datatypes.DepthImage(
        depth, colors=colors, compression=datatypes.ImageCompression.ZSTD
    )
    logger.info(f"ZSTD-compressed DepthImage: {zstd_image}")

    depth_image_copy = depth_image.copy()
    logger.info(f"Copied DepthImage: {depth_image_copy}")

    depth_image_numpy = depth_image.to_numpy(copy=True)
    logger.info(f"NumPy depth array: {depth_image_numpy}")

    numpy_array = np.asarray(depth_image)
    logger.info(f"Mean depth value: {np.mean(numpy_array)}")
    logger.info(f"Flipped depth shape: {np.flipud(numpy_array).shape}")

    # ======================= Visualize =========================================
    rr.init("depth_image_example", spawn=True)
    datatypes.visualize(depth_image, entity_path="/depth_image/original")
    datatypes.visualize(rgbd_image, entity_path="/depth_image/rgbd")
    datatypes.visualize(zstd_image, entity_path="/depth_image/zstd")

    # ======================= Serialize / Deserialize ===========================
    start = time.perf_counter()
    serialized = datatypes.serialize(rgbd_image)
    serialization_ms = (time.perf_counter() - start) * 1000

    start = time.perf_counter()
    deserialized = datatypes.deserialize(serialized)["param_0"]
    deserialization_ms = (time.perf_counter() - start) * 1000

    logger.info(f"Deserialized DepthImage: {deserialized}")
    logger.info(f"Round-trip successful: {rgbd_image == deserialized}")
    logger.info(f"Serialization time: {serialization_ms:.3f} ms")
    logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")


if __name__ == "__main__":
    depth_image_example()