您的位置:

深入探讨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