Kinect V2 開發專題(2)專案配置與API概況

查志強發表於2016-09-13

【原文:http://blog.csdn.net/bbdxf/article/details/44856713

Kinect V2 開發專題(2)

 

1、專案配置

2、Kinect API概況

 

 

1、專案配置

Kinect V2 版本SDK安裝之後,預設會在環境變數中新增了一個叫做 KINECTSDK20_DIR 的環境變數,我們新增標頭檔案和庫時可以方便地直接使用。

在VS專案屬性中,需要新增:

 

l C++目錄 -> 標頭檔案:$(KINECTSDK20_DIR)\inc;

l C++目錄 -> 庫檔案:$(KINECTSDK20_DIR)\lib\x86; (64位的為x64)

l 聯結器 -> 輸入:Kinect20.lib

 

至此,在專案中引入標頭檔案 #include “kinect.h”,就可以隨意使用啦!

2、Kinect API 概況

近幾年,微軟對C++的發展真的是沒做多大貢獻,C++的native程式設計一再地收到冷漠對待,從新技術的參考文件就可以看出來。同樣,官方給出的參考文件基本都是對應託管C++和C#,對於非託管的,雖然有介面表,但是說了和沒說差不多了,不過好歹還是有的。

對於C#和託管C++請參考官方文件。這裡由於自己需要使用非託管C++進行程式設計,所以,重點討論這些內容。

 

首先,介面表和函式文件:https://msdn.microsoft.com/en-us/library/hh855364.aspx 。特別是介面表,很長一大串,似乎還沒有一代的好用。但是,它確實比一代好用多了。我們這裡做簡要說明。

以下內容來源:http://blog.csdn.net/jiangfan2014/article/details/40760543

在Kinect 2.0中,每個型別的資料都有三個類與之對應:Source,Reader和Frame。比如如果要讀取骨架,就有IBodyFrameSource, IBodyFrameReader, IBodyFrame這三個類,而要讀取深度資料,就有IDepthFrameSource, IDepthFrameReader, IDepthFrame這三個類,以此類推其他的如Body Index,Infrared,Color資料也是這樣命名的。

 

然後,這三個介面是什麼關係呢?

 

Source

在我們初始化並開啟了Kinect後,我們需要請求Kinect開啟一個源,我們將從這個源不斷獲得資訊。其程式碼為:

 

m_pKinectSensor->get_BodyFrameSource(&pBodyFrameSource);  

其中m_pKinectSensor是我們的Kinect總埠,pBodyFrameSource是一個IBodyFrameSource類。

 

2 Reader

由於Source是Kinect端擁有的,不是我們電腦擁有的,所以我們需要建立一個讀口,這個讀口和上述的源繫結,之後我們讀取資訊都通過呼叫這個Reader來獲得。其程式碼為:

pBodyFrameSource->OpenReader(&m_pBodyFrameReader);  

其中m_pBodyFrameReader是一個IBodyFrameReader類。

 

3 Frame

Frame是真正儲存資料的類,每一次都讓Reader把資料讀到Frame中,然後我們再從Frame中提取各種各樣最後使用的資料。程式碼為:

m_pBodyFrameReader->AcquireLatestFrame(&pBodyFrame);  

其中pBodyFrame是一個IBodyFrame類。

 

4 如何從Frame中獲得資料

請求Source和建立Reader對於每一個資料型別都是一模一樣的,但是從Frame中提取資訊則各有不同。下面講講深度資訊、骨架資訊、手勢狀態和人物二值圖資訊的提取方法。

 

4.1 深度資訊:

在Kinect 2.0中,深度座標空間的範圍是(高*寬 = 424*512)(官網有說明)。從深度資訊Frame中提取資料,主要就是把Frame中的資料轉存到一個陣列中(官網連結)。程式碼為:

pBodyIndexFrame->CopyFrameDataToArray(cDepthHeight*cDepthWidth, odyIndexArray);  

這裡cDepthHeight是424,cDepthWidth是512,bodyIndexArray就是一個424*512大小的16位unsigned int陣列,用來儲存深度資料。 

 

4.2 骨架資訊:

kinect 2.0可以同時追蹤六個人的骨架,因此每次我們需要先呼叫函式,獲得六個骨架資訊(如果沒有人,那麼那個骨架類就是空指標)。程式碼為:

pBodyFrame->GetAndRefreshBodyData(_countof(ppBodies), ppBodies);  

 

這裡ppBodies是一個長度為6的IBody陣列,IBody是用來儲存追蹤到的骨架資訊的類。 

在獲得了這個類後,我們需要進一步從類中提取骨架位置,對於ppBodies中的每一個元素pBody,程式碼為:

pBody->GetJoints(_countof(joints), joints);  

 

這裡的joints是一個長度為25的陣列,每一個元素就是骨架的位置資訊。然而, 這個骨架位置資訊是照相機座標系(camera view)下的位置,x和y的範圍都是-1到1。因此我們需要將它轉化到深度座標系中。這裡要用到一個coordinateMapper類,具體程式碼為:

m_pCoordinateMapper->MapCameraPointToDepthSpace(joints[j].Position, &depthSpacePosition[j]);  

coordinateMapper類的建立非常簡單,具體可以參考程式碼。depthSpacePosition是一個長度也為25的陣列,每一個元素是DepthSpacePoint,這個元素包含了在深度座標系下的x和y座標。 

 

最後,是否發現,我們通過這些對應關係很容易就能拿到我們需要的資料!哈哈,即便沒發現也沒關係,我們下一節進行更具體的開發。


相關文章