深入探讨realsenseD435i

从自动驾驶到AR/VR,从无人机到机器人,从医疗到教育,深度相机(深度视觉)的应用在越来越多的行业中得到了广泛的应用。而realsense D435i作为英特尔公司发布的一款基于深度相机技术的智能产品,在以上各个行业都有着广泛的适用性,今天我们就一起来深入探讨一下realsense D435i的一些细节和应用场景。

一、realsense D435i VO

视觉里程计(Visual Odometry),是一种基于光流计算的,能够输出相机前后位移的算法。VO算法是自动驾驶、机器人、AR/VR等各种AI应用都必不可少的一个模块。realsense D435i在硬件上和视觉里程计有着紧密的联系。realsense D435i整合了IMU和其他传感器,IMU实时输出位移数据,据此配合视觉里程计来解算每时每刻的绝对位姿,读者可以参考下面的代码。

//初始化相机  
rs2::pipeline pipe;  
rs2::config cfg;  
cfg.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);  
cfg.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_BGR8, 30);  
rs2::pipeline_profile selection = pipe.start(cfg);  
auto stream_depth = selection.get_stream(RS2_STREAM_DEPTH).as();
 
//初始化算法
cv::Ptr opt_flow = cv::cuda::DensePyrLKOpticalFlow::create(Size(21, 21), 3, 30, false);
 
rs2::align align_to_color(RS2_STREAM_COLOR);
 
bool should_quit = false;
 
//主循环
while (!should_quit)
{
    rs2::frameset frames = pipe.wait_for_frames();
    frames = align_to_color.process(frames);
    rs2::depth_frame depth = frames.get_depth_frame();
    rs2::video_frame color = frames.get_color_frame();
    auto color_profile = color.get_profile().as();
    std::vector streams = { depth.get_profile(), color.get_profile() };
    std::vector frames_vec = { depth, color };
    auto transforms = pipe.get_active_profile().get_device().as().get_depth_to_color_extrinsics();
 
    cv::Mat image_depth(Size(stream_depth.width(), stream_depth.height()), CV_16UC1, (void*)depth.get_data(), Mat::AUTO_STEP);
    cv::Mat image_color(Size(color_profile.width(), color_profile.height()), CV_8UC3, (void*)color.get_data(), Mat::AUTO_STEP);
    cv::cuda::GpuMat d_frame0, d_frame1;
    d_frame0.upload(image_color);
 
    rs2_vector accel = { 0, 0, 0 }, gyro = { 0, 0, 0 };
    for (auto&& frame : frames_vec)
    {
        auto motion = frame.as();
        if (motion && motion.get_profile().stream_type() == RS2_STREAM_ACCEL)
        {
            accel = motion.get_motion_data();
        }
        if (motion && motion.get_profile().stream_type() == RS2_STREAM_GYRO)
        {
            gyro = motion.get_motion_data();
        }
    }
 
    //始终计算在cvgpu上,只有在VO追丢之后才停下来
    Mat H;
    cv::Mat image_color_hsv;
    std::vector status;
    std::vector error;
    cv::cuda::GpuMat gray0, gray1;
    cv::cuda::cvtColor(d_frame0, gray0, COLOR_BGR2GRAY);
             
    cuda::cvtColor(d_frame0, gray0, cv::COLOR_BGR2GRAY);
    cuda::cvtColor(d_frame1, gray1, cv::COLOR_BGR2GRAY);
    cuda::calcOpticalFlowPyrLK(gray0, gray1, gpu_pts[0], gpu_pts[1], status, error);
 
    //根据pts0,pts1,status,H得到新的pts0,pts1,retval并赋值回来
    Mat R, t;
    handeye_calculation(H, &R, &t);
 
    for (int i = 0; i < n_points; i++)
    {
        pts0[i] = gpu_pts[0].at(i);
        pts1[i] = gpu_pts[1].at(i);
    }
}

二、realsense D435i中的IMU

