(四)ROS2中利用只读取DS435摄像头的颜色数据,并用opencv进行可视化显示

在ros2实现D435的rs-color Sample

在本篇博客中我将详细的讲述如何然传输D435的颜色数据,并详细的进行实际的代码讲述、CAMKE文件的编写、并结合opencv进行实例的演示。

1、代码实现的主要功能,通过以下可以方便读者阅读理解代码。

此示例演示如何使用 C API 传输颜色数据并打印一些帧信息,例如帧号、时间戳、到达时间、时间戳域和帧数据的前 10 个字节。
这是一个RealSense相机的示例代码,用于初始化RealSense相机并捕获图像数据。以下是代码的主要步骤和功能:

1. 创建RealSense上下文对象 `rs2_context* ctx`,该对象用于管理连接的RealSense设备。

2. 查询连接的设备并获取设备列表,以便后续选择设备进行配置和捕获。

3. 创建RealSense设备对象 `rs2_device* dev`,并打印设备信息,以了解所连接设备的属性和功能。

4. 创建RealSense管道对象 `rs2_pipeline* pipeline`,用于配置、启动和停止相机流。

5. 创建配置对象 `rs2_config* config`,并启用所需的数据流类型、分辨率、帧率和格式,以配置相机捕获参数。

6. 启动管道流,配置所选的相机并开始捕获图像数据。

7. 进入主循环,在循环中不断等待新的图像帧数据。

8. 对每个捕获到的帧数据进行处理:
   - 从帧数据中提取彩色图像数据,并获取帧号、时间戳、时间戳域和时间到达元数据。
   - 打印帧数据的一些信息,如前10个字节的数据、帧号、时间戳等。
   - 释放帧对象,以释放其占用的内存资源。
9. 通过OPENCV来进行图像的可视化显示来显示读取的color图像信息。

10. 循环继续等待新的图像帧数据,直到应用程序被手动停止。

11. 最后,停止管道流、释放所有相关资源,包括管道配置、管道、设备、设备列表和上下文。

这个示例代码演示了如何使用Intel RealSense SDK来初始化RealSense相机、配置捕获参数、捕获图像数据,并进行一些基本的帧数据处理和输出。
代码中使用了一些RealSense SDK提供的函数和结构体来管理设备和帧数据,以及进行相应的错误处理。
通过这个示例代码,您可以学习如何使用RealSense SDK来构建自己的RealSense应用程序。
在本篇博客中我会详细的讲解代码,并进行参数的选择配置及其意义。

2、代码讲述

2.1、包含进行功能实现的头文件
#include <librealsense2/rs.h>
#include <librealsense2/h/rs_pipeline.h>
#include <librealsense2/h/rs_frame.h>

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "example.h"
2.2、进行相机的宏参配置定义
//
//                                    这些参数是可以重新配置的
//
#define STREAM          RS2_STREAM_COLOR  // rs2_stream是RealSense设备提供的一种数据类型       
	 //
#define FORMAT          RS2_FORMAT_RGB8   // rs2_format 识别二进制数据在帧内的编码方式这里是
	//
#define WIDTH           640               // 帧列数
	//
#define HEIGHT          480               // 帧行数
	//
#define FPS             30                // 帧率                    
	//
