双目立体视觉- ZED2双目视觉Examples for Beginner (Cpp/Liunx) - 上篇

Posted Techblog of HaoWANG

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双目立体视觉- ZED2双目视觉Examples for Beginner (Cpp/Liunx) - 上篇相关的知识,希望对你有一定的参考价值。

 

目录

Tutorial 1: Hello ZED

Getting started

Prerequisites

Build the program

Code overview

Camera Configuration

Getting Camera Information

Tutorial 2: Image capture

Getting started

Prerequisites

Build the program

Code overview

Create a camera

Capture data

Tutorial 3: Depth sensing with the ZED

Prerequisites

Build the program

Code overview

Create a camera

Capture data


 

Tutorial 1: Hello ZED

This tutorial simply shows how to configure and open the ZED, then print its serial number and then close the camera. This is the most basic step and a good start for using the ZED SDK.

Getting started

Prerequisites

  • Windows 10, Ubuntu LTS, L4T
  • ZED SDK and its dependencies (CUDA)

Build the program

Download the sample and follow the instructions below: More

Build for Windows

  • Create a "build" folder in the source folder
  • Open cmake-gui and select the source and build folders
  • Generate the Visual Studio Win64 solution
  • Open the resulting solution and change configuration to Release
  • Build solution

Build for Linux

Open a terminal in the sample directory and execute the following command:

mkdir build
cd build
cmake ..
make

Code overview

The ZED API provides low-level access to camera control and configuration. To use the ZED in your application, you will need to create and open a Camera object. The API can be used with two different video inputs: the ZED live video (Live mode) or video files recorded in SVO format with the ZED API (Playback mode).


Camera Configuration


#include <sl/Camera.hpp>

using namespace sl;

int main(int argc, char **argv) {

    // Create a ZED camera object
    Camera zed;

    // Open the camera
    ERROR_CODE returned_state = zed.open();
    if (returned_state != ERROR_CODE::SUCCESS) {
        std::cout << "Error " << returned_state << ", exit program.\\n";
        return EXIT_FAILURE;
    }

    // Get camera information (ZED serial number)
    auto camera_infos = zed.getCameraInformation();
    printf("Hello! This is my serial number: %d\\n", camera_infos.serial_number);

    // Close the camera
    zed.close();
    return EXIT_SUCCESS;
}

To configure the camera, create a Camera object and specify your InitParameters. Initial parameters let you adjust camera resolution, FPS, depth sensing parameters and more. These parameters can only be set before opening the camera and cannot be changed while the camera is in use.

// Create a ZED camera object
Camera zed;

// Set configuration parameters
InitParameters init_params;
init_params.camera_resolution = RESOLUTION::HD1080 ;
init_params.camera_fps = 30 ;

InitParameters contains a configuration by default. To get the list of available parameters, see API documentation.

Once initial configuration is done, open the camera.

// Open the camera
err = zed.open(init_params);
if (err != ERROR_CODE::SUCCESS)
    exit(-1);

You can set the following initial parameters:

  • Camera configuration parameters, using the camera_* entries (resolution, image flip...).
  • SDK configuration parameters, using the sdk_* entries (verbosity, GPU device used...).
  • Depth configuration parameters, using the depth_* entries (depth mode, minimum distance...).
  • Coordinate frames configuration parameters, using the coordinate_* entries (coordinate system, coordinate units...).
  • SVO parameters to use Stereolabs video files with the ZED SDK (filename, real-time mode...)

Getting Camera Information

Camera parameters such as focal length, field of view or stereo calibration can be retrieved for each eye and resolution:

  • Focal length: fx, fy.
  • Principal points: cx, cy.
  • Lens distortion: k1, k2.
  • Horizontal and vertical field of view.
  • Stereo calibration: rotation and translation between left and right eye.

Those values are available in CalibrationParameters. They can be accessed using getCameraInformation().

In this tutorial, we simplfy retrieve the serial number of the camera:

// Get camera information (serial number)
int zed_serial = zed.getCameraInformation().serial_number;
printf("Hello! This is my serial number: %d\\n", zed_serial);

In the console window, you should now see the serial number of the camera (also available on a sticker on the ZED USB cable).

Note: `CameraInformation` also contains the firmware version of the ZED, as well as calibration parameters.

To close the camera properly, use zed.close() and exit the program.

// Close the camera
zed.close();
return 0;
CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
PROJECT(ZED_Tutorial_1)

option(LINK_SHARED_ZED "Link with the ZED SDK shared executable" ON)

if (NOT LINK_SHARED_ZED AND MSVC)
    message(FATAL_ERROR "LINK_SHARED_ZED OFF : ZED SDK static libraries not available on Windows")
endif()

if(COMMAND cmake_policy)
	cmake_policy(SET CMP0003 OLD)
	cmake_policy(SET CMP0015 OLD)
