Realsense相机的RGB与depth图像的对齐

第三部分 将RGB图像和Depth图像对齐



前言

将RGB图像和深度图像对齐有两种方式,一种是将深度图对齐到RGB图像上,另一种是将RGB图像对齐到深度图上。此处采用的是第一种将深度图对齐到RGB图上。


一、创建对齐的cpp文件

1.用vim创建C++文件

在指定文件夹下进入终端,并输入以下代码创建cpp文件:

vim duiqi.cpp

回车后进入编辑界面:
请添加图片描述
按键盘“i”进入编辑模式,输入C++代码。

对齐的代码如下:

#include <iostream>
using namespace std;
#include <sstream>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <opencv2/opencv.hpp>
using namespace cv;
#include <librealsense2/rs.hpp>
// 获取深度像素对应长度单位转换
float get_depth_scale(rs2::device dev);
// 检查摄像头数据管道设置是否改变
bool profile_changed(const std::vector<rs2::stream_profile> &current, const std::vector<rs2::stream_profile> &prev);
int main(int argc, char *argv[])
try
{
    
    
    // 创建 opencv 窗口
    const char *depth_win = "depth_Image";
    namedWindow(depth_win, WINDOW_AUTOSIZE);
    const char *color_win = "color_Image";
    namedWindow(color_win, WINDOW_AUTOSIZE);
    // 深度图像颜色
    rs2::colorizer c;
    // 创建数据管道
    rs2::pipeline pipe;
    rs2::config pipe_config;
    pipe_config.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);
    pipe_config.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_RGB8, 30);
    // start() 函数返回数据管道的profile
    rs2::pipeline_profile profile = pipe.start(pipe_config);
    // rs2::pipeline_profile profile = pipe.start();
    // 使用数据管道的 profile 获取深度图像像素对应于长度单位(米)的转换比例
    float depth_scale = get_depth_scale(profile.get_device());
    cout << "depth_scale = " << depth_scale << endl;
    // 选择彩色图像数据流来作为对齐对象
    rs2_stream align_to = RS2_STREAM_COLOR; // 对齐的是彩色图,所以彩色图是不变的
    // // 将深度图对齐到RGB图
    rs2::align align(align_to);
    while (getWindowProperty(depth_win, WND_PROP_AUTOSIZE) && getWindowProperty(color_win, WND_PROP_AUTOSIZE))
    {
    
    
        // 堵塞程序直到新的一帧捕获
        rs2::frameset frameset = pipe.wait_for_frames();
        // 正在对齐深度图到其他图像流,我们要确保对齐的图像流不发生改变
        if (profile_changed(pipe.get_active_profile().get_streams(), profile.get_streams()))
        {
    
    
            // 如果profile发生改变,则更新align对象,重新获取深度图像像素到长度单位的转换比例
            profile = pipe.get_active_profile();
            align = rs2::align(align_to);
            depth_scale = get_depth_scale(profile.get_device());
        }
        // 获取对齐后的帧
        auto processed = align.process(frameset);
        // 尝试获取对齐后的深度图像帧和其他帧
        rs2::frame aligned_color_frame = processed.get_color_frame();                 // RGB图
        rs2::frame aligned_depth_frame = processed.get_depth_frame().apply_filter(c); // 深度图
        // 获取对齐之前的color图像
        rs2::frame before_depth_frame = frameset.get_depth_frame().apply_filter(c); // 获取对齐之前的深度图
        // 获取宽高
        const int depth_w = aligned_depth_frame.as<rs2::video_frame>().get_width();
        const int depth_h = aligned_depth_frame.as<rs2::video_frame>().get_height();
        const int color_w = aligned_color_frame.as<rs2::video_frame>().get_width();
        const int color_h = aligned_color_frame.as<rs2::video_frame>().get_height();
        const int b_color_w = before_depth_frame.as<rs2::video_frame>().get_width();
        const int b_color_h = before_depth_frame.as<rs2::video_frame>().get_height();
        // 如果其中一个未能获取,继续迭代
        if (!aligned_depth_frame || !aligned_color_frame)
        {
    
    
            continue;
        }
        // 创建opencv类型,并传入数据
        Mat aligned_depth_image(Size(depth_w, depth_h), CV_8UC3, (void *)aligned_depth_frame.get_data(), Mat::AUTO_STEP);
        Mat aligned_color_image(Size(color_w, color_h), CV_8UC3, (void *)aligned_color_frame.get_data(), Mat::AUTO_STEP);
        Mat before_depth_image(Size(b_color_w, b_color_h), CV_8UC3, (void *)before_depth_frame.get_data(), Mat::AUTO_STEP);
        // 彩色图RGB转BGR
        cvtColor(aligned_color_image, aligned_color_image, COLOR_RGB2BGR);
        // 显示
        imshow(depth_win, aligned_depth_image);
        imshow(color_win, aligned_color_image);
        imshow("before aligned depth Image", before_depth_image);
        waitKey(10);
    }
    return EXIT_SUCCESS;
}
catch (const std::exception &e)
{
    
    
    std::cerr << e.what() << '\n';
}
float get_depth_scale(rs2::device dev)
{
    
    
    // 遍历设备的传感器
    for (rs2::sensor &sensor : dev.query_sensors())
    {
    
    
        // 检查传感器是否是深度传感器
        if (rs2::depth_sensor dpt = sensor.as<rs2::depth_sensor>())
            return dpt.get_depth_scale();
    }
    throw std::runtime_error("Device does not have a depth sensor");
}
bool profile_changed(const std::vector<rs2::stream_profile> &current, const std::vector<rs2::stream_profile> &prev)
{
    
    
    for (auto &&sp : prev)
    {
    
    
        // if previous profile is in current ( maybe just added another)
        auto itr = std::find_if(std::begin(current), std::end(current), [&sp](const rs2::stream_profile &current_sp)
                                {
    
     return sp.unique_id() == current_sp.unique_id(); });
        if (itr == std::end(current))
        {
    
    
            return true;
        }
    }
    return false;
}

输入完毕后,按“ESC”健进入命令模式,输入“:wq”保存并退出文本编辑器。
在这里插入图片描述
在这里插入图片描述

C++文件即被创建完毕。

二、使用CMake构建C++工程

1.创建并编写CMakeList.txt文件

使用VScode打开项目文件
在这里插入图片描述
在项目目录中,New File一个CMakeLists.txt:
在这里插入图片描述
将下段代码复制进CMakeList.txt文件中,并保存:

cmake_minimum_required(VERSION 3.1.0)
project(realsense)
find_package(OpenCV REQUIRED)
include_directories(${
    
    OpenCV_INCLUDE_DIRS})
set(DEPENDENCIES realsense2 ${
    
    OpenCV_LIBS})
add_executable(duiqi duiqi.cpp)
target_link_libraries(duiqi ${
    
    DEPENDENCIES})

在这里插入图片描述
保存后的结果如下:
在这里插入图片描述

2.编译CMakeLists.txt

  1. 在当前目录下,创建build文件夹
mkdir build
  1. 进入到build文件夹
cd build
  1. 编译上级目录的CMakeLists.txt,生成Makefile和其他文件
 cmake ..
  1. 执行make命令,生成target
make

示例如下:
在这里插入图片描述
5.在命令行输入“./duiqi",执行build文件夹下生成的可执行文件

./duiqi

在这里插入图片描述
6.对齐后的结果如图:
在这里插入图片描述

总结

以上就是今天要讲的内容,本文仅仅简单介绍了如何将RGB图像和深度图像对齐。

猜你喜欢

转载自blog.csdn.net/weixin_44934373/article/details/128614089