Stream Status Display

This sample shows how to monitor a live DELTA stream while displaying generated ColorFrame output with OpenCV. It registers stream callback functions, stores the latest stream status values, and draws those values on top of the preview window.

Back to Code Samples.

Example Overview

Step SDK API Purpose
1 scanDevices() / openDevice() Find and open a connected DELTA Series camera.
2 applySensorSetting() Apply the recommended sensor setting file.
3 setFrameGeneration() Choose how event data is converted into generated frames.
4 setOutputType() Select ColorFrame output for OpenCV preview and overlay display.
5 setColorFormat() / setColor() Choose gray or RGB event visualization.
6 getColorFrameBufferSize() Get the required caller-owned frame buffer size.
7 setDataRateCallback() Receive USB data rate updates in KB/s.
8 setFrameRateCallback() Receive generated frame rate updates in FPS.
9 setEventCountCallback() Receive total parsed event count updates.
10 setFrameCountCallback() Receive total parsed frame count updates.
11 startStream() Start live USB streaming.
12 getColorFrame() Read generated frames and draw status values on the preview.
13 stopStream() / closeDevice() Stop streaming and release the device.

Expected Result

When the sample runs successfully, an OpenCV preview window appears and shows the live camera output with stream status values displayed in green.

Stream Status Display result

USB : Current data rate received over USB during streaming

FPS : FPS calculated using Frame End packets received from the sensor

Events : Total number of events accumulated during streaming

Frames : Total number of frames accumulated during streaming

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 Camera

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

const std::int32_t selectDeviceIndex = 0;

selectDeviceIndex = 0 selects the first detected camera. If multiple cameras are connected, use 1, 2, and so on to choose another detected camera.

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.

Store Stream Status Values

The sample uses StreamStats to store the latest values received from SDK callbacks. Each value is atomic because the callbacks may be called from an SDK internal thread while the main thread is drawing the preview.

struct StreamStats
{
    std::atomic<double> dataRateKBps{0.0};
    std::atomic<std::int32_t> frameRateFPS{0};
    std::atomic<std::uint64_t> totalEvents{0};
    std::atomic<std::uint64_t> totalFrames{0};
};

Define Callback Functions

Each callback receives userData, converts it back to StreamStats, and stores only the latest value.

static void onDataRate(void* userData, double kilobytesPerSecond)
{
    auto* stats = static_cast<StreamStats*>(userData);
    stats->dataRateKBps.store(kilobytesPerSecond);
}

static void onFrameRate(void* userData, std::int32_t framesPerSecond)
{
    auto* stats = static_cast<StreamStats*>(userData);
    stats->frameRateFPS.store(framesPerSecond);
}

The event and frame count callbacks use the same pattern.

static void onEventCount(void* userData, std::uint64_t totalEvents)
{
    auto* stats = static_cast<StreamStats*>(userData);
    stats->totalEvents.store(totalEvents);
}

static void onFrameCount(void* userData, std::uint64_t totalFrames)
{
    auto* stats = static_cast<StreamStats*>(userData);
    stats->totalFrames.store(totalFrames);
}

Note

Keep callback functions short and thread-safe. Do not call blocking SDK APIs such as saveRawByTime() from inside a callback.

Open the Device and Prepare ColorFrame Output

Device setup, frame generation, output type, color format, and frame buffer preparation follow the same pattern as Single Streaming. The sample enables ColorFrame because the stream status values are drawn on top of the preview image.

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

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

std::vector<std::uint8_t> frameBuffer(bufferSize);

delta::ColorFrame frame{};
frame.startAddress = frameBuffer.data();
frame.bufferSize = bufferSize;

Register Stream Status Callbacks

Register the callback functions before starting the stream. The same StreamStats instance is passed as userData to every callback.

StreamStats stats;

status = delta::setDataRateCallback(cameraHandle, onDataRate, &stats);
status = delta::setFrameRateCallback(cameraHandle, onFrameRate, &stats);
status = delta::setEventCountCallback(cameraHandle, onEventCount, &stats);
status = delta::setFrameCountCallback(cameraHandle, onFrameCount, &stats);
Callback Value
setDataRateCallback() USB receive data rate in KB/s.
setFrameRateCallback() Generated frame rate in FPS.
setEventCountCallback() Total parsed event count.
setFrameCountCallback() Total parsed frame count.

Start Live Streaming

Start the stream after the device setup, output setup, frame buffer, and callbacks are ready.

status = delta::startStream(cameraHandle);

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

Display Stream Status with OpenCV

The preview loop reads the latest ColorFrame, converts it to a display image, loads the latest callback values, and draws them with cv::putText().

std::ostringstream dataRateText;
dataRateText << "USB: " << std::fixed << std::setprecision(1)
             << stats.dataRateKBps.load() << " KB/s";

const std::string frameRateText =
    "FPS: " + std::to_string(stats.frameRateFPS.load());
const std::string eventCountText =
    "Events: " + std::to_string(stats.totalEvents.load());
const std::string frameCountText =
    "Frames: " + std::to_string(stats.totalFrames.load());
const cv::Scalar overlayColor(0, 255, 0);

cv::putText(displayImage, dataRateText.str(), cv::Point(20, 35),
            cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);
cv::putText(displayImage, frameRateText, cv::Point(20, 70),
            cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);
cv::putText(displayImage, eventCountText, cv::Point(20, 105),
            cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);
cv::putText(displayImage, frameCountText, cv::Point(20, 140),
            cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);

cv::imshow("DELTA Callback Monitor", displayImage);

The callback functions do not draw to the window directly. The main loop owns the OpenCV display, which keeps the callback path lightweight.

Stop Streaming

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

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