从自动驾驶到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