#define STREAM_INDEX    0                 // 定义流索引,用于同一类型的多个流
//
宏定义解释 STREAM RealSense相机支持多种不同类型的数据流(stream)。
STREAM 宏的值可以设置为以下不同的数据流类型之一,以满足您的应用需求。
这些不同的数据流类型用于不同的应用场景和用途。您可以根据您的需求选择适当的数据流类型,并在配置RealSense相机时使用相应的常量。
例如,如果您需要捕获彩色图像,可以使用 RS2_STREAM_COLOR;如果您需要深度数据,可以使用 RS2_STREAM_DEPTH。根据选择的数据流类型,相机会以不同的方式捕获和提供数据。
参数 解释
RS2_STREAM_COLOR 彩色图像流,用于捕获彩色图像。
RS2_STREAM_DEPTH 深度图像流,用于捕获深度图像或距离数据。
RS2_STREAM_INFRARED 红外图像流,用于捕获红外图像。
RS2_STREAM_CONFIDENCE 置信度图像流,用于捕获每个像素的深度数据置信度。
RS2_STREAM_FISHEYE 鱼眼图像流,用于捕获鱼眼图像。
RS2_STREAM_GYRO 陀螺仪数据流,用于捕获设备的陀螺仪数据。
RS2_STREAM_ACCEL 加速度计数据流,用于捕获设备的加速度计数据。
RS2_STREAM_POSE 相机姿态数据流,用于捕获设备的位置和方向信息。
RealSense相机支持多种不同的帧格式(format)。除了 RS2_FORMAT_RGB8 外,还有其他一些常见的帧格式,具体取决于相机和数据流类型。以下是一些常见的帧格式:
彩色帧格式:
RS2_FORMAT_RGB8:每个像素使用8位表示红色、绿色和蓝色通道。
RS2_FORMAT_BGR8:每个像素使用8位表示蓝色、绿色和红色通道。
RS2_FORMAT_RGBA8:每个像素使用8位表示红色、绿色、蓝色和透明度通道。
RS2_FORMAT_BGRA8:每个像素使用8位表示蓝色、绿色、红色和透明度通道。

深度帧格式:
RS2_FORMAT_Z16:每个像素使用16位表示深度值(以毫米为单位)。
RS2_FORMAT_DISPARITY32:每个像素使用32位表示视差值。
RS2_FORMAT_Y8:每个像素使用8位表示灰度值(适用于深度帧的灰度图像)。

红外帧格式:
RS2_FORMAT_Y8:每个像素使用8位表示灰度值。

其他帧格式:
RS2_FORMAT_MOTION_XYZ32F:用于陀螺仪和加速度计数据,每个像素使用32位浮点数表示。
#define STREAM_INDEX 0 这行代码定义了一个宏 STREAM_INDEX,并将其值设置为 0。它用于定义流的索引。
"标识同一类型的多个数据流" 意味着在一台RealSense相机中,可能会有多个具有相同类型的数据流可用。这些数据流可以是不同配置下的相同类型(例如,不同分辨率或帧率的彩色图像数据流),或者可以是来自不同传感器的相同类型数据流(例如,多个彩色摄像头)。

让我用一个更具体的示例来解释这一概念:

1、假设您有一台RealSense相机,该相机同时具有两个彩色摄像头,这两个摄像头都可以捕获彩色图像数据流。由于这两个摄像头都是彩色数据流,它们属于相同的数据流类型,但是它们可以位于不同的位置或有不同的配置。

在这种情况下,您可以使用数据流索引来区分这两个彩色摄像头的数据流。一个彩色摄像头的数据流可能使用索引 `0`,而另一个彩色摄像头的数据流可能使用索引 `1`。这样,您可以根据需要选择特定的数据流进行捕获和处理。

所以,"标识同一类型的多个数据流" 意味着您可以根据数据流的索引来区分和选择相机提供的不同数据流,以满足您的应用需求。

2、例如,如果有两个彩色摄像头流,您可以将一个数据流的 STREAM_INDEX 设置为 0,另一个数据流的 STREAM_INDEX 设置为 1,以区分它们。然后,您可以在代码中使用 STREAM_INDEX 来选择特定的数据流。

3、代码解读

在这里进行main函数里主要功能的讲解。
3.1、用于检查Intel RealSense摄像头库(librealsense2)中的错误。这个函数的主要目的是在调用RealSense 2库函数时检查是否发生了错误,并在发生错误时打印错误信息并退出程序。

 rs2_error* e = 0;