endif(COMMAND cmake_policy)

if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
SET(CMAKE_BUILD_TYPE "RelWithDebInfo")
endif()

SET(EXECUTABLE_OUTPUT_PATH ".")

find_package(ZED 3 REQUIRED)
find_package(CUDA ${ZED_CUDA_VERSION} EXACT REQUIRED)

include_directories(${CUDA_INCLUDE_DIRS})
include_directories(${ZED_INCLUDE_DIRS})

link_directories(${ZED_LIBRARY_DIR})
link_directories(${CUDA_LIBRARY_DIRS})

ADD_EXECUTABLE(${PROJECT_NAME} main.cpp)
add_definitions(-std=c++14 -O3)

if (LINK_SHARED_ZED)
    SET(ZED_LIBS ${ZED_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_CUDART_LIBRARY})
else()
    SET(ZED_LIBS ${ZED_STATIC_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_LIBRARY})
endif()

TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${ZED_LIBS})

 


Tutorial 2: Image capture

This tutorial shows how to capture left images of the ZED camera. The program will loop until we have successfully grabbed 50 images. We assume that you have read the tutorial 1 and successfully opened your ZED.

Getting started

Prerequisites

  • Windows 10, Ubuntu LTS, L4T
  • ZED SDK and its dependencies (CUDA)

Build the program

Download the sample and follow the instructions below: More

Build for Windows

  • Create a "build" folder in the source folder
  • Open cmake-gui and select the source and build folders
  • Generate the Visual Studio Win64 solution
  • Open the resulting solution and change configuration to Release
  • Build solution

Build for Linux

Open a terminal in the sample directory and execute the following command:

mkdir build
cd build
cmake ..
make

Code overview


#include <sl/Camera.hpp>

using namespace std;
using namespace sl;

int main(int argc, char **argv) {

    // Create a ZED camera object
    Camera zed;

    // Set configuration parameters
    InitParameters init_parameters;
    init_parameters.camera_resolution = RESOLUTION::HD1080; // Use HD1080 video mode
    init_parameters.camera_fps = 30; // Set fps at 30

    // Open the camera
    auto returned_state = zed.open(init_parameters);
    if (returned_state != ERROR_CODE::SUCCESS) {
        cout << "Error " << returned_state << ", exit program." << endl;
        return EXIT_FAILURE;
    }

    // Capture 50 frames and stop
    int i = 0;
    sl::Mat image;
    while (i < 50) {
        // Grab an image
        returned_state = zed.grab();
        // A new image is available if grab() returns ERROR_CODE::SUCCESS
        if (returned_state == ERROR_CODE::SUCCESS) {

            // Get the left image
            zed.retrieveImage(image, VIEW::LEFT);
            
            // Display the image resolution and its acquisition timestamp
            cout<<"Image resolution: "<< image.getWidth()<<"x"<<image.getHeight() <<" || Image timestamp: "<<image.timestamp.data_ns<<endl;
            i++;
        }
    }

    // Close the camera
    zed.close();
    return EXIT_SUCCESS;
}

Create a camera

As with previous tutorial, we create, configure and open the ZED. Here we show how to set a resolution and a framerate. We want to work in H1080 at 30 fps (default) in this example.

// Create a ZED camera object
Camera zed;

// Set configuration parameters
InitParameters init_params;
init_params.camera_resolution = RESOLUTION_HD1080; // Use HD1080 video mode
init_params.camera_fps = 30; // Set fps at 30

// Open the camera
ERROR_CODE err = zed.open(init_params);
if (err != ERROR_CODE::SUCCESS)
    exit(-1);

Capture data

Now that the ZED is opened, we can now capture the images coming from it. We create a loop that capture 50 images and exit.

To capture an image and process it, you need to call Camera::grab() function. This function take runtime parameters as well, but we leave them to default in this tutorial. Each time you want a new image, you need to call this function. if grab() returns ERROR_CODE::SUCCESS, a new image has been capture and is now available. Otherwise, you can check the status of grab() which will tell you if there is no new frame available (depending on the framerate of the camera) or if something wrong happened.

// Grab an image
if (zed.grab() == ERROR_CODE::SUCCESS) {
	// A new image is available if grab() returns ERROR_CODE::SUCCESS
}

Once grab has been done, you can get all the data provided with the ZED SDK. In this tutorial, we want to retrieve the left image and its timestamp. To do so, we use the Camera::retrieveImage() and Camera::getCameraTimestamp() functions.

zed.retrieveImage(image,VIEW_LEFT); // Get the left image
unsigned long long timestamp = zed.getCameraTimestamp(); // Get the timestamp of the image
printf("Image resolution: %d x %d  || Image timestamp: %llu\\n", image.getWidth(), image.getHeight(), timestamp);

