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

# stellarHD YUYV Video Guide

> Capture, save, and convert uncompressed YUYV frames from the stellarHD, including monochrome models.

## Overview

The stellarHD exposes two video formats over its standard UVC (USB Video Class) interface:

* **MJPEG** — JPEG-compressed frames. Best for high framerates (up to 60 FPS) and live viewing.
* **YUYV** — uncompressed 4:2:2 raw video. Best when you need the original, unprocessed pixel data (machine vision, photogrammetry, scientific imaging).

This guide focuses on **YUYV (RAW)** capture: how to grab true raw frames, save them to disk, and convert them for inspection. It also covers a detail specific to **monochrome stellarHD models**, where only the luminance (`Y`) channel contains real image data.

<Note>
  YUYV is uncompressed, so it consumes far more USB bandwidth than MJPEG. As a result, raw mode is limited to lower framerates at higher resolutions. Refer to the [stellarHD Technical Specifications](/stellarHD/specs/stellarHD#supported-resolutions-and-framerates) for the supported resolution/framerate combinations.
</Note>

## Requirements

These commands require a Linux computer with `v4l-utils`, GStreamer, and FFmpeg installed:

```bash theme={null}
sudo apt install v4l-utils ffmpeg \
  libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-tools \
  gstreamer1.0-x gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
  gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-plugins-ugly
```

## Understanding YUYV vs MJPEG

|                   | YUYV (uncompressed)                  | MJPEG                        |
| ----------------- | ------------------------------------ | ---------------------------- |
| Compression       | None (4:2:2 uncompressed)            | JPEG compressed              |
| Use case          | Raw pixel data, analysis             | High framerate, live preview |
| Framerate         | Lower at high resolution             | Up to 60 FPS                 |
| File size         | `width × height × 2` bytes per frame | Variable (small)             |
| Directly viewable | No (raw bytes)                       | Yes (each frame is a JPEG)   |

In GStreamer caps, the V4L2 format `YUYV` is written as `YUY2`.

<Warning>
  **"YUYV" is uncompressed, but it is not sensor-raw.** In camera terms, *raw* means the
  unprocessed **Bayer mosaic** straight off the sensor — one color sample per pixel, before
  demosaicing, white balance, or color conversion. YUYV 4:2:2 (`YUY2`) is something different:
  it is the camera's **already-processed output** — the Bayer data has been demosaiced on the
  camera, converted to the YUV color space, and chroma-subsampled (4:2:2 stores two chroma
  samples for every two luma samples). This is true of both the color and monochrome models:
  the output is uncompressed, but it is still processed and sub-sampled.

  The stellarHD does **not** expose the underlying Bayer/sensor-raw data over UVC, so you
  **cannot** retrieve a raw mosaic or run your own demosaicing pipeline. The "raw" in this guide
  means *uncompressed pixel data*, not *sensor-raw*.
</Warning>

## Step 1 — Identify the Device Node

When you plug in a stellarHD, the kernel creates several V4L2 device nodes. Both YUYV and MJPEG are exposed on the **first** node of the group.

```bash theme={null}
v4l2-ctl --list-devices
```

Example output:

```text theme={null}
stellarHD Leader: stellarHD Lea (usb-0000:00:14.0-6):
	/dev/video4   # <-- this node outputs both YUYV and MJPEG
	/dev/video5
	/dev/media2
```

In this example, `/dev/video4` is the node to use. Substitute your own node in the commands below.

<Tip>
  Confirm the formats, resolutions, and framerates your camera advertises before capturing:

  ```bash theme={null}
  v4l2-ctl -d /dev/video4 --list-formats-ext
  ```

  You should see both `YUYV` (uncompressed 4:2:2) and `MJPG` (MJPEG compressed) entries.
</Tip>

## Step 2 — Capture a Single RAW Frame

Use `v4l2-ctl` to capture one uncompressed YUYV frame at full resolution:

```bash theme={null}
v4l2-ctl -d /dev/video4 \
  --set-fmt-video=width=1600,height=1200,pixelformat=YUYV \
  --stream-mmap \
  --stream-count=1 \
  --stream-to=frame_1600x1200.yuyv
```

This writes the raw YUYV bytes directly to `frame_1600x1200.yuyv`.

### Verify the frame size

A complete raw frame should be exactly `width × height × 2` bytes:

```text theme={null}
1600 × 1200 × 2 = 3,840,000 bytes (~3.8 MB)
```

If the file size matches, you have captured a complete raw frame.

## Step 3 — Convert the RAW Frame to PNG

Raw YUYV bytes are not directly viewable. Use FFmpeg to convert the frame into a PNG for inspection:

```bash theme={null}
ffmpeg \
  -f rawvideo \
  -pixel_format yuyv422 \
  -video_size 1600x1200 \
  -i frame_1600x1200.yuyv \
  frame.png
```

<Warning>
  You must tell FFmpeg the exact pixel format (`yuyv422`) and resolution (`-video_size`) of the raw file. Raw video has no header, so if these values don't match the capture, the image will appear skewed or corrupted.
</Warning>

## Monochrome stellarHD Models

Because of a UVC quirk, the monochrome stellarHD advertises its output as `YUYV 4:2:2` even though the sensor has no color information.

* Only the **`Y` (luminance)** channel contains the real image.
* The **`U` and `V` (chroma)** channels are dummy/fixed values and can be ignored.

If you convert a monochrome frame as full color, you may see bogus tinting from the meaningless chroma data. Extract grayscale only:

```bash theme={null}
ffmpeg \
  -f rawvideo \
  -pixel_format yuyv422 \
  -video_size 1600x1200 \
  -i frame_1600x1200.yuyv \
  -vf format=gray \
  mono.png
```

This uses only the luminance channel and avoids bogus chroma interpretation.

### Verify the camera is genuinely monochrome

Play the raw file back directly with `ffplay`. If the image appears grayscale naturally, the chroma channels are constant:

```bash theme={null}
ffplay \
  -f rawvideo \
  -pixel_format yuyv422 \
  -video_size 1600x1200 \
  frame_1600x1200.yuyv
```

## GStreamer Pipelines

### View the live raw stream

```bash theme={null}
gst-launch-1.0 \
  v4l2src device=/dev/video4 ! \
  video/x-raw,format=YUY2,width=1600,height=1200,framerate=5/1 ! \
  videoconvert ! \
  autovideosink
```

### Save one raw frame to disk

```bash theme={null}
gst-launch-1.0 -e \
  v4l2src device=/dev/video4 num-buffers=1 ! \
  video/x-raw,format=YUY2,width=1600,height=1200,framerate=5/1 ! \
  filesink location=frame.yuyv
```

### Faster preview with MJPEG

Because YUYV is limited to low framerates at high resolution, use MJPEG when you only need a smooth realtime preview:

```bash theme={null}
gst-launch-1.0 \
  v4l2src device=/dev/video4 ! \
  image/jpeg,width=1600,height=1200,framerate=30/1 ! \
  jpegdec ! \
  videoconvert ! \
  autovideosink
```

## Extracting Luminance in OpenCV / Python

If you process raw frames downstream and your sensor is monochrome, extract the luminance channel rather than treating the frame as color.

```python theme={null}
# YUYV frame loaded as a 3-channel array — the Y channel is the real image
gray = frame[:, :, 0]
```

Or convert explicitly from YUY2:

```python theme={null}
import cv2

gray = cv2.cvtColor(frame, cv2.COLOR_YUV2GRAY_YUY2)
```

<Card title="OpenCV Guide" icon="https://github.com/opencv/opencv/wiki/logo/OpenCV_logo_no_text.png" href="/stellarHD/guides/opencv-stellarHD">
  See our full guide on using the stellarHD with OpenCV.
</Card>

## Troubleshooting

### The output file is the wrong size

A complete raw frame is exactly `width × height × 2` bytes. A smaller file usually means the capture was interrupted or the requested resolution isn't supported in YUYV mode — check `v4l2-ctl -d /dev/video4 --list-formats-ext`.

### The converted image is skewed or garbled

The `-pixel_format` and `-video_size` passed to FFmpeg must exactly match the capture. Raw video has no header, so any mismatch corrupts the layout.

### The image looks tinted on a monochrome camera

The chroma channels carry no real data on a monochrome sensor. Re-convert with `-vf format=gray` (FFmpeg) or extract the `Y` channel (OpenCV) as shown above.

### YUYV framerate is too low

This is expected — uncompressed video is bandwidth-heavy. Drop the resolution, lower the framerate, or switch to MJPEG for live viewing.