void check_error(rs2_error* e)
{
    
    
    if (e)
    {
    
    
        printf("rs_error was raised when calling %s(%s):\n", rs2_get_failed_function(e), rs2_get_failed_args(e));
        printf("    %s\n", rs2_get_error_message(e));
        
 //如果发生了错误,这个语句会导致程序退出,并返回一个失败的状态码EXIT_FAILURE,通常用于指示程序执行失败。
        exit(EXIT_FAILURE);
    }
}
3.2
    /*
    	目的是创建一个RealSense上下文对象,该对象用于管理所有连接的RealSense设备。
    	如果创建上下文对象成功,它将存储在 ctx 变量中,并可以在后续代码中使用。
    	如果创建失败,错误信息将被捕获并处理。
    */
rs2_context* ctx = rs2_create_context(RS2_API_VERSION, &e);
check_error(e);
3.3
    /*
    	这段代码的目的是执行设备查询操作,以获取连接到计算机上的所有RealSense设备的列表。
    	如果查询成功,设备列表将存储在 device_list 变量中,并可以在后续代码中使用。
    	如果查询失败,错误信息将被捕获并处理。
    */
rs2_device_list* device_list = rs2_query_devices(ctx, &e);
check_error(e);

int dev_count = rs_device_count(device_list, &e);
check_error(e);
printf("There are %d connected RealSense devices.\n", dev_count);
if (0 == dev_count)
    return EXIT_FAILURE;
3.4
    /*
    	这段代码的目的是从设备列表中选择并创建一个特定的RealSense设备对象,然后打印有关该设备的信息。
    	这有助于了解所连接设备的属性和功能,以便在后续的代码中配置和操作该设备。
    	如果创建设备对象或打印设备信息的过程中出现错误,错误信息将被捕获并处理。
    */
//0:这是设备的索引,表示你要连接到设备列表中的哪一个设备。在这里,索引为0表示连接到列表中的第一个设备。
rs2_device* dev = rs2_create_device(device_list, 0, &e);
check_error(e);

print_device_info(dev);

void print_device_info(rs2_device* dev)
{
    
    
    rs2_error* e = 0;
    printf("\nUsing device 0, an %s\n", rs2_get_device_info(dev, RS2_CAMERA_INFO_NAME, &e));
    check_error(e);
    printf("    Serial number: %s\n", rs2_get_device_info(dev, RS2_CAMERA_INFO_SERIAL_NUMBER, &e));
    check_error(e);
    printf("    Firmware version: %s\n\n", rs2_get_device_info(dev, RS2_CAMERA_INFO_FIRMWARE_VERSION, &e));
    check_error(e);
}
3.5、
    /*
    	这段代码的目的是创建一个RealSense管道对象,该对象用于配置、启动和停止相机流。
    	管道是一种用于管理相机数据流的高级抽象,允许您在一个对象中组合多个相机配置和处理步骤。
    	如果创建管道对象成功,它将存储在 pipeline 变量中,并可以在后续代码中使用。
    	如果创建失败,错误信息将被捕获并处理。
	一旦有了管道对象,您可以使用它来配置和控制RealSense相机的数据流,并在后续的代码中处理捕获的帧数据。 
    */
    rs2_pipeline* pipeline =  rs2_create_pipeline(ctx, &e);
    check_error(e);
3.6
    /*
    	这段代码的目的是创建一个RealSense配置对象,该对象用于指定和设置相机的硬件配置参数。
    	配置对象可以在后续的代码中用于定义所需的数据流类型、分辨率、帧率和格式,
    	以便根据应用程序的需求来配置RealSense相机。
    */
rs2_config* config = rs2_create_config(&e);
check_error(e);

    /*
    	这段代码的目的是在RealSense配置对象中启用指定的数据流,
    	以定义应用程序希望捕获的图像流类型、分辨率、帧率和格式。
    	配置对象可以在后续的代码中用于初始化管道对象,从而配置RealSense相机以开始捕获所需的图像数据。
    */
    // Request a specific configuration