IMU是inertial measurement unit的缩写,即惯性测量单元,主要包括加速度计和陀螺仪。在realsenseD435i中,IMU是用来帮助算法判断相机的运动,从而可以输出每一帧的绝对姿态信息。由于realsense D435i的IMU和传感器都集成在了同一个设备中,因此可以很方便地应用到各种移动设备和机器人中。下面我们来看一下如何在realsense D435i中获取IMU数据。

//初始化相机
rs2::pipeline pipe;
rs2::config cfg;
cfg.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);
cfg.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_BGR8, 30);
rs2::pipeline_profile selection = pipe.start(cfg);
 
//获取IMU和Depth帧
while (true) {
    rs2::frameset frames = pipe.wait_for_frames();
    auto imu_data = frames["motion_data"];
    auto gyro_data = imu_data.as().get_motion_data();
    auto accel_data = imu_data.as().get_motion_data();
    auto depth_data = frames.get_depth_frame();
     
    //输出Gyro和Accel数据
    std::cout << gyro_data.z << " " << accel_data.x << std::endl;
}

三、realsense D435i是单目还是双目?

realsense D435i实际上一共有两个摄像头,分别为RGB相机和深度相机。RGB相机是标准的摄像机,主要用于普通图像的获取,而深度相机则是用来测量深度信息的。由于深度相机的物理尺寸和RGB相机一致,因此也可以视为一种单目视觉系统。但是由于深度相机获取的深度图信息可以和RGB图像进行配准,从而得到更加精确的深度信息,因此在实际应用中,可以将realsense D435i视为一种双目视觉系统。下面的代码演示了如何在opencv中获取realsense D435i的RGB和深度图信息。

//初始化相机
rs2::pipeline pipe;
rs2::config cfg;
cfg.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);
cfg.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_BGR8, 30);
rs2::pipeline_profile selection = pipe.start(cfg);
 
//获取RGB和Depth帧
while (true) {
    rs2::frameset frames = pipe.wait_for_frames();
    auto depth_data = frames.get_depth_frame();
    auto color_data = frames.get_color_frame();
     
    //将RGB图像和深度图像转换成opencv中的Mat格式
    cv::Mat image_depth(Size(depth_data.as().get_width(), depth_data.as().get_height()), CV_16UC1, (void*)depth_data.as().get_data(), Mat::AUTO_STEP);
    cv::Mat image_color(Size(color_data.as().get_width(), color_data.as().get_height()), CV_8UC3, (void*)color_data.as().get_data(), Mat::AUTO_STEP);
}

四、realsense D435i在自动驾驶中的应用

在自动驾驶领域,深度相机常常被用来进行3D物体检测、背景分割、行人检测等任务。realsense D435i具备较高分辨率和稳定性,适合在自动驾驶等高精度场景中使用。下面的代码演示了如何使用realsense D435i来进行行人检测。

//初始化相机
rs2::pipeline pipe;
rs2::config cfg;
cfg.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);
cfg.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_BGR8, 30);
rs2::pipeline_profile selection = pipe.start(cfg);
 
//初始化行人检测模型
auto net = cv::dnn::readNetFromCaffe("detect.prototxt", "detect.caffemodel");
net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
 
//获取RGB和Depth帧
while (true) {
    rs2::frameset frames = pipe.wait_for_frames();
    auto depth_data = frames.get_depth_frame();
    auto color_data = frames.get_color_frame();
     
    //将RGB图像和深度图像转换成opencv中的Mat格式
    cv::Mat image_depth(Size(depth_data.as().get_width(), depth_data.as().get_height()), CV_16UC1, (void*)depth_data.as().get_data(), Mat::AUTO_STEP);
    cv::Mat image_color(Size(color_data.as().get_width(), color_data.as().get_height()), CV_8UC3, (void*)color_data.as().get_data(), Mat::AUTO_STEP);
     
    //行人检测
    cv::Mat image_color_resized;
    cv::resize(image_color, image_color_resized, cv::Size(300, 300));
    cv::Mat inputBlob = cv::dnn::blobFromImage(image_color_resized, 0.007843, cv::Size(300, 300), cv::Scalar(127.5, 127.5, 127.5), false);
    net.setInput(inputBlob);
    cv::Mat detection = net.forward();
}

