Stereo Streaming

This sample shows how to receive and display two camera streams from a stereo DELTA device. It reads ColorFrame output from cameraIndex = 0 and cameraIndex = 1, then displays both frames side by side with OpenCV.

Back to Code Samples.

Note

This sample is for a stereo-configured DELTA camera, not for two separate DELTA cameras connected over USB. In stereo mode, one device provides interleaved data for two camera indexes. The SDK separates that stream into cameraIndex = 0 and cameraIndex = 1. If you connect two independent USB cameras, do not use this sample as a dual-device streaming example.

Example Overview

Step SDK API Purpose
1 scanDevices() / openDevice() Find and open one DELTA device.
2 applySensorSetting() Apply the stereo sensor setting file.
3 getStreamVersion() Confirm that the applied setting produces Version::Stereo.
4 setFrameGeneration() Choose how event data is converted into generated frames.
5 setOutputType() Select ColorFrame output for side-by-side OpenCV preview.
6 setColorFormat() / setColor() Choose gray or RGB event visualization.
7 getColorFrameBufferSize() Allocate one frame buffer per camera index.
8 startStream() Start live USB streaming.
9 getColorFrame(..., 0) / getColorFrame(..., 1) Read generated frames from both stereo camera indexes.
10 stopStream() / closeDevice() Stop streaming and release the device.

Expected Result

When the sample runs successfully, two OpenCV preview windows appear and show the left and right stereo stream outputs.

Stereo Streaming result

Code Walkthrough

Edit the User Control Panel

The USER CONTROL PANEL section is the only part you normally need to edit. Each option group has one active line and one or more commented alternatives. To use a different mode, comment out the current active line and uncomment the mode you want to use.

Select a Device

selectDeviceIndex selects which device from the latest scanDevices() result will be opened.

const std::int32_t selectDeviceIndex = 0;

selectDeviceIndex = 0 selects the first detected device. This should be the stereo DELTA device. It does not select the left or right camera; left/right selection happens later through cameraIndex.

Select a Frame Generation Mode

Frame generation controls how raw event data is grouped into display frames. Only one selected_framemode line should be active at a time.

(a) FrameEndBased

This is the default mode used by the example.

const std::string selected_framemode = "FrameEndBased";
const std::int32_t frameEndCount = 20;

When this mode is active, the SDK generates one output frame after the selected number of frame-end markers. This is a good default for live preview because it follows the camera stream structure directly.

(b) TimeBased

To use time-based frame generation, uncomment the TimeBased line in the example and comment out the currently active FrameEndBased line.

// const std::string selected_framemode = "TimeBased";
const std::int32_t framePeriodMs = 16;

When this mode is active, the SDK generates one output frame at a fixed time interval. For example, framePeriodMs = 16 is about 60 Hz.

(c) EventCountBased

To use event-count-based frame generation, uncomment the EventCountBased line in the example and comment out the currently active FrameEndBased line.

// const std::string selected_framemode = "EventCountBased";
const std::int32_t eventsPerFrame = 150000;

When this mode is active, the SDK generates one output frame after the selected number of events. If eventsPerFrame is too small, event activity can be split across too many frames and the preview may look clipped.

Note

Keep only one selected_framemode definition active. If more than one selected_framemode line is uncommented, the example will not compile because the same variable is defined multiple times.

Select the Color Format

The color format controls how the generated ColorFrame is stored and shown in OpenCV.

(a) Gray

This is the default mode used by the example.

const std::string selected_colorformat = "Gray";

When Gray is active, the SDK generates a single-channel grayscale image. The default grayscale rendering is:

Event State Display Color
ON event White
OFF event Black
No event Gray

(b) RGB

To use RGB output, uncomment the RGB line in the example and comment out the currently active Gray line.

// const std::string selected_colorformat = "RGB";

When RGB is active, the SDK generates a three-channel RGB image. You can customize the ON event, OFF event, and no-event colors with rgbColor.

const delta::EventColor rgbColor = {
    {255, 0, 0},     // ON event color
    {0, 0, 255},     // OFF event color
    {255, 255, 255}  // No event (background) color
};

The values are written in RGB order. In the default example above:

Event State RGB Value Display Color
ON event {255, 0, 0} Red
OFF event {0, 0, 255} Blue
No event {255, 255, 255} White

Note

Keep only one selected_colorformat definition active. If both Gray and RGB are uncommented, the example will not compile because the same variable is defined multiple times.

Open a Stereo Device

The sample opens one DELTA device and checks that it is compatible with stereo streaming.

std::int32_t deviceCount = 0;
delta::Status status = delta::scanDevices(&deviceCount);

delta::DeviceInfo deviceInfo{};
status = delta::getDeviceInfo(selectDeviceIndex, &deviceInfo);

if (deviceInfo.type != delta::DeviceType::Delta_10) {
    std::cout << "Stereo streaming requires a Delta_10 device.\n";
    return 1;
}

