双目立体视觉- ZED2双目视觉Examples for Beginner (Cpp/Liunx) - 上篇
Posted Techblog of HaoWANG
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双目立体视觉- ZED2双目视觉Examples for Beginner (Cpp/Liunx) - 上篇相关的知识,希望对你有一定的参考价值。
目录
Tutorial 3: Depth sensing with the ZED
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
- First, download the latest version of the ZED SDK on stereolabs.com.
- For more information, read the ZED API documentation.
Prerequisites
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
- First, download the latest version of the ZED SDK on stereolabs.com.
- For more information, read the ZED API documentation.
Prerequisites
Build the program
Download the sample and follow the instructions below: More
Build for Windows
Create a "build" folder in the source folderOpen cmake-gui and select the source and build foldersGenerate the Visual StudioWin64
solutionOpen the resulting solution and change configuration toRelease
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
Build the program
Download the sample and follow the instructions below: More
Build for Windows
Create a "build" folder in the source folderOpen cmake-gui and select the source and build foldersGenerate the Visual StudioWin64
solutionOpen the resulting solution and change configuration toRelease
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) - 上篇