记录第一次Intel Realsense D435i之读取红外双目图像+深度图

记录第一次Intel Realsense的开发之路

今天实验室新置办的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

你可能感兴趣的:(RealsenseD435i)