从自动驾驶到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
微信扫一扫
支付宝扫一扫