rs2_config_enable_stream(config, STREAM, STREAM_INDEX, WIDTH, HEIGHT, FORMAT, FPS, &e);
check_error(e);
3.7、
    /*
    	段代码的目的是通过配置对象启动RealSense管道,以开始捕获数据流。
    	如果配置的方式无法启动管道或连接的设备不支持所需的数据流类型,它将打印错误消息并退出应用程序。
    	这有助于在配置相机和捕获数据时进行错误处理。
    */
rs2_pipeline_profile* pipeline_profile = rs2_pipeline_start_with_config(pipeline, config, &e);
    if (e)
    {
    
    
        printf("The connected device doesn't support color streaming!\n");
        exit(EXIT_FAILURE);
    }
3.8、主循环函数
   /*
        	这段代码用于从RealSense相机管道(pipeline)中获取一组帧数据。
        	一旦成功获取一组帧数据,这些帧数据将存储在 frames 变量中。
            每个帧可以包含彩色图像、深度图像或其他类型的数据,具体取决于相机的配置和支持的流类型。
        	接下来,可以遍历和处理这些帧数据,根据需要执行相应的图像处理、深度分析或其他操作。
        */
        rs2_frame* frames = rs2_pipeline_wait_for_frames(pipeline, RS2_DEFAULT_TIMEOUT, &e);
        check_error(e);
3.9、
        /*
        	这段代码用于获取一组嵌套帧(embedded frames)中包含的帧数量。
        	嵌套帧通常用于同步捕获不同类型的数据,例如彩色图像和深度图像。
        	一旦成功获取帧数量,变量 num_of_frames 将包含嵌套帧中包含的帧数。
        	每个帧可以包含不同类型的数据,例如彩色图像、深度图像等。
        	接下来,您可以使用循环遍历并处理每个帧的数据,以根据需要执行相应的操作。
        	如果只是开启了彩色图像流
            num_of_frames 等于1 表示您在一次捕获中只获取了一帧单一类型的图像数据,即彩色图像。
        */
        int num_of_frames = rs2_embedded_frames_count(frames, &e);
        check_error(e);
3.10、这里对每帧的具体数据进行提取
/*
            这段代码用于从一组帧数据中提取特定索引位置的帧(frame)
            一旦成功提取帧,该帧将存储在 frame 变量中。
            您可以使用帧对象的方法来访问帧中包含的数据,
            例如图像数据、时间戳等。帧的具体内容取决于帧的类型,例如彩色图像帧、深度图像帧等。
*/
rs2_frame* frame = rs2_extract_frame(frames, i, &e);
check_error(e);
3.11、对提取的每帧数据进行处理
/*
          这行代码用于获取彩色图像帧(Color Frame)中的图像数据。
          通过这行代码,您可以获得彩色图像帧的原始像素数据,这些数据通常以一维数组的形式存储,
          每个像素的通道值(如红色、绿色和蓝色通道)可能依次排列在数组中,
          具体排列方式可能因帧的格式而异。          
*/ 
const uint8_t* rgb_frame_data = (const uint8_t*)(rs2_get_frame_data(frame, &e));
check_error(e);

/*
          这段代码用于获取帧的帧号(frame number),并将其存储在 frame_number 变量中。	
          帧号通常是连续的整数,从0开始递增,但也可能因相机或捕获流的设置而异。
*/
unsigned long long frame_number = rs2_get_frame_number(frame, &e);
check_error(e);
3.11、时间域时间戳的获取
/*
            	这段代码用于获取帧的时间戳(frame timestamp),并将其存储在变量中。
*/
rs2_time_t frame_timestamp = rs2_get_frame_timestamp(frame, &e);
check_error(e);

/*
            	这段代码的目的是获取帧(frame)的时间戳域(timestamp domain)信息
            	时间戳域信息对于在多个数据源之间同步和排序帧非常重要。
            	它告诉您时间戳是相对于哪个时间基准计算的,以便在时间上对帧进行正确的排序和分析。
 */
rs2_timestamp_domain frame_timestamp_domain = rs2_get_frame_timestamp_domain(frame, &e);
            check_error(e);
