realsense SDK2.0学习::(二)D435深度图片对齐到彩色图片-SDK实现

D435深度图片对齐到彩色图片


开发环境:

  • ubuntu 16.04LTS
  • Intel Realsense SDK2.0
  • C++
  • Opencv3.4
  • CMake

Intel Realsense SDK2.0 貌似已经有了红外摄像头和RBG摄像头的标定数据,本例参照example里面的例程Align进行简化和修改,注释翻译。这里是直接用SDK的对齐了,迟点会出自己实现的对齐方案。

程序流程:

(1) 创建窗口

(2)创建数据管道以及配置信息

(3)打开数据管道,并传入配置信息,打开的函数返回一个profile对象

(4)选择要将深度图对齐到什么数据流(这里选择对齐到RS2_STREAM_COLOR流)

(6)定义一个align对象

(7)取新的一帧,通过align对象即可获得对齐后的帧(再重复一遍,这个例子是将深度图对齐到彩色图,即彩色图不变,深度图发生变化)

(8)将对应的帧输出(详细可参见 ----)

(10)注意:这里虽然有个 rs2::等待捕获下一帧,但是opencv的waitkey()函数不能少,否则不能显示

全部代码及原版英文注释和翻译注释:

#include <iostream>
using namespace std;
#include <sstream>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>

#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.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
{
    // Create and initialize GUI related objects
    //创建gui窗口
    //window app(1280, 720, "CPP - Align Example"); // Simple window handling
    //ImGui_ImplGlfw_Init(app, false);      // ImGui library intializition
    const char* depth_win="depth_Image";
    namedWindow(depth_win,WINDOW_AUTOSIZE);
    const char* color_win="color_Image";
    namedWindow(color_win,WINDOW_AUTOSIZE);

    //深度图像颜色map
    rs2::colorizer c;                          // Helper to colorize depth images
    //helper用于渲染图片
    //texture renderer;                     // Helper for renderig images

    // Create a pipeline to easily configure and start the camera
    //创建数据管道
    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_BGR8,30);
    //Calling pipeline's start() without any additional parameters will start the first device
    //直接start(),不添加配置参数,则默认打开第一个设备
    // with its default streams.
    //以及以默认的配置进行流输出
    //The start function returns the pipeline profile which the pipeline used to start the device
    //start()函数返回数据管道的profile
    rs2::pipeline_profile profile = pipe.start(pipe_config);

    // Each depth camera might have different units for depth pixels, so we get it here
    //每个深度摄像头有不同单元的像素,我们这里获取
    // Using the pipeline's profile, we can retrieve the device that the pipeline uses
    //使用数据管道的profile获取深度图像像素对应于长度单位(米)的转换比例
    float depth_scale = get_depth_scale(profile.get_device());

    //Pipeline could choose a device that does not have a color stream
    //数据管道可以选择一个没有彩色图像数据流的设备
    //If there is no color stream, choose to align depth to another stream
    //选择彩色图像数据流来作为对齐对象
    rs2_stream align_to = RS2_STREAM_COLOR;//find_stream_to_align(profile.get_stream());

    /*

     @这里的对齐是改变深度图,而不改变color图

    */
    // Create a rs2::align object.
    //创建一个rs2::align的对象
    // rs2::align allows us to perform alignment of depth frames to others frames
    //rs2::align 允许我们去实现深度图像对齐其他图像
    //The "align_to" is the stream type to which we plan to align depth frames.
    // "align_to"是我们打算用深度图像对齐的图像流
    rs2::align align(align_to);

    // Define a variable for controlling the distance to clip
    //定义一个变量去转换深度到距离
    float depth_clipping_distance = 1.f;

    while (cvGetWindowHandle(depth_win)&&cvGetWindowHandle(color_win)) // Application still alive?
    {
        // Using the align object, we block the application until a frameset is available
        //堵塞程序直到新的一帧捕获
        rs2::frameset frameset = pipe.wait_for_frames();

        // rs2::pipeline::wait_for_frames() can replace the device it uses in case of device error or disconnection.
        // Since rs2::align is aligning depth to some other stream, we need to make sure that the stream was not changed
        //因为rs2::align 正在对齐深度图像到其他图像流,我们要确保对齐的图像流不发生改变
        //  after the call to wait_for_frames();
        if (profile_changed(pipe.get_active_profile().get_streams(), profile.get_streams()))
        {
            //If the profile was changed, update the align object, and also get the new device's depth scale
            //如果profile发生改变,则更新align对象,重新获取深度图像像素到长度单位的转换比例
            profile = pipe.get_active_profile();
            align = rs2::align(align_to);
            depth_scale = get_depth_scale(profile.get_device());
        }

        //Get processed aligned frame
        //获取对齐后的帧
        auto processed = align.process(frameset);

        // Trying to get both other and aligned depth frames
        //尝试获取对齐后的深度图像帧和其他帧
        rs2::frame aligned_color_frame = processed.get_color_frame();//processed.first(align_to);
        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 one of them is unavailable, continue iteration
        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_color_image(Size(b_color_w,b_color_h),CV_8UC3,(void*)before_depth_frame.get_data(),Mat::AUTO_STEP);
        //显示
        imshow(depth_win,aligned_depth_image);
        imshow(color_win,aligned_color_image);
        imshow("before aligned",before_color_image);
        waitKey(10);
    }
    return EXIT_SUCCESS;
}
catch (const rs2::error & e)
{
    std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n    " << e.what() << std::endl;
    return EXIT_FAILURE;
}
catch (const std::exception & e)
{
    std::cerr << e.what() << std::endl;
    return EXIT_FAILURE;
}