retrieveImage() takes a sl::Mat as parameter, as well as a VIEW mode. We first need to create the Mat before starting the loop. Note that creating a Mat does not allocate its memory, therefore the first retrieveImage() will automatically allocate its memory for us.

Since we want to stop the loop once we capture 50 images, we just increment the counter when a grab is successful.

// Capture 50 frames and stop
int i = 0;
sl::Mat image;
while (i < 50) {
    // Grab an image
    if (zed.grab() == ERROR_CODE::SUCCESS) {
        // A new image is available if grab() returns ERROR_CODE::SUCCESS
        zed.retrieveImage(image, VIEW::LEFT); // Get the left image
        auto timestamp = zed.getTimestamp(sl::TIME_REFERENCE::IMAGE); // Get the timestamp at the time the image was captured
        printf("Image resolution: %d x %d  || Image timestamp: %llu\\n", image.getWidth(), image.getHeight(), timestamp);
        i++;
    }
}

Note: the image timestamp is given in nanoseconds. You can compare the timestamp between two grab() : it should be close to the framerate time, if you don't have frames dropped.

Now that we have captured 50 images, we can close the camera and exit the program.

// Close the camera
zed.close();
return 0;
CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
PROJECT(ZED_Tutorial_2)

option(LINK_SHARED_ZED "Link with the ZED SDK shared executable" ON)

if (NOT LINK_SHARED_ZED AND MSVC)
    message(FATAL_ERROR "LINK_SHARED_ZED OFF : ZED SDK static libraries not available on Windows")
endif()

if(COMMAND cmake_policy)
	cmake_policy(SET CMP0003 OLD)
	cmake_policy(SET CMP0015 OLD)
endif(COMMAND cmake_policy)

if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
SET(CMAKE_BUILD_TYPE "RelWithDebInfo")
endif()

SET(EXECUTABLE_OUTPUT_PATH ".")

find_package(ZED 3 REQUIRED)
find_package(CUDA ${ZED_CUDA_VERSION} EXACT REQUIRED)

include_directories(${CUDA_INCLUDE_DIRS})
include_directories(${ZED_INCLUDE_DIRS})

link_directories(${ZED_LIBRARY_DIR})
link_directories(${CUDA_LIBRARY_DIRS})

ADD_EXECUTABLE(${PROJECT_NAME} main.cpp)
add_definitions(-std=c++14 -O3)

if (LINK_SHARED_ZED)
    SET(ZED_LIBS ${ZED_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_CUDART_LIBRARY})
else()
    SET(ZED_LIBS ${ZED_STATIC_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_LIBRARY})
endif()

TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${ZED_LIBS})

Tutorial 3: Depth sensing with the ZED

This tutorial shows how to get the depth from the ZED SDK. The program will loop until 50 frames are grabbed. We assume that you have followed previous tutorials (opening the ZED and image capture).

Prerequisites

  • Windows 10, Ubuntu LTS, L4T
  • ZED SDK and its dependencies (CUDA)

Build the program

Download the sample and follow the instructions below: More

Build for Windows

  • Create a "build" folder in the source folder
  • Open cmake-gui and select the source and build folders
  • Generate the Visual Studio Win64 solution
  • Open the resulting solution and change configuration to Release
  • Build solution

Build for Linux

Open a terminal in the sample directory and execute the following command:

mkdir build
cd build
cmake ..
make

Code overview

#include <sl/Camera.hpp>

using namespace std;
using namespace sl;

int main(int argc, char **argv) {

    // Create a ZED camera object
    Camera zed;

    // Set configuration parameters
    InitParameters init_parameters;
    init_parameters.depth_mode = DEPTH_MODE::PERFORMANCE; // Use PERFORMANCE depth mode
    init_parameters.coordinate_units = UNIT::MILLIMETER; // Use millimeter units (for depth measurements)

    // Open the camera
    auto returned_state = zed.open(init_parameters);
    if (returned_state != ERROR_CODE::SUCCESS) {
        cout << "Error " << returned_state << ", exit program." << endl;
        return EXIT_FAILURE;
    }

    // Set runtime parameters after opening the camera
    RuntimeParameters runtime_parameters;
    runtime_parameters.sensing_mode = SENSING_MODE::STANDARD; // Use STANDARD sensing mode

    // Capture 50 images and depth, then stop
    int i = 0;
    sl::Mat image, depth, point_cloud;

    while (i < 50) {
        // A new image is available if grab() returns ERROR_CODE::SUCCESS
        if (zed.grab(runtime_parameters) == ERROR_CODE::SUCCESS) {
            // Retrieve left image
            zed.retrieveImage(image, VIEW::LEFT);
            // Retrieve depth map. Depth is aligned on the left image
            zed.retrieveMeasure(depth, MEASURE::DEPTH);
            // Retrieve colored point cloud. Point cloud is aligned on the left image.
            zed.retrieveMeasure(point_cloud, MEASURE::XYZRGBA);

            // Get and print distance value in mm at the center of the image
            // We measure the distance camera - object using Euclidean distance
            int x = image.getWidth() / 2;
            int y = image.getHeight() / 2;
            sl::float4 point_cloud_value;
            point_cloud.getValue(x, y, &point_cloud_value);

            if(std::isfinite(point_cloud_value.z)){
                float distance = sqrt(point_cloud_value.x * point_cloud_value.x + point_cloud_value.y * point_cloud_value.y + point_cloud_value.z * point_cloud_value.z);
                cout<<"Distance to Camera at {"<<x<<";"<<y<<"}: "<<distance<<"mm"<<endl;
            }else
                cout<<"The Distance can not be computed at {"<<x<<";"<<y<<"}"<<endl;           

            // Increment the loop
            i++;
        }
    }
    // Close the camera
    zed.close();
    return EXIT_SUCCESS;
}