五、realsense D435i在AR/VR中的应用

在AR/VR领域,深度相机也是非常重要的一个部分,主要用途是获取真实环境场景的深度信息,并将其与虚拟场景进行融合,从而实现更加真实的虚拟现实体验。realsense D435i具有较高的分辨率和稳定性,适合在AR/VR等高精度场景中使用。下面的代码演示了如何使用realsense D435i进行深度图与RGB图像配准。

//初始化相机
rs2::pipeline pipe;
rs2::config cfg;
cfg.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);
cfg.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_BGR8, 30);
rs2::pipeline_profile selection = pipe.start(cfg);

//获取RGB和Depth帧
while (true) {
rs2::frameset frames = pipe.wait_for_frames();
auto depth_data = frames.get_depth_frame();
auto color_data = frames.get_color_frame();

//将RGB图像和深度图像转换成opencv中的Mat格式
cv::Mat image_depth(Size(depth_data.as().get_width(), depth_data.as().get_height()), CV_16UC1, (void*)depth_data.as().get_data(), Mat::AUTO_STEP);
cv::Mat image_color(Size(color_data.as().get_width(), color_data.as().get_height()), CV_8UC3, (void*)color_data.as().get_data(), Mat::AUTO_STEP

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/301993.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝的头像小蓝
上一篇 2024-12-30 16:10
下一篇 2024-12-30 16:10

相关推荐

  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25
  • 深入理解byte转int

    一、字节与比特 在讨论byte转int之前,我们需要了解字节和比特的概念。字节是计算机存储单位的一种,通常表示8个比特(bit),即1字节=8比特。比特是计算机中最小的数据单位,是…

    编程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什么是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变…

    编程 2025-04-25
  • 深入探讨OpenCV版本

    OpenCV是一个用于计算机视觉应用程序的开源库。它是由英特尔公司创建的,现已由Willow Garage管理。OpenCV旨在提供一个易于使用的计算机视觉和机器学习基础架构,以实…

    编程 2025-04-25
  • 深入了解scala-maven-plugin

    一、简介 Scala-maven-plugin 是一个创造和管理 Scala 项目的maven插件,它可以自动生成基本项目结构、依赖配置、Scala文件等。使用它可以使我们专注于代…

    编程 2025-04-25
  • 深入了解LaTeX的脚注(latexfootnote)

    一、基本介绍 LaTeX作为一种排版软件,具有各种各样的功能,其中脚注(footnote)是一个十分重要的功能之一。在LaTeX中,脚注是用命令latexfootnote来实现的。…

    编程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一个程序就是一个模块,而一个模块可以引入另一个模块,这样就形成了包。包就是有多个模块组成的一个大模块,也可以看做是一个文件夹。包可以有效地组织代码和数据…

    编程 2025-04-25
  • 深入探讨冯诺依曼原理

    一、原理概述 冯诺依曼原理,又称“存储程序控制原理”,是指计算机的程序和数据都存储在同一个存储器中,并且通过一个统一的总线来传输数据。这个原理的提出,是计算机科学发展中的重大进展,…

    编程 2025-04-25
  • 深入剖析MapStruct未生成实现类问题

    一、MapStruct简介 MapStruct是一个Java bean映射器,它通过注解和代码生成来在Java bean之间转换成本类代码,实现类型安全,简单而不失灵活。 作为一个…

    编程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r为前缀的字符串。r字符串中的反斜杠(\)不会被转义,而是被当作普通字符处理,这使得r字符串可以非常方便…

    编程 2025-04-25

发表回复

登录后才能评论