float get_depth_scale(rs2::device dev)
{
    // Go over the device's sensors
    for (rs2::sensor& sensor : dev.query_sensors())
    {
        // Check if the sensor if a depth sensor
        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)) //If it previous stream wasn't found in current
        {
            return true;
        }
    }
    return false;
}
float get_depth_scale(rs2::device dev)
{
    // Go over the device's sensors
    for (rs2::sensor& sensor : dev.query_sensors())
    {
        // Check if the sensor if a depth sensor
        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");
}

CMakeLists.txt

project(align_test)
cmake_minimum_required(VERSION 2.8)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})

set(CMAKE_CXX_FLAGS "-std=c++11")
#寻找opencv库
find_package(OpenCV REQUIRED)
#message(STATUS ${OpenCV_INCLUDE_DIRS})
#添加头文件
include_directories(${OpenCV_INCLUDE_DIRS})
#链接Opencv库
target_link_libraries(align_test ${OpenCV_LIBS} )
#添加后可进行调试
set( CMAKE_BUILD_TYPE Debug )
set(DEPENDENCIES realsense2 )
target_link_libraries(align_test ${DEPENDENCIES})

实现效果:

左上为对齐之前的深度图,

左下为对齐后的深度图

  • 19
    点赞
  • 142
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
### 回答1: Realsense SDK 2.0 是英特尔公司推出的一款深度相机开发工具包,可以用于开发各种基于深度相机的应用程序。学习 Realsense SDK 2.0 需要掌握深度相机的原理和使用方法,以及相关的编程知识和技能。可以通过阅读官方文档、参加培训课程、查阅相关书籍等方式进行学习。同时,还需要具备一定的计算机视觉和机器学习等方面的知识,以便更好地应用 Realsense SDK 2.0 进行开发。 ### 回答2: RealSense SDK2.0是英特尔公司推出的一款深度学习软件开发工具包,专门用于开发支持英特尔RealSense摄像头的应用程序。利用该工具包,用户可以轻松地将RealSense摄像头的深度感知功能集成到自己的应用程序中,实现场景感知、动作识别、手势控制、面部表情识别等多种功能。 学习RealSense SDK2.0需要具备一定的编程基础,熟悉C++、C#、Python等编程语言,同时还需要了解深度学习、计算机视觉等相关知识。具体的学习步骤如下: 1. 安装RealSense SDK2.0:从英特尔官网下载RealSense SDK2.0,并按照安装步骤进行安装。 2. 熟悉RealSense SDK2.0 API:RealSense SDK2.0提供了丰富的API,包括深度图像获取、人体骨骼识别、手势识别、面部表情识别等功能,需要深入了解并进行实际操作。 3. 开发实际应用程序:在熟悉API后,可以进行实际的应用程序开发。例如,基于RealSense SDK2.0开发的人脸识别系统、动作捕捉系统等。 4. 学习RealSense SDK2.0案例:英特尔官网提供了丰富的RealSense SDK2.0应用案例,可以通过学习这些案例,更好地了解RealSense SDK2.0的使用方法和开发技巧。 总之,学习RealSense SDK2.0需要具备一定的编程基础和相关知识,并需要在实际应用程序开发中进行深入学习和实践。 ### 回答3: RealSense SDK2.0是Intel公司出品的一款开发工具包,用于支持使用Intel RealSense技术进行开发。该工具包提供了一套完整的工具链,开发人员可以使用它来创建实时的3D摄像头解决方案,使设备具有感知环境和深化了解用户的能力。它主要包括了许多功能强大的API和库,使得开发人员可以使用这些API和库,来访问RealSense 3D深度摄像头的数据并将其应用在各种开发领域中。 在使用RealSense SDK2.0学习时,需要首先掌握一些基础知识,如深度图像、RGB图像、位置追踪等。此外,还需要掌握如何使用真实的数据来处理视频流、创建人脸和手势识别、物体追踪、语音识别和跟踪等功能。同时,为了提高开发效率,还需要掌握如何使用一些高级工具和技术,例如RealSense Viewer、RealSense Depth Quality Tool、RealSense Explorer、RealSense Emotion Detection、RealSense Player等。 在应用中,RealSense SDK2.0非常适用于各种场景,可以应用于虚拟现实、移动机器人、医学成像、安全监控、互动游戏、屏幕投影等领域。该SDK具有高性能、高精度和易于使用等优点,能够为开发人员提供更好的用户体验和更好的开发体验。 要学习RealSense SDK2.0,需要掌握计算机视觉、深度学习、机器学习等相关领域的基础知识,以便更好地处理和分析数据。此外,还需要掌握常用的编程语言,如C++、Python等,以便更好地开发应用程序。最后,需要注意实践。只有通过实践,才能更好地了解RealSense SDK2.0,并将其应用到实际的场景中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值