手把手带你死磕ORBSLAM3源代码(二)stereo_inertial_realsense_D435i.cc调用导入库详解

发布时间:2023年12月20日

一.简介

??? stereo_inertial_realsense_D435i.cc代码位于Examples目录下的Stereo-Inertial文件夹。

??? 采用双目惯导实现,硬件采用realsenseD435i相机。

??? 相机照片如下:

二.代码死磕

2.1代码导入

#include <signal.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <fstream>
#include <chrono>
#include <ctime>
#include <sstream>

#include <condition_variable>

#include <opencv2/core/core.hpp>

#include <librealsense2/rs.hpp>
#include "librealsense2/rsutil.h"

#include <System.h>

2.1.1 signal介绍

??? signal.h是C语言标准库中的一部分,它提供了处理程序运行期间引发的各种异常条件的功能。这个库包含了处理信号的函数,信号是用于进程间通信的一种机制,可以报告异常行为(如除零)或用户的一些按键组合(如同时按下Ctrl与C键,产生信号SIGINT)。

??? signal.h函数包括signal(),决定了如何处理后续的信号。如果handler的值是SIG_DFL,则采用由实现定义的默认行为;如果handler的值是SIG_IGN,则忽略该信号;否则,调用handler指向的函数(以信号作为参数)。当随后碰到信号sig时,该信号将恢复为默认行为,随后调用信号处理程序,就好像由(*handler)(sig)调用的一样。

2.1.2 stdlib介绍

??? stdlib.h是C和C++编程语言中的一个标准库文件,全称为“Standard Library”(标准库)。它包含了C和C++语言中最常用的系统函数,这些函数可用于内存分配、随机数生成、字符串操作等多种操作。

??? stdlib.h中定义了五种类型,包括size_t、wchar_t、div_t、ldiv_t和lldiv_t,以及一些宏,如EXIT_FAILURE、EXIT_SUCCESS、RAND_MAX和MB_CUR_MAX等。同时,stdlib.h库中提供了许多实用的函数,如malloc()和free()用于动态内存分配和释放,rand()和srand()用于生成随机数,atoi()等函数用于字符串转换。

??? 总的来说,stdlib.h库在C/C++编程中起着重要的作用,可以大大简化编程过程,并提高代码的运行效率。

2.1.3 iostream介绍

??? iostream是C++中用于输入输出的库,它包括istream和ostream两个类型,分别表示输入流和输出流。流是指从某种IO设备上读出或写入的字符序列。在iostream库中,标准库定义了4个IO对象,处理输入时使用命名为cin的istream类型对象,这个对象也称为标准输入。处理输出时使用命名为cout的ostream类型对象,这个对象也称为标准输出。此外,iostream库还定义了另外两个ostream对象,分别命名为cerr和clog。

2.1.4 algorithm介绍

? #include <algorithm>是C++标准库中的一个头文件,它包含了大量的标准模板库(STL)算法。这些算法用于对容器(如数组、向量、列表等)中的元素进行排序、查找、替换、合并等操作。

<algorithm>头文件中,常见的算法包括:

  1. 排序算法:如std::sortstd::stable_sortstd::partial_sort等,用于对容器中的元素进行排序。
  2. 查找算法:如std::findstd::find_ifstd::find_if_not等,用于在容器中查找特定的元素。
  3. 替换算法:如std::replacestd::replace_if等,用于替换容器中满足特定条件的元素。
  4. 合并算法:如std::merge,用于合并两个已排序的容器。
  5. 其他常用算法:如std::reverse(反转容器中的元素)、std::rotate(旋转容器中的元素)、std::partition(根据条件对容器进行划分)等。

使用这些算法可以大大简化代码,提高代码的可读性和可维护性。在使用这些算法时,通常需要提供一个迭代器范围(即起始迭代器和结束迭代器),以及一个用于比较元素大小的函数(如std::less<int>)。

2.1.5 fstream介绍

#include <fstream>是C++标准库中的一个头文件,它提供了文件流的功能,用于对文件进行读写操作。

