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是深度數據的最大距離。
最后,輸出的圖像應該像這樣:

<br/><br/><font/>
