Depth Camera¶
A depth camera is a per-pixel metric depth stream, pixel-aligned to a sibling RGB
Camera whose camera_id, projection model, intrinsics, and extrinsics it
shares. It is stored as CAMERA_DEPTH in its own stream,
camera_depth.<camera_id>.arrow, separate from the RGB camera.<camera_id>.arrow of the same
camera_id.
The storage contract — how metric depth is quantized into the stored raster, and the max_depth,
depth_bits, depth_transform, min_depth, has_invalid and depth_type knobs that
control it — is documented on DepthCameraMetadata below. The examples here
show it end to end.
Reading and writing¶
from py123d.datatypes import Camera, DepthCameraMetadata
# Writing: quantize metric depth into the stored raster.
depth_metadata = DepthCameraMetadata(camera_metadata=rgb_metadata, max_depth=96.0, depth_bits=16)
log_writer.write_async(
Camera(
metadata=depth_metadata,
image=depth_metadata.encode_depth(depth_in_metres),
camera_to_global_se3=camera_to_global_se3,
timestamp=timestamp,
)
)
# Reading: `image` is the raw quantized raster, not metres. `scale` optionally downsamples.
camera = scene.get_camera_depth_at_iteration(iteration, camera_id=CameraID.PCAM_F0, scale=2)
depth_in_metres = camera.metadata.decode_depth(camera.image) # NaN where has_invalid marked no data
# `rgb_image` colorizes the raster with a TURBO ramp for display.
preview = camera.rgb_image
The default above (linear, no sentinel, z-depth) matches a simulator that renders a finite depth for every pixel. A sparse real sensor — e.g. lidar projected into the image — wants the inverse transform for near-field precision and the invalid sentinel for dropouts:
depth_metadata = DepthCameraMetadata(
camera_metadata=rgb_metadata,
max_depth=120.0,
depth_bits=16,
depth_transform="inverse", # fine near, coarse far
min_depth=0.5, # required by the inverse transform
has_invalid=True, # code 0 -> NaN for pixels with no measurement
depth_type="z_depth", # or "ray_distance" for a native range sensor
)
The scale argument on the read accessors (get_camera_depth_at_iteration /
get_camera_depth_at_timestamp) is an integer downscale denominator — 2 for half size, 4 for
quarter — applied at decode time. It resamples with nearest-neighbour, never bilinear: averaging depth
across an occlusion boundary would invent a surface floating between foreground and background.
Depth Camera Metadata¶
- class py123d.datatypes.DepthCameraMetadata[source]¶
Metadata for a per-pixel depth camera stream.
A depth camera is pixel-aligned to a sibling RGB camera: it shares that camera’s id, projection model, intrinsics, and extrinsics, and composes its
BaseCameraMetadatafor all geometry. In addition, it records how the continuous metric depth was quantized into the stored integer raster.Its
channel_typeis alwaysDEPTH(modalityCAMERA_DEPTH, filecamera_depth.<camera_id>.arrow), a separate stream from the RGBcamera.<camera_id>.arrowof the samecamera_id.Storage contract. Depth is continuous, so it is quantized to an unsigned integer raster (
uint8oruint16) and stored as a lossless PNG. Quantization clips to[min_depth, max_depth], maps onto the unit interval (linearly in depth, or in inverse depth — seedepth_transform), and rounds onto the integer codes[offset, max_raw]:t = to_unit(clip(depth_m, min_depth, max_depth)) # depth -> [0, 1] (transform-dependent) raw = offset + round(t * (max_raw - offset)) # encode # decode inverts to_unit on (raw - offset) / (max_raw - offset)
where
max_raw = 2 ** depth_bits - 1andoffsetis1whenhas_invalidreserves code0(else0). Points to keep in mind:max_depthclips the far range. Anything at or beyondmax_depthsaturates tomax_rawand decodes back as exactlymax_depth, so a sky pixel at 1000 m and a wall atmax_depthare indistinguishable once encoded.Invalid pixels. With
has_invalid=False(the default) there is no sentinel: the full integer range encodes depth,0means zero metres, and non-finite inputs clamp to the range. This suits simulators, which render a finite depth for every pixel. Withhas_invalid=True, code0is reserved for “no measurement”: any non-finite or non-positive input encodes to0and decodes back toNaN, and valid depth uses[1, max_raw]. Set this for real sensors (lidar-projected, ToF, stereo) that have dropouts.depth_transformchooses linear vs. inverse-depth spacing;depth_typerecords whether the scalar is planar z-depth or euclidean range (see those knobs).
depth_bitstrades resolution against file size;max_depthtrades range against resolution. Forlinearthe worst-case error is half a quantization step (depth_resolution/ 2):depth_bits
max_depth
depth_resolution
max error
8
50 m
196 mm
98 mm
16
96 m
1.46 mm
0.73 mm
16
1024 m
15.6 mm
7.8 mm
Public Data Attributes:
camera_metadataThe sibling camera metadata that provides this stream's geometry.
max_depthThe far clipping plane in metres; depth at or beyond this saturates to
max_raw.min_depthThe near clipping plane in metres.
depth_bitsthe bit depth of the stored integer raster (and of the PNG).
depth_transformhow metric depth is spaced across the integer codes.
has_invalidWhether code
0is a reserved "no measurement" sentinel (valid depth then uses[1, max_raw]).depth_typewhat the stored scalar measures.
max_rawThe largest storable integer,
2 ** depth_bits - 1(i.e.255or65535).depth_dtypeuint8oruint16.depth_resolutionMetres per integer unit for the
lineartransform,max_depth / code_span.channel_typeAlways
CameraChannelType.DEPTH.camera_modelInherited, see superclass.
camera_idInherited, see superclass.
camera_nameInherited, see superclass.
camera_to_imu_se3Inherited, see superclass.
widthInherited, see superclass.
heightInherited, see superclass.
modality_idThe camera id, so the stream sits at
camera_depth.<camera_id>.Inherited from
BaseCameraMetadatacamera_modelThe projection model of the camera.
camera_idThe camera ID, unique within a sensor rig.
camera_nameThe camera name, according to the dataset naming convention.
camera_to_imu_se3The static extrinsic pose of the camera relative to the IMU frame.
widthThe width of the camera image in pixels.
heightThe height of the camera image in pixels.
channel_typeThe channel type of the camera image.
modality_typeReturns the type of the modality that this metadata describes.
modality_idReturns the camera ID as the modality ID.
aspect_ratioThe aspect ratio (width / height) of the camera.
Inherited from
BaseModalityMetadatamodality_typeReturns the type of the modality that this metadata describes.
modality_idOptional identifier for the modality, e.g. sensor ID for sensor modalities.
modality_keyReturns a unique key for this modality, combining type and id if applicable.
Public Methods:
encode_depth(depth)Quantize a metric depth map
(H, W)in metres into the stored integer raster.decode_depth(raw)Dequantize a stored integer raster back to metric depth in metres.
project_to_image(points_cam)Inherited, see superclass.
to_dict()Serialize the metadata, embedding the sibling camera and the quantization contract.
from_dict(data_dict)Construct a
DepthCameraMetadatafrom a dictionary.Inherited from
BaseCameraMetadataproject_to_image(points_cam)Project 3D points in camera frame to image pixel coordinates.
Inherited from
BaseMetadatato_dict()Serialize the metadata instance to a plain Python dictionary.
from_dict(data_dict)Construct a metadata instance from a plain Python dictionary.
Private Methods:
_depth_to_unit(depth_m)Map clipped metric depth in
[min_depth, max_depth]onto[0, 1], monotonically increasing._unit_to_depth(t)Inverse of
_depth_to_unit(): map[0, 1]back onto metric depth.Inherited from
BaseCameraMetadata_compute_in_fov_mask(pixel_coords, depth[, eps])Compute a boolean mask for points in front of the camera and within image bounds.
- property camera_metadata: BaseCameraMetadata¶
The sibling camera metadata that provides this stream’s geometry.
- property max_depth: float¶
The far clipping plane in metres; depth at or beyond this saturates to
max_raw.
- property min_depth: float¶
The near clipping plane in metres.
0(no near clip) unless set, and required forinverse.
- property depth_bits: int¶
the bit depth of the stored integer raster (and of the PNG).
- Type:
8or16
- property depth_transform: Literal['linear', 'inverse']¶
how metric depth is spaced across the integer codes.
- Type:
"linear"or"inverse"
- property has_invalid: bool¶
Whether code
0is a reserved “no measurement” sentinel (valid depth then uses[1, max_raw]).
- property depth_type: Literal['z_depth', 'ray_distance']¶
what the stored scalar measures.
- Type:
"z_depth"(planar) or"ray_distance"(euclidean)
- property depth_resolution: float¶
Metres per integer unit for the
lineartransform,max_depth / code_span.For
inversethe step is not constant (fine near, coarse far); this returns the same nominal value only as a rough far-plane-ish scale, and the half-step error bound does not apply.
- property channel_type: CameraChannelType¶
Always
CameraChannelType.DEPTH.
- encode_depth(depth)[source]¶
Quantize a metric depth map
(H, W)in metres into the stored integer raster.Clips to
[min_depth, max_depth], maps onto[0, 1]viadepth_transform, rescales onto the valid codes[offset, max_raw], and rounds to nearest (rather than truncating, which would bias every pixel downward by half a step on average).With
has_invalid=False(default), non-finite values (NaN/inf, e.g. an unrendered pixel) clamp to the near/far plane. Withhas_invalid=True, any non-finite or non-positive pixel is instead written as the0sentinel.
- decode_depth(raw)[source]¶
Dequantize a stored integer raster back to metric depth in metres.
The inverse of
encode_depth, up to the quantization error. Pixels that saturated on encode decode to exactlymax_depth, not to their true distance. Whenhas_invalidis set, the0sentinel decodes toNaN.
- property camera_model: CameraModel¶
Inherited, see superclass.
- to_dict()[source]¶
Serialize the metadata, embedding the sibling camera and the quantization contract.
- classmethod from_dict(data_dict)[source]¶
Construct a
DepthCameraMetadatafrom a dictionary.The transform/sentinel/type keys default to the historic behaviour (linear, no near clip, no invalid sentinel, z-depth) so
.arrowfiles written before these knobs existed still read.- Return type:
- Parameters:
- property modality_key: str¶
Returns a unique key for this modality, combining type and id if applicable.
- property modality_type: ModalityType¶
Returns the type of the modality that this metadata describes.
The channel type drives the modality: a
CameraChannelType.SEMANTICcamera is a per-pixel semantic segmentation stream (ModalityType.CAMERA_SEMANTIC), aCameraChannelType.INSTANCEcamera a per-pixel panoptic/instance stream (ModalityType.CAMERA_INSTANCE), and aCameraChannelType.DEPTHcamera a per-pixel metric depth stream (ModalityType.CAMERA_DEPTH), each written to its own Arrow file so it sits alongside — and never collides with — the RGB camera that shares itscamera_id. All other channel types are regularModalityType.CAMERA.
Depth Colorization¶
- py123d.datatypes.colorize_depth_map(depth_raw, max_raw=None)[source]¶
Colorize a stored integer depth raster into a
(H, W, 3)uint8 RGB image for display.Normalizes against the dtype’s full range rather than the frame’s min/max, so the colour of a given distance is stable across frames (a per-frame min/max would make the palette flicker as objects enter and leave the view). Near is warm, far is cool.
- Parameters:
- Return type:
- Returns:
A
(H, W, 3)uint8 RGB image.