<fstream>头文件中,定义了三种类型的文件流:

  1. std::ifstream:输入文件流,用于从文件中读取数据。
  2. std::ofstream:输出文件流,用于向文件中写入数据。
  3. std::fstream:输入/输出文件流,既可用于读取数据,也可用于写入数据。

使用这些文件流,可以打开、读取、写入和关闭文件。例如,以下是一个简单的示例,演示如何使用std::ifstream从文件中读取数据:

#include <iostream>  
#include <fstream>  
#include <string>  
  
int main() {  
    std::ifstream file("example.txt"); // 打开文件  
    if (file.is_open()) { // 检查文件是否成功打开  
        std::string line;  
        while (std::getline(file, line)) { // 逐行读取文件内容  
            std::cout << line << std::endl; // 输出每一行内容  
        }  
        file.close(); // 关闭文件  
    } else {  
        std::cerr << "Failed to open file" << std::endl; // 文件打开失败  
    }  
    return 0;  
}

2.1.6 chrono介绍

#include <chrono>是C++标准库中的一个头文件,它提供了时间相关的功能和类。这个头文件提供了高精度计时器的支持,可以用于测量代码执行时间、延迟、时间间隔等。

<chrono>头文件中,主要提供了以下几个方面的功能:

  1. 时间点:std::chrono::system_clock::time_point表示一个绝对时间点,使用系统时钟的历元来表示。
  2. 时间间隔:std::chrono::duration表示一段时间间隔,可以表示任何类型的时间单位(如秒、毫秒、微秒等),并可以与时间点进行加减运算。
  3. 时间流:std::chrono::time_point_caststd::chrono::duration_cast可以将时间点或时间间隔转换为指定的时间单位。
  4. 计时器:std::chrono::high_resolution_clock是一个高精度计时器,可以用于测量代码执行时间。

以下是一个简单的示例,演示如何使用<chrono>头文件测量代码执行时间:

#include <iostream>  
#include <chrono>  
  
int main() {  
    auto start = std::chrono::high_resolution_clock::now(); // 记录开始时间  
    // 执行需要计时的代码  
    // ...  
    auto end = std::chrono::high_resolution_clock::now(); // 记录结束时间  
    std::chrono::duration<double> elapsed = end - start; // 计算执行时间  
    std::cout << "Elapsed time: " << elapsed.count() << " seconds" << std::endl; // 输出执行时间  
    return 0;  
}

2.1.7 ctime介绍

#include <ctime>是C++标准库中的一个头文件,它提供了与时间相关的函数和数据类型。这个头文件主要用于获取和操作系统时间。

<ctime>头文件中,主要提供了以下几个方面的功能:

  1. 时间获取:std::time()函数用于获取当前的系统时间,返回一个表示当前时间的time_t类型的值。
  2. 时间转换:std::gmtime()函数用于将一个time_t类型的值转换为对应的UTC时间,返回一个指向struct tm的指针。std::localtime()函数用于将一个time_t类型的值转换为对应的本地时间,返回一个指向structtm的指针。
  3. 时间格式化:std::strftime()函数用于将时间格式化为指定的字符串,返回一个指向格式化后的字符串的指针。
  4. 字符串解析:std::strptime()函数用于将格式化的字符串解析为时间,返回一个指向解析结果的指针。
  5. 日期计算:std::mktime()函数用于将一个structtm结构体转换为对应的time_t类型的值。

以下是一个简单的示例,演示如何使用<ctime>头文件获取和格式化当前时间:

#include <iostream>  
#include <ctime>  
  
int main() {  
    time_t now = time(0); // 获取当前时间  
    struct tm *tm_now = localtime(&now); // 转换为本地时间  
    char time_str[50];  
    strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_now); // 格式化时间  
    std::cout << "Current time: " << time_str << std::endl; // 输出当前时间  
    return 0;  
}

2.1.8 sstream介绍

#include <sstream>是C++标准库中的一个头文件,它提供了字符串流(string stream)的功能,用于对字符串进行格式化和解析。

