Kinect For Windows V2开发日志四:使用OpenCV显示深度图像

# 代码示例: ```CPP #include #include #include

using namespace std;
using namespace cv;
int main(void)
{
IKinectSensor * mySensor = nullptr;
GetDefaultKinectSensor(&mySensor); //获取感应器
mySensor->Open(); //打开感应器

IDepthFrameSource	* mySource = nullptr;	//取得深度数据
mySensor->get_DepthFrameSource(&mySource);

int	height = 0, width = 0;
IFrameDescription	* myDescription = nullptr;	//取得深度数据的分辨率
mySource->get_FrameDescription(&myDescription);
myDescription->get_Height(&height);
myDescription->get_Width(&width);
myDescription->Release();

IDepthFrameReader	* myReader = nullptr;		
mySource->OpenReader(&myReader);	//打开深度数据的Reader

IDepthFrame	* myFrame = nullptr;
Mat	temp(height,width,CV_16UC1);	//建立图像矩阵
Mat	img(height,width,CV_8UC1);
while (1)
{
	if (myReader->AcquireLatestFrame(&myFrame) == S_OK)	//通过Reader尝试获取最新的一帧深度数据,放入深度帧中,并判断是否成功获取
	{
		myFrame->CopyFrameDataToArray(height * width, (UINT16 *)temp.data);	//先把数据存入16位的图像矩阵中
		temp.convertTo(img,CV_8UC1,255.0 / 4500);	//再把16位转换为8位
		imshow("TEST", img);
		myFrame->Release();
	}
	if (waitKey(30) == VK_ESCAPE)
		break;
}
myReader->Release();		//释放不用的变量并且关闭感应器
mySource->Release();
mySensor->Close();
mySensor->Release();

return	0;

}

---
#   详细解释
为了简便起见,此段代码同样略掉了大部分错误检测。不难看出此段代码于[上一篇](http://www.cnblogs.com/xz816111/p/5184405.html)非常相似,主要区别在循环里。

首先,声明了两个矩阵,一个为16位单通道,一个为8位单通道,之所以开16位的,是因为在[Kinect的基本参数](http://www.cnblogs.com/xz816111/p/5184350.html)这篇里可以看到,深度数据是16位的。开8位的原因等下说。然后同样的,利用`AcquireLatestFrame()`来获取最新的一帧,不同的是下面一句,不再用`AccessUnderlyingBuffer()`,而是用`CopyFrameDataToArray`来把数据复制到openCV的图像矩阵Mat里,注意第三个参数的类型是`UINT16*`,所以需要强制转换一下。接下来要把16位的Mat转换成8位来输出显示,为什么不直接用16位?其实也可以用,但是直接用16位的话显示的图像很接接近于全黑,不方便观察,于是转换为8位。`convertTo()`这个函数的第一个参数是输出矩阵,第二个是转换的类型,第三个是缩放因子,其中4500是深度数据的最大距离。

最后,输出的图像应该像这样:
![](http://images.cnblogs.com/cnblogs_com/xz816111/786501/o_Kinect%e6%b7%b1%e5%ba%a6%e5%9b%be%e5%83%8f.png)
<br/><br/><font/>
原文地址:https://www.cnblogs.com/xz816111/p/5184517.html