delta::DeviceHandle cameraHandle = nullptr;
status = delta::openDevice(deviceInfo.index, &cameraHandle);

Note

This check does not mean every Delta_10 device is a stereo camera. The stream must also be configured with a stereo setting file and confirmed with getStreamVersion().

Apply a Stereo Sensor Setting

The example applies a stereo setting file before streaming.

const std::filesystem::path settingFilePath =
    std::filesystem::path(DELTA_SETTINGS_DIR) / "Delta_Sigma_2000FPS.txt";

const std::string settingFileString = settingFilePath.generic_string();
status = delta::applySensorSetting(cameraHandle, settingFileString.c_str());

After applying the setting file, the sample checks the stream version.

delta::Version streamVersion = delta::Version::Unknown;
status = delta::getStreamVersion(cameraHandle, &streamVersion);

if (streamVersion != delta::Version::Stereo) {
    std::cout << "Applied setting file is not a stereo configuration.\n";
    delta::closeDevice(cameraHandle);
    return 1;
}

Version::Stereo means the SDK will separate the incoming stereo stream into two camera indexes: cameraIndex = 0 and cameraIndex = 1.

Set Frame Generation, Output Type, and Color Format

The setup after stereo detection is the same as the single streaming example. The sample selects ColorFrame output because it is used for the side-by-side OpenCV preview.

status = delta::setFrameGeneration(
    cameraHandle,
    delta::frameEndBased(frameEndCount)
);

status = delta::setOutputType(cameraHandle, delta::OutputType::ColorFrame);
status = delta::setColorFormat(cameraHandle, delta::ColorFormat::Gray);

Prepare Per-Camera Buffers

Both stereo camera indexes use the same output format and resolution, so the sample gets one color buffer size and allocates one buffer for each camera index.

const std::uint32_t colorBufferSize =
    delta::getColorFrameBufferSize(cameraHandle);

std::vector<std::uint8_t> frameBuffer0(colorBufferSize);
std::vector<std::uint8_t> frameBuffer1(colorBufferSize);

delta::ColorFrame frame0{};
delta::ColorFrame frame1{};

frame0.startAddress = frameBuffer0.data();
frame0.bufferSize   = colorBufferSize;

frame1.startAddress = frameBuffer1.data();
frame1.bufferSize   = colorBufferSize;

Start Stereo Streaming

Start the stream after the stereo setting, frame generation, output type, color format, and frame buffers are ready.

status = delta::startStream(cameraHandle);

if (status != delta::Status::Success) {
    std::cout << "startStream failed: "
              << delta::getStatusMessage(status) << "\n";
    delta::closeDevice(cameraHandle);
    return 1;
}

Read Both Camera Indexes

The sample reads generated frames from cameraIndex = 0 and cameraIndex = 1. These are not two separate USB devices. They are two camera indexes separated from one stereo stream.

bool hasFrame0 = false;
for (int drainCount = 0; drainCount < 8; ++drainCount) {
    status = delta::getColorFrame(cameraHandle, &frame0, 0);

    if (status != delta::Status::Success) {
        break;
    }

    hasFrame0 = true;
}

bool hasFrame1 = false;
for (int drainCount = 0; drainCount < 8; ++drainCount) {
    status = delta::getColorFrame(cameraHandle, &frame1, 1);

    if (status != delta::Status::Success) {
        break;
    }

    hasFrame1 = true;
}

The inner loops drain older generated frames for each camera index so the preview stays close to the latest stream output.

Display Frames Side by Side

After both camera indexes have a frame, the sample converts RGB output to BGR when needed, concatenates both images horizontally, and displays them in one OpenCV window.

cv::Mat image0;
cv::Mat image1;

if (frame0.colorFormat == delta::ColorFormat::RGB) {
    cv::Mat rgbImage0(
        frame0.header.height,
        frame0.header.width,
        CV_8UC3,
        frame0.startAddress
    );

    cv::Mat rgbImage1(
        frame1.header.height,
        frame1.header.width,
        CV_8UC3,
        frame1.startAddress
    );

    cv::cvtColor(rgbImage0, image0, cv::COLOR_RGB2BGR);
    cv::cvtColor(rgbImage1, image1, cv::COLOR_RGB2BGR);
}
else {
    image0 = cv::Mat(
        frame0.header.height,
        frame0.header.width,
        CV_8UC1,
        frame0.startAddress
    );

    image1 = cv::Mat(
        frame1.header.height,
        frame1.header.width,
        CV_8UC1,
        frame1.startAddress
    );
}

cv::Mat combined;
cv::hconcat(image0, image1, combined);
cv::imshow("DELTA Stereo Streaming (Cam0 | Cam1)", combined);

Stop Streaming

Stop the stream and close the device before the application exits.

delta::stopStream(cameraHandle);
delta::closeDevice(cameraHandle);
cv::destroyAllWindows();