设备
此处RGBD相机主要指利用Light Coding(结构光)或TOF进行成像的深度相机,主动发光,主要适用于室内环境。
比较常见的RGBD相机如下表:
相机 | 原理 | SDK | 资料 |
---|---|---|---|
PrimeSense Carmine 1.08/1.09 (2012) | Light Coding(散斑) | OpenNI | 链接 |
Xbox One Kinect(Kinect v2,2013) | TOF | OpenNI/Kinect SDK | |
ASUS XTION 2 / XTION PRO LIVE(CARMINE 1.08的马甲) | Light Coding | OpenNI | 链接 |
Intel RealSense(D435 etc.) | Light Coding(编码) | OpenNI/Realsense Camera SDK | 链接 |
ZED (2016) | Stereo |
数据格式
通常深度数据使用整形数进行表示,范围在0-65535之间,类型为UINT16,即unsigned short,无符号2字节
单位为毫米(mm),但是某些SDK也支持使用100微米(um)来进行表示,如OpenNI支持的深度数据格式有PIXEL_FORMAT_DEPTH_1_MM,PIXEL_FORMAT_DEPTH_100_UM等。至于分辨率则通常是万年的640x480,有些甚至是320x240插值上去的。
由于Depth有一定的有效工作范围,以PrimeSense Carmine 1.09为例,其工作范围只有0.35-1.4m,即数据范围是350-1400,通常会使用一个数值来表示无效的数据,如0或65535。
通常RGB Sensor和Depth Sensor的FOV并不一致,所以需要进行配准,配准的目的是使得RGB的像素和Depth的像素一一对应。谁向谁来配准倒是没有那么重要,深度图也可以被插值,与彩色图类似。
以OpenNI为例,里面有一个这样的接口,setImageRegistrationMode(IMAGE_REGISTRATION_DEPTH_TO_COLOR)
,其效果是裁剪缩放深度图使得其FOV与RGB完全相同(但其实边缘已经没有了,全部都是无效的Depth像素)。
存储读取
根据之前的描述,深度图的表示也很简单,如下:
char RGBData[640][480][3];
typedef unsigned short UINT16,*PUINT16;
UINT16 DepthData[640][480];
我们可以自己实现保存与读取的方法,也可以借助一些第三方SDK,如OpenCV进行读写,
在操作深度图时,OpenCV使用的格式是CV_16U
,举个例子:
inline cv::Mat getMat(const VideoFrameRef &frame,int dataStride,int openCVFormat){
//深度图PNG16类型(short),Little-Endian(低位在低字节)
//RGB图BGR24类型
int h=frame.getHeight();
int w=frame.getWidth();
cv::Mat image=cv::Mat(h,w,openCVFormat);
memcpy(image.data,frame.getData(),h*w*dataStride);
/