今天实验室新置办的D435i到了,然后需要调试一下,这款D435i是D435的升级版,二者仅仅差了一个imu(D435i有imu),其余并无差别(官网上是这样说的),然后在某东上买的,一共1999(带发票).
先是配置开发环境,网上有很多博客已经写了,这里就不做赘述,**只是要注意在各种包含目录下要记得加上include文件夹或者是lib文件夹**,要不然就会报错。
因为我们实验室这个项目是做双目的,但是在官方的Viewer里是没有给显示左右红外双目图像的功能,因此本片博客就写一下如何使用Opencv来读取双目IR图像与深度图。下面直接上代码吧。(笔者能力有限,有些地方做的不是特别好,希望读者能给予批评指正,另外也非常希望有从事结构光,双目视觉方面研究的同学与我联系,大家共同进步)
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
using namespace rs2;
const int width = 1280;
const int height = 720;
const int fps = 30;
//const int fps = 60;
int main()
{
//Initialization
//Depth
const char* depth_win = "depth_Image";
namedWindow(depth_win, WINDOW_AUTOSIZE);
//IR Left & Right
const char* left_win = "left_Image";
namedWindow(left_win, WINDOW_AUTOSIZE);
const char* right_win = "right_Image";
namedWindow(right_win, WINDOW_AUTOSIZE);
//Color
const char* color_win = "color_Image";
namedWindow(color_win, WINDOW_AUTOSIZE);
char LName[100];//left
char RName[100];//right
char DName[100];//depth
char CName[100];//color
long long i = 0;//counter
//Pipeline
rs2::pipeline pipe;
rs2::config pipe_config;
pipe_config.enable_stream(RS2_STREAM_DEPTH, width, height, RS2_FORMAT_Z16, fps);
pipe_config.enable_stream(RS2_STREAM_INFRARED, 1, width, height, RS2_FORMAT_Y8, fps);
pipe_config.enable_stream(RS2_STREAM_INFRARED, 2, width, height, RS2_FORMAT_Y8, fps);
pipe_config.enable_stream(RS2_STREAM_COLOR , width, height, RS2_FORMAT_BGR8, fps);
rs2::pipeline_profile profile = pipe.start(pipe_config);
//stream
auto depth_stream = profile.get_stream(RS2_STREAM_DEPTH).as();
while (cvGetWindowHandle(depth_win)&& cvGetWindowHandle(right_win)&& cvGetWindowHandle(left_win)&& cvGetWindowHandle(color_win)) // Application still alive?
{
//堵塞程序直到新的一帧捕获
rs2::frameset frameset = pipe.wait_for_frames();
//取深度图和彩色图
frame depth_frame = frameset.get_depth_frame();
video_frame ir_frame_left = frameset.get_infrared_frame(1);
video_frame ir_frame_right = frameset.get_infrared_frame(2);
frame color_frame = frameset.get_color_frame();
Mat dMat_left(Size(width, height), CV_8UC1, (void*)ir_frame_left.get_data());
Mat dMat_right(Size(width, height), CV_8UC1, (void*)ir_frame_right.get_data());
Mat depth_image(Size(width, height),CV_16U, (void*)depth_frame.get_data(), Mat::AUTO_STEP);
Mat color_image(Size(width, height), CV_8UC3, (void*)color_frame.get_data(), Mat::AUTO_STEP);
imshow(left_win,dMat_left);
imshow(right_win,dMat_right);
imshow(depth_win, depth_image);
imshow(color_win, color_image);
/*waitKey(1);*/
char c = waitKey(1);
if (c == 'p')
{
sprintf_s(LName, "F:\\cpppractice\\D435iimshow\\x64\\Debug\\left_eye\\%d.png", i);
imwrite(LName, dMat_left);
sprintf_s(RName, "F:\\cpppractice\\D435iimshow\\x64\\Debug\\right_eye\\%d.png", i);
imwrite(RName, dMat_right);
sprintf_s(DName, "F:\\cpppractice\\D435iimshow\\x64\\Debug\\depth\\%d.png", i);
imwrite(DName, depth_image);
sprintf_s(CName, "F:\\cpppractice\\D435iimshow\\x64\\Debug\\color\\%d.png", i);
imwrite(CName, color_image);
i++;
}
else if (c == 'q')
break;
/*sprintf_s(LName, "F:\\cpppractice\\D435iimshow\\x64\\Debug\\left_eye\\%d.png", i);
imwrite(LName, dMat_left);
sprintf_s(RName, "F:\\cpppractice\\D435iimshow\\x64\\Debug\\right_eye\\%d.png", i);
imwrite(RName, dMat_right);
sprintf_s(DName, "F:\\cpppractice\\D435iimshow\\x64\\Debug\\depth\\%d.png", i);
imwrite(DName, depth_image);
sprintf_s(CName, "F:\\cpppractice\\D435iimshow\\x64\\Debug\\color\\%d.png", i);
imwrite(CName, color_image);
i++;*/
}
return 0;
}
在这里补充一下使用linux下的坑,我在用linux的时候opencv和realsense各种不给力,然后只能一点一点调,其实就是主要就是各种库没链接上,所以在Cmakelists上下功夫就好了,Cmakelists如下:
cmake_minimum_required(VERSION 3.1)
project(pic_cap)
add_definitions(-std=c++11)
add_executable(pic_cap main.cpp)
aux_source_directory(. SRC_LIST)
#add_executable(${PROJECT_NAME} ${SRC_LIST})
find_package( OpenCV 3 REQUIRED )
#find_package( REALSENSE 2 REQUIRED )
install(TARGETS pic_cap RUNTIME DESTINATION bin)
target_link_libraries(pic_cap ${OpenCV_LIBS})
target_link_libraries(pic_cap ${DEPENDENCIES})
#target_link_libraries(pic_cap ${REALSENSE2_LIBS})
include_directories(/home/librealsense/include)
set(DEPENDENCIES realsense2 )
target_link_libraries(pic_cap ${DEPENDENCIES})
注意:Realsense D435i直接读出的是16位的图像,而我们所使用的opencv的Mat常用的是8位的,因此,在图像转化方面(Mat depthimageconvert(Mat input)这个函数) C++语言里我还没有找到一个合适的方法,原因有2:
<1> 直接从depth_stream中读出的深度图的像素值范围为0-65535,而我们最终要使用的图像像素灰度值范围是0-255,因此如果直接用I(i,j)/255或者I(i,j)/65535*255的话(其实二者原理是一样的),这样得到的结果就会是一片黑,要乘以一个系数,使整张图像的灰度值提升才能获得可视化的结果。但是如果这样做的话会使原数据不真实。
<2> realsense D435i默认的depth图像是远白近黑,但是我们经常使用的是远黑近白,二者没有一个很好的转化方式(我还没找到,总不能直接用255-I(i,j)吧)
参考文献:
[1] https://blog.csdn.net/xuyuhua1985/article/details/80108597