深入探討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/zh-hant/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

發表回復

登錄後才能評論