<sstream>头文件中,主要提供了以下几个方面的功能:

  1. 字符串流:std::stringstream类是一个字符串流,可以像其他流(如std::cout)一样进行读写操作。使用std::stringstream可以对字符串进行格式化、拼接、分割等操作。
  2. 格式化:std::stringstream支持使用插入运算符(<<)将数据插入到流中,并使用提取运算符(>>)从流中提取数据。可以设置流的格式化选项,如浮点数的小数位数、整数基数等。
  3. 字符串拼接:std::stringstream支持使用operator+进行字符串拼接,可以将两个字符串流连接起来。
  4. 字符串分割:std::stringstream支持使用std::stringstream::getline()函数从流中读取一行数据,并使用std::stringstream::read()函数读取指定长度的数据。可以将字符串流中的数据分割成多个子串。

以下是一个简单的示例,演示如何使用<sstream>头文件将一个整数转换为字符串,并进行格式化:

#include <iostream>  
#include <sstream>  
  
int main() {  
    int number = 12345;  
    std::stringstream ss;  
    ss << std::setw(10) << std::setfill('0') << std::right << number;  
    std::string formattedNumber = ss.str();  
    std::cout << "Formatted number: " << formattedNumber << std::endl; // 输出结果为"000000012345"  
    return 0;  
}

2.1.9 condition_variable介绍

#include <condition_variable>是C++标准库中的一个头文件,它提供了条件变量的功能,用于在多线程编程中实现线程间的同步。

条件变量是一种同步机制,它允许一个或多个线程等待某个条件成立,直到其他线程通知它们条件已经满足。在C++中,std::condition_variable类提供了条件变量的接口。

std::condition_variable类具有以下主要成员函数:

  1. wait():阻塞当前线程,直到其他线程调用notify_one()notify_all()函数。
  2. wait_for():阻塞当前线程一段时间,直到其他线程调用notify_one()notify_all()函数。
  3. wait_until():阻塞当前线程直到到达指定的时间点,或者直到其他线程调用notify_one()notify_all()函数。
  4. notify_one():唤醒一个正在等待的线程。
  5. notify_all():唤醒所有正在等待的线程。

使用条件变量时,通常需要配合互斥锁(如std::mutex)使用,以确保在访问共享数据时不会被其他线程同时访问。以下是一个简单的示例,演示了如何使用条件变量实现线程间的同步:

#include <iostream>  
#include <thread>  
#include <mutex>  
#include <condition_variable>  
  
std::mutex mtx;  
std::condition_variable cv;  
int count = 0;  
  
void increment() {  
    std::unique_lock<std::mutex> lock(mtx);  
    while (count < 10) {  
        std::cout << count << std::endl;  
        ++count;  
        cv.wait(lock); // 等待其他线程调用notify_one()或notify_all()  
    }  
    cv.notify_one(); // 通知一个正在等待的线程  
}  
  
void decrement() {  
    std::unique_lock<std::mutex> lock(mtx);  
    while (count > 0) {  
        --count;  
        cv.notify_one(); // 通知一个正在等待的线程  
        cv.wait(lock); // 等待其他线程调用notify_one()或notify_all()  
    }  
    cv.notify_all(); // 通知所有正在等待的线程  
}  
  
int main() {  
    std::thread incrementThread(increment);  
    std::thread decrementThread(decrement);  
    incrementThread.join();  
    decrementThread.join();  
    return 0;  
}

2.1.10 opencv2/core/core.hpp介绍

#include <opencv2/core/core.hpp> 是OpenCV库中的一个头文件,它包含了OpenCV核心功能模块的接口和类。OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,广泛应用于图像处理、计算机视觉、机器学习等领域。

<opencv2/core/core.hpp> 提供了许多基本的数据结构和算法,用于图像处理和计算机视觉任务。以下是一些主要的功能和类:

  1. Mat 类:这是OpenCV中最常用的数据结构,用于存储图像、矩阵等数据。它提供了许多操作和函数,如读取、写入、矩阵运算等。
  2. Size 类:用于表示图像或矩阵的尺寸,可以通过 Size(width, height) 构造函数进行创建。
  3. Point 类:用于表示二维或三维空间中的点,可以通过 Point(x, y) 构造函数进行创建。
  4. Scalar 类:用于表示颜色或数值的标量,通常用于图像处理中的颜色转换和阈值操作。
  5. Range 类:用于表示范围,常用于遍历图像或矩阵的一部分区域。
  6. Algorithm 类:提供了一系列基本的机器学习算法和函数,如直方图计算、特征提取等。
  7. Utility 类:提供了一些实用的工具函数,如数学运算、类型转换等。

