> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nomadicml.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cameras

> Camera views and their roles, intrinsics and accepted encodings.

## Views

Each camera stream is one channel of `foxglove.CompressedVideo`, `foxglove.CompressedImage` or
`foxglove.RawImage` messages, declared in the overlay's `views` array with the role a media
message cannot carry:

```json theme={null}
"primary_view": "/cam/front",
"views": [
  {"channel": "/cam/front",      "role": "front",      "label": "Front wide"},
  {"channel": "/cam/front_left", "role": "front_left", "label": "Front left"}
]
```

| Field | Type | Required | Rule |
| - | - | - | - |
| `channel` | string | yes | The camera's channel. MUST exist and carry an accepted media message. |
| `role` | string | yes | lower\_snake\_case (`^[a-z0-9_]+$`), unique in the recording. See [Roles](#roles). |
| `label` | string | no | A human-readable name. |

* Top-level `primary_view` SHOULD name the recording's default view and, when present, MUST name a
  declared view's channel. It MAY be omitted for a LiDAR-only recording.
* Keep multi-camera rigs as **separate views**. Do not pre-stitch a mosaic: it destroys per-camera
  geometry and cannot be undone.

## Roles

`role` is free text. These canonical roles have a defined meaning; an unrecognised role is
accepted, with a warning, and kept as a label, so an unusual rig is never blocked.

| Rig | Canonical roles |
| - | - |
| Vehicle surround | `front`, `front_left`, `front_right`, `rear`, `rear_left`, `rear_right`, `left`, `right`, `top`, `bottom`, `left_repeater`, `right_repeater`, `left_pillar`, `right_pillar`, `vehicle_view`, `surround_view`, `range_view` |
| Overhead / site | `overhead_1` … `overhead_6` |
| Robot | `wrist_left`, `wrist_right` |
| Head-worn | `ego` (the head camera), `slam_left`, `slam_right`, `eye_left`, `eye_right` |
| Off-body | `external_1`, `external_2`, … (any positive number, no leading zero) |

* A camera that is **not on the body** (fixed in the world, e.g. a third-person view of a robot or
  a person) uses `external_<n>`. Any kind of body MAY have external cameras.
* On a robot, the main body or head camera is usually `front` (or `ego` on a humanoid or head-worn
  rig); a camera on the end effector is `wrist_left` or `wrist_right`.
* `range_image` and `range_image_rgb` are **reserved**: views with these roles are generated from
  LiDAR at ingest. Do not declare them.

## Intrinsics

Publish each camera's intrinsics as a **`foxglove.CameraCalibration`** message (not declared in the
overlay):

| Field | Value |
| - | - |
| `frame_id` | the camera's frame, matching its image messages and its [transform](/mcap-spec/frames-and-units#transforms) |
| `width`, `height` | image size in pixels |
| `K` | 3×3 intrinsic matrix, row-major |
| `distortion_model`, `D` | **only if the images are not rectified** |

Intrinsics are per camera; cameras on one rig routinely differ. Omitting `D` means the images are
rectified. Do not publish a zero `D` for unknown distortion: it makes "rectified" and "distortion
unknown" indistinguishable.

## Encodings

| Schema | Accepted `format` / `encoding` |
| - | - |
| `foxglove.CompressedVideo` | `h264` (preferred), `h265` |
| `foxglove.CompressedImage` | `jpeg`, `png`, `webp` |
| `foxglove.RawImage` | `rgb8`, `bgr8`, `mono8` |

### Compressed video

`foxglove.CompressedVideo` data follows the Foxglove definition: Annex B byte stream, each message
exactly one frame, keyframes carrying their parameter sets. In addition:

* **No B-frames.** Decode order MUST equal presentation order, because the video is rebuilt by
  concatenating message payloads in `log_time` order. Encode with `-bf 0` (ffmpeg) for both h264
  and h265. An h265 stream with B-frames is rejected.
* If your source is h265 with B-frames, re-encode with `-bf 0` (to h264 or h265) or publish a
  `foxglove.CompressedImage` sequence instead.

### Image sequences

`CompressedImage` and `RawImage` sequences are assembled into video using the message timestamps,
so irregular frame intervals are preserved.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.