從自動駕駛到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-tw/n/301993.html