//这行代码的目的是将帧的时间戳域(timestamp domain)枚举值转换为相应的字符串表示形式,以便于显示和分析。
const char* frame_timestamp_domain_str = rs2_timestamp_domain_to_string(frame_timestamp_domain);
				
// 这段代码的目的是获取帧(frame)的时间到达元数据
rs2_metadata_type frame_metadata_time_of_arrival = rs2_get_frame_metadata(frame, RS2_FRAME_METADATA_TIME_OF_ARRIVAL, &e);
            check_error(e);
3.12、利用opencv把读取的数据进行显示。不会用opencv的可以参考我的上一篇博客文章进行配置。

3.13、最后就是参数的打印和资源的释放
// 参数打印
            printf("RGB frame arrived.\n");
            printf("First 10 bytes: ");
            int i;
            for(i=0; i < 10; ++i)
                printf("%02x ", rgb_frame_data[i]);

            printf("\nFrame No: %llu\n", frame_number);
            printf("Timestamp: %f\n", frame_timestamp);
            printf("Timestamp domain: %s\n", frame_timestamp_domain_str);
            printf("Time of arrival: %lld\n\n", frame_metadata_time_of_arrival);
            rs2_release_frame(frame);

// Stop the pipeline streaming
 		   rs2_pipeline_stop(pipeline, &e);
  		  check_error(e);

// Release resources
  		  rs2_delete_pipeline_profile(pipeline_profile);
  		  rs2_delete_config(config);
   		  rs2_delete_pipeline(pipeline);
   		  rs2_delete_device(dev);
   		  rs2_delete_device_list(device_list);
   		  rs2_delete_context(ctx);

   		  return EXIT_SUCCESS;

4、在ros2中cmake文件的配置,及其遇到的问题

4.1 、问题描述
如果只在cmake文件里面加入find_package
find_package(realsense2 REQUIRED)
只加入find_package会出现以下问题
/usr/bin/ld: my_opencv.cpp:(.text+0x290): undefined reference to `rs2_create_config'
/usr/bin/ld: my_opencv.cpp:(.text+0x2ce): undefined reference to `rs2_config_enable_stream'
/usr/bin/ld: my_opencv.cpp:(.text+0x2f5): undefined reference to `rs2_pipeline_start_with_config'
/usr/bin/ld: my_opencv.cpp:(.text+0x32d): undefined reference to `rs2_pipeline_wait_for_frames'
/usr/bin/ld: my_opencv.cpp:(.text+0x350): undefined reference to `rs2_embedded_frames_count'
/usr/bin/ld: my_opencv.cpp:(.text+0x390): undefined reference to `rs2_extract_frame
出现以上错误的原因是
find_package(realsense2 REQUIRED)是一个重要的步骤,但仅仅依赖于它通常是不够的。
你还需要提供必要的配置信息,
例如通过设置realsense2_DIR来告诉CMake Realsense2库的位置,
以及通过include_directories和target_link_libraries来设置头文件路径和链接库。
这些步骤是确保你的项目能够正确与Realsense2库集成的必要步骤。
4.2、完整的cmake文件编写
#realsence 配置
set(realsense2_DIR /usr/share/realsense2)
find_package(realsense2 REQUIRED)

#realsence 配置
include_directories(${realsense2_INCLUDE_DIR})          #
target_link_libraries(my_opencv ${realsense2_LIBRARY})  #
#realsence 配置
#realsense2_DIR,该变量用于指定 Realsense2 库的配置文件所在的目录路径。通常情况下,Realsense2库会提供一个CMake配置文件,其中包含了有关库的信息,如头文件路径、库文件路径和其他链接信息。
#通过设置 realsense2_DIR 变量为 /usr/share/realsense2,你告诉CMake去这个目录下查找 Realsense2 库的配置文件。这是为了帮助CMake定位 Realsense2 库的配置信息,以便后续的 find_package(realsense2 REQUIRED) 命令可以成功找到并加载这些配置信息。