Create a camera

As in other tutorials, we create, configure and open the ZED. We set the ZED in HD720 mode at 60fps and enable depth in PERFORMANCE mode. The ZED SDK provides different depth modes: PERFORMANCE, QUALITY, ULTRA. For more information, see online documentation.

// Create a ZED camera
Camera zed;

// Create configuration parameters
InitParameters init_params;
init_params.sdk_verbose = true; // Enable the verbose mode
init_params.depth_mode = DEPTH_MODE::PERFORMANCE; // Set the depth mode to performance (fastest)
init_params.coordinate_units = UNIT::MILLIMETER; // Use millimeter units


// Open the camera
ERROR_CODE err = zed.open(init_params);
if (err != ERROR_CODE::SUCCESS) {
    std::cout << "Error " << err << ", exit program.\\n"; // Display the error
    return -1;
}

Note: Default parameter for depth mode is DEPTH_MODE::PERFORMANCE. In practice, it is not necessary to set the depth mode in InitParameters.

Capture data

Now that the ZED is opened, we can capture images and depth. Here we loop until we have successfully captured 50 images. Retrieving the depth map is as simple as retrieving an image:

  • We create a Mat to store the depth map.
  • We call retrieveMeasure() to get the depth map.
  • We call retrieveMeasure() to get the point cloud.
// Capture 50 images and depth, then stop
int i = 0;
sl::Mat image, depth;
while (i < 50) {
    // Grab an image
    if (zed.grab(runtime_parameters) == ERROR_CODE::SUCCESS) {

        // A new image is available if grab() returns ERROR_CODE::SUCCESS
        zed.retrieveImage(image, VIEW::LEFT); // Get the left image
        zed.retrieveMeasure(depth, MEASURE::DEPTH); // Retrieve depth Mat. Depth is aligned on the left image
        zed.retrieveMeasure(point_cloud, MEASURE::XYZRGBA);
        i++;
    }
}

Now that we have retrieved the point cloud, we may want to get the distance to a specific pixel. In the example, we extract the distance of the point at the center of the image (width/2, height/2)

// Get and print distance value in mm at the center of the image
// We measure the distance camera - object using Euclidean distance
int x = image.getWidth() / 2;
int y = image.getHeight() / 2;
sl::float4 point_cloud_value;
point_cloud.getValue(x, y, &point_cloud_value);

float distance = sqrt(point_cloud_value.x*point_cloud_value.x + point_cloud_value.y*point_cloud_value.y + point_cloud_value.z*point_cloud_value.z);
printf("Distance to Camera at (%d, %d): %f mm\\n", x, y, distance);

If we want to use the depth map instead of the point cloud, you can get a depth value with the following code.

int x = image.getWidth() / 2;
int y = image.getHeight() / 2;
float depth_value;
depth.getValue(x,y, depth_value);
printf("Depth to Camera at (%d, %d): %f mm\\n", x, y, depth_value);

Once 50 frames have been grabbed, we close the camera.

// Close the camera
zed.close();

You are now using the ZED as a depth sensor.You can move on to the next tutorial to learn how to use the ZED as a positional tracker.

 

 

以上是关于双目立体视觉- ZED2双目视觉Examples for Beginner (Cpp/Liunx) - 上篇的主要内容,如果未能解决你的问题,请参考以下文章

双目立体视觉- ZED2双目视觉Examples for Beginner (Cpp/Liunx) - 下篇

双目立体视觉- ZED2双目视觉Examples for Beginner (Cpp/Liunx) - 下篇

双目立体视觉- ZED2双目视觉Examples for Beginner (Cpp/Liunx) - 上篇

双目立体视觉- ZED2双目视觉Examples for Beginner (Cpp/Liunx) - 上篇

双目立体视觉- ZED2 ROS 双目视觉开发理论与实践 2

双目立体视觉- ZED2 ROS 双目视觉开发理论与实践 2