<opencv2/core/core.hpp> 是OpenCV库的核心部分,许多其他的模块和功能都依赖于这个头文件。

2.1.11 librealsense2/rs.hpp介绍

#include <librealsense2/rs.hpp> 是一个用于包含 Intel RealSense 库的 C++ 头文件。RealSense 是 Intel 开发的一个用于计算机视觉的库,它允许计算机从摄像头捕获深度、彩色和红外等传感器数据,并对其进行处理和分析。

通过包含这个头文件,你可以使用 RealSense 库提供的各种功能和类。这些功能包括:

  1. 深度传感器捕获:使用 Intel RealSense 摄像头捕获深度数据,生成三维点云数据。
  2. 彩色和红外传感器捕获:捕获彩色和红外图像,用于颜色识别、物体检测等任务。
  3. 传感器同步:同时捕获多个传感器的数据,如深度和彩色图像的同步。
  4. 点云处理:对捕获的点云数据进行处理和分析,如滤波、分割、测量等。
  5. 姿态估计:使用深度数据估计物体的姿态和位置。
  6. 光照和颜色校准:对传感器数据进行校准,以获得更准确的结果。

2.1.12 librealsense2/rsutil.h介绍

#include "librealsense2/rsutil.h" 是 Intel RealSense 库中的一个头文件,用于提供一些实用工具和辅助功能。

rsutil.h 包含了一些用于处理 RealSense 数据的实用函数和辅助功能,例如:

  1. 数据流管理:提供了用于管理 RealSense 数据流的函数,如开始和停止数据流、查询设备状态等。
  2. 帧处理:提供了用于处理捕获的帧数据的函数,如获取帧数据、解码帧数据等。
  3. 传感器控制:提供了用于控制 RealSense 摄像头传感器功能的函数,如设置传感器模式、配置传感器参数等。
  4. 图像处理:提供了一些图像处理功能,如缩放、旋转、裁剪等。
  5. 日志和调试:提供了用于记录日志和调试信息的函数,以便开发人员可以更好地了解程序运行情况。

通过使用 rsutil.h 中的函数和功能,你可以更方便地处理和控制 RealSense 摄像头捕获的数据,并进行相关的图像处理和分析任务。

2.1.13 System介绍

该库位于Include文件夹。

2.2代码总结

通过分析引用的库文件,可以总结如下:

  1. 标准库

    • #include <signal.h>:提供了信号处理功能,例如发送和接收信号。
    • #include <stdlib.h>:提供了各种常用的函数,如内存分配、随机数生成等。
    • #include <iostream>:提供了标准输入输出功能,允许程序从标准输入读取数据并写入标准输出。
    • #include <algorithm>:提供了各种算法,如排序、查找等。
    • #include <fstream>:提供了文件操作功能,允许程序读取和写入文件。
    • #include <chrono>#include <ctime>:提供了日期和时间功能,包括获取当前时间、格式化日期等。
    • #include <sstream>:提供了字符串流的功能,可以方便地进行字符串格式化操作。
  2. 条件变量库

    • #include <condition_variable>:提供了条件变量的功能,用于实现线程间的同步。
  3. OpenCV库

    • #include <opencv2/core/core.hpp>:OpenCV的核心头文件,提供了图像处理、计算机视觉等功能。
  4. RealSense库

    • #include <librealsense2/rs.hpp>#include "librealsense2/rsutil.h":Intel RealSense库的头文件,用于捕捉和解析来自摄像头的深度、彩色、红外等传感器数据。
  5. 自定义库

    • #include <System.h>:一个自定义的头文件,可能提供系统级别的功能或定义,但具体内容需要查看该头文件的内容才能确定。
文章来源:https://blog.csdn.net/anananajiushiwo/article/details/135102565
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。