set(realsense2_DIR /usr/share/realsense2)
find_package(realsense2 REQUIRED)

add_executable(my_opencv src/my_opencv.cpp)

#realsence 配置
#realsense2_INCLUDE_DIR 是一个CMake变量,用于存储 Realsense2 库的头文件(即包含文件)所在的目录路径。
#一旦你执行了 find_package(realsense2 REQUIRED),你就可以使用 ${realsense2_INCLUDE_DIR} 来引用 Realsense2 头文件目录的路径,然后通过 include_directories(${realsense2_INCLUDE_DIR}) 将这个路径添加到你的项目中,以便 CMake 知道在哪里查找 Realsense2 头文件。
include_directories(${realsense2_INCLUDE_DIR})          #
#realsense2_LIBRARY 可以包含 Realsense2 库的库文件路径(例如共享库文件的完整路径)或库文件的名称(例如不包括路径的库文件名称)
#这一行代码将你的项目与Realsense2库链接起来,以便在编译时正确链接Realsense2库,并使你的项目能够使用Realsense2库的功能。
target_link_libraries(my_opencv ${realsense2_LIBRARY})  #

5、运行效果展示

上述代码进行编译运行其最终的数据通过OPENCV进行可视化展示,其结果如下。
这是参数信息打印

在这里插入图片描述

这是图片信息传递

在这里插入图片描述

6、完整代码

rs-color.c
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.

/* Include the librealsense C header files */
#include <librealsense2/rs.h>
#include <librealsense2/h/rs_pipeline.h>
#include <librealsense2/h/rs_frame.h>

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "example.h"



//                                     These parameters are reconfigurable                                        //

#define STREAM          RS2_STREAM_COLOR  // rs2_stream is a types of data provided by RealSense device           //
#define FORMAT          RS2_FORMAT_RGB8   // rs2_format identifies how binary data is encoded within a frame      //
#define WIDTH           640               // Defines the number of columns for each frame                         //
#define HEIGHT          480               // Defines the number of lines for each frame                           //
#define FPS             30                // Defines the rate of frames per second                                //
#define STREAM_INDEX    0                 // Defines the stream index, used for multiple streams of the same type //



