C++ Example

This example demonstrates how to use the epc::TOFCam API to capture distance and amplitude frames from the EPC670 ToF camera module and display them in real time using OpenCV.

C++ example result

Prerequisites

  • A connected EPC670 ToF camera module

  • OpenCV 4.10 or later installed on the system (e.g. sudo apt install libopencv-dev)

  • libepctofcam installed, see Installation for details.

Build

Compile and link the example code against the preinstalled libepctofcam library:

g++ cpp_example.cpp -o cpp_example \
    -std=c++17 \
    -lepctofcam \
    $(pkg-config --cflags --libs opencv4)

If pkg-config is not available for OpenCV, specify the flags manually:

g++ cpp_example.cpp -o cpp_example \
    -std=c++17 \
    -lepctofcam \
    -I/usr/include/opencv4 \
    -lopencv_core -lopencv_highgui -lopencv_imgproc

Run

./cpp_example

Press any key in the OpenCV window to stop the stream and exit.

Parameters

Parameter

Value

Description

ACQUISITION_MODE

DIST_AMP_HDR

Acquisition mode

HDR_INTEGRATION_TIME1_US

40 µs

HDR integration time (short)

HDR_INTEGRATION_TIME2_US

400 µs

HDR integration time (medium)

HDR_INTEGRATION_TIME3_US

4000 µs

HDR integration time (long)

MODULATION_FREQ_HZ

10 MHz

Modulation frequency

How It Works

  1. Open the camera with cam.open().

  2. Configure the acquisition mode, exposure time and modulation frequency via cam.setControl().

  3. Start the stream with cam.startStream().

  4. In a loop, capture frames with cam.captureFrame() and copy the distance and amplitude data into OpenCV matrices using std::memcpy.

  5. The distance image is scaled to the unambiguity range of the sensor and colorized with the JET colormap. The amplitude image is colorized with the VIRIDIS colormap.

  6. Both images are upscaled 2x using nearest-neighbor interpolation for better visibility on screen.

  7. When a key is pressed, the stream is stopped with cam.stopStream() and the camera is closed with cam.close().

Full Source Code

  1#include <iostream>
  2#include <opencv2/opencv.hpp>
  3
  4#include "epc/tofcam.hpp"
  5
  6const int modulation_freq = 10e6; // 10 MHz
  7const int min_amplitude = 80;     // minimum amplitude threshold for valid distance measurements
  8const float max_distance = 2000.0f;
  9const int hdr_integration_times_us[3] = {40, 400, 4000}; // HDR integration times in microseconds
 10
 11int main(int argc, char *argv[]) {
 12
 13    epc::TOFCam cam;
 14
 15    // connect to the TOFCam module
 16    int ret = cam.open();
 17    if (ret != 0) {
 18        std::cerr << "Failed to connect to camera module: " << strerror(-ret) << std::endl;
 19        return -1;
 20    }
 21
 22    // set camera parameters
 23    cam.setControl(epc::ControlID::ACQUISITION_MODE, epc::AcquisitionMode::DIST_AMP_HDR);
 24    cam.setControl(epc::ControlID::HDR_INTEGRATION_TIME1_US, hdr_integration_times_us[0]);
 25    cam.setControl(epc::ControlID::HDR_INTEGRATION_TIME2_US, hdr_integration_times_us[1]);
 26    cam.setControl(epc::ControlID::HDR_INTEGRATION_TIME3_US, hdr_integration_times_us[2]);
 27    cam.setControl(epc::ControlID::MODULATION_FREQ_HZ, modulation_freq);
 28    cam.setControl(epc::ControlID::MIN_AMPLITUDE, min_amplitude);
 29
 30    // start capturing frames
 31    ret = cam.startStream();
 32    if (ret != 0) {
 33        std::cerr << "Failed to start stream." << std::endl;
 34        return -1;
 35    }
 36
 37    std::cout << "Camera is running. Press any key to quit..." << std::endl;
 38
 39    // capture and display a frame every 10 ms if no key has been pressed
 40    while (cv::waitKey(10) < 0) {
 41
 42        // get the latest frame
 43        std::unique_ptr<epc::TOFFrame> frame;
 44        ret = cam.captureFrame(frame);
 45        if (ret != 0) {
 46            std::cerr << "Failed to capture frame." << std::endl;
 47            return -1;
 48        }
 49
 50        // create an OpenCV matrix from the image
 51        cv::Mat distance_raw(frame->getHeight(), frame->getWidth(), CV_16UC1);
 52        cv::Mat amplitude_raw(frame->getHeight(), frame->getWidth(), CV_16UC1);
 53        std::memcpy(distance_raw.data,
 54                    frame->get<epc::DistanceFrame>(0),
 55                    frame->getWidth() * frame->getHeight() * sizeof(uint16_t));
 56        std::memcpy(amplitude_raw.data,
 57                    frame->get<epc::AmplitudeFrame>(0),
 58                    frame->getWidth() * frame->getHeight() * sizeof(uint16_t));
 59
 60        cv::Mat distance_scaled, amplitude_scaled;
 61        cv::convertScaleAbs(distance_raw, distance_scaled, 0xff / max_distance);
 62        cv::convertScaleAbs(amplitude_raw, amplitude_scaled, 0xff / 3000.0f);
 63
 64        // apply colormap
 65        cv::Mat distance_colored, amplitude_colored;
 66        cv::applyColorMap(distance_scaled, distance_colored, cv::COLORMAP_JET);
 67        cv::applyColorMap(amplitude_scaled, amplitude_colored, cv::COLORMAP_VIRIDIS);
 68
 69        // upscale images for larger display
 70        cv::Mat distance_upscaled, amplitude_upscaled;
 71        cv::resize(distance_colored,
 72                   distance_upscaled,
 73                   cv::Size(frame->getWidth() * 2, frame->getHeight() * 2),
 74                   0,
 75                   0,
 76                   cv::INTER_NEAREST);
 77        cv::resize(amplitude_colored,
 78                   amplitude_upscaled,
 79                   cv::Size(frame->getWidth() * 2, frame->getHeight() * 2),
 80                   0,
 81                   0,
 82                   cv::INTER_NEAREST);
 83
 84        cv::imshow("TOFCam Distance", distance_upscaled);
 85        cv::imshow("TOFCam Amplitude", amplitude_upscaled);
 86    }
 87
 88    cv::destroyAllWindows();
 89
 90    // stop capturing frames
 91    ret = cam.stopStream();
 92    if (ret != 0) {
 93        std::cerr << "Failed to stop stream." << std::endl;
 94        return -1;
 95    }
 96
 97    // close the connection to the camera module
 98    ret = cam.close();
 99    if (ret != 0) {
100        std::cerr << "Failed to close the connection." << std::endl;
101        return -1;
102    }
103
104    std::cout << "Done." << std::endl;
105    return 0;
106}