int main()
{
    
    
    rs2_error* e = 0;

    // Create a context object. This object owns the handles to all connected realsense devices.
    // The returned object should be released with rs2_delete_context(...)
    rs2_context* ctx = rs2_create_context(RS2_API_VERSION, &e);
    check_error(e);

    /* Get a list of all the connected devices. */
    // The returned object should be released with rs2_delete_device_list(...)
    rs2_device_list* device_list = rs2_query_devices(ctx, &e);
    check_error(e);

    int dev_count = rs2_get_device_count(device_list, &e);
    check_error(e);
    printf("There are %d connected RealSense devices.\n", dev_count);
    if (0 == dev_count)
        return EXIT_FAILURE;

    // Get the first connected device
    // The returned object should be released with rs2_delete_device(...)
    rs2_device* dev = rs2_create_device(device_list, 0, &e);
    check_error(e);

    print_device_info(dev);

    // Create a pipeline to configure, start and stop camera streaming
    // The returned object should be released with rs2_delete_pipeline(...)
    rs2_pipeline* pipeline =  rs2_create_pipeline(ctx, &e);
    check_error(e);

    // Create a config instance, used to specify hardware configuration
    // The retunred object should be released with rs2_delete_config(...)
    rs2_config* config = rs2_create_config(&e);
    check_error(e);

    // Request a specific configuration
    rs2_config_enable_stream(config, STREAM, STREAM_INDEX, WIDTH, HEIGHT, FORMAT, FPS, &e);
    check_error(e);

    // Start the pipeline streaming
    // The retunred object should be released with rs2_delete_pipeline_profile(...)
    rs2_pipeline_profile* pipeline_profile = rs2_pipeline_start_with_config(pipeline, config, &e);
    if (e)
    {
    
    
        printf("The connected device doesn't support color streaming!\n");
        exit(EXIT_FAILURE);
    }

    while (1)
    {
    
    
        // This call waits until a new composite_frame is available
        // composite_frame holds a set of frames. It is used to prevent frame drops
        // The returned object should be released with rs2_release_frame(...)
        rs2_frame* frames = rs2_pipeline_wait_for_frames(pipeline, RS2_DEFAULT_TIMEOUT, &e);
        check_error(e);

        // Returns the number of frames embedded within the composite frame
        int num_of_frames = rs2_embedded_frames_count(frames, &e);
        check_error(e);

        int i;
        for (i = 0; i < num_of_frames; ++i)
        {
    
    
            // The retunred object should be released with rs2_release_frame(...)
            rs2_frame* frame = rs2_extract_frame(frames, i, &e);
            check_error(e);

            const uint8_t* rgb_frame_data = (const uint8_t*)(rs2_get_frame_data(frame, &e));
            check_error(e);

            unsigned long long frame_number = rs2_get_frame_number(frame, &e);
            check_error(e);

            rs2_time_t frame_timestamp = rs2_get_frame_timestamp(frame, &e);
            check_error(e);

            // Specifies the clock in relation to which the frame timestamp was measured
            rs2_timestamp_domain frame_timestamp_domain = rs2_get_frame_timestamp_domain(frame, &e);
            check_error(e);
            const char* frame_timestamp_domain_str = rs2_timestamp_domain_to_string(frame_timestamp_domain);

            rs2_metadata_type frame_metadata_time_of_arrival = rs2_get_frame_metadata(frame, RS2_FRAME_METADATA_TIME_OF_ARRIVAL, &e);
            check_error(e);

            printf("RGB frame arrived.\n");
            printf("First 10 bytes: ");
            int i;
            for(i=0; i < 10; ++i)
                printf("%02x ", rgb_frame_data[i]);

            printf("\nFrame No: %llu\n", frame_number);
            printf("Timestamp: %f\n", frame_timestamp);
            printf("Timestamp domain: %s\n", frame_timestamp_domain_str);
            printf("Time of arrival: %lld\n\n", frame_metadata_time_of_arrival);
            rs2_release_frame(frame);
        }

        rs2_release_frame(frames);
    }

    // Stop the pipeline streaming
    rs2_pipeline_stop(pipeline, &e);
    check_error(e);

    // Release resources
    rs2_delete_pipeline_profile(pipeline_profile);
    rs2_delete_config(config);
    rs2_delete_pipeline(pipeline);
    rs2_delete_device(dev);
    rs2_delete_device_list(device_list);
    rs2_delete_context(ctx);

    return EXIT_SUCCESS;
}
example.h
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.

#include <librealsense2/rs.h>
#include <stdio.h>
#include <stdlib.h>

/* Function calls to librealsense may raise errors of type rs_error*/
void check_error(rs2_error* e)
{
    
    
    if (e)
    {
    
    
        printf("rs_error was raised when calling %s(%s):\n", rs2_get_failed_function(e), rs2_get_failed_args(e));
        printf("    %s\n", rs2_get_error_message(e));
        exit(EXIT_FAILURE);
    }
}

void print_device_info(rs2_device* dev)
{
    
    
    rs2_error* e = 0;
    printf("\nUsing device 0, an %s\n", rs2_get_device_info(dev, RS2_CAMERA_INFO_NAME, &e));
    check_error(e);
    printf("    Serial number: %s\n", rs2_get_device_info(dev, RS2_CAMERA_INFO_SERIAL_NUMBER, &e));
    check_error(e);
    printf("    Firmware version: %s\n\n", rs2_get_device_info(dev, RS2_CAMERA_INFO_FIRMWARE_VERSION, &e));
    check_error(e);
}

猜你喜欢

转载自blog.csdn.net/qq_45